APP聊天项目介绍
项目结构说明
res/layout目录:存放布局相关的 XML 文件,用于定义界面的外观,包含activity_main.xml(主界面布局)和message_item.xml(聊天消息项布局)。
res/drawable目录:存放一些自定义的图形资源相关的 XML 文件以及图片资源(如果有),用于界面样式设置,如背景、按钮样式等,包含edittext_rounded_bg.xml、button_send_bg.xml、left_message_bg.xml、right_message_bg.xml等文件(代码中只是简单示意,这部分并没有整理很清楚,接下来打算可根据实际需求替换和完善图片资源等)。
java(对应项目包名的目录下):存放业务逻辑代码等,包含如MainActivity.java(主 Activity 类,处理界面交互、消息发送接收展示等核心逻辑)、ChatAdapter.java(聊天消息列表适配器类,用于将消息数据绑定到RecyclerView的每一项上展示)、Message.java(消息实体类,表示一条聊天消息)、DBHelper.java(数据库帮助类,用于管理 SQLite 数据库的创建、操作等)。
代码展示
布局文件代码
activity_main.xml(存放在res/layout目录下)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#EFEFF4"tools:context=".MainActivity"><!-- 聊天消息列表RecyclerView --><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recyclerView_chat"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_above="@+id/layout_chat_input"android:clipToPadding="false"android:padding="8dp"android:scrollbars="vertical" /><!-- 输入框及发送按钮所在的底部布局 --><LinearLayoutandroid:id="@+id/layout_chat_input"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:background="@android:color/white"android:orientation="horizontal"android:padding="8dp"><!-- 表情按钮(这里先简单占位,可后续添加点击事件及表情选择功能等) --><ImageButtonandroid:id="@+id/button_emoji"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/ic_emoji"android:contentDescription="表情" /><!-- 输入文本的EditText,设置了一些样式属性 --><EditTextandroid:id="@+id/editText_message"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:background="@drawable/edittext_rounded_bg"android:hint="输入消息"android:padding="8dp"android:textColor="#000"android:textColorHint="#999" /><!-- 发送按钮 --><Buttonandroid:id="@+id/button_send"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="发送"android:textColor="@android:color/white"android:background="@drawable/button_send_bg" /></LinearLayout></RelativeLayout>
message_item.xml(存放在res/layout目录下)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:padding="4dp"><!-- 显示发送者头像(这里先简单用一个ImageView占位,实际可根据用户信息加载对应的头像资源) --><ImageViewandroid:id="@+id/imageView_sender_avatar"android:layout_width="40dp"android:layout_height="40dp"android:src="@drawable/default_avatar"android:scaleType="centerCrop" /><!-- 用于包裹消息内容的布局,根据消息是自己发送还是别人发送设置不同的对齐方式 --><LinearLayoutandroid:id="@+id/layout_message_content"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:orientation="vertical"android:padding="8dp"><!-- 显示发送者昵称(实际中可根据用户信息动态设置) --><TextViewandroid:id="@+id/textView_sender_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="发送者昵称"android:textColor="#000"android:textSize="14sp" /><!-- 根据消息类型展示不同内容,这里先以文本消息为例,用TextView展示 --><TextViewandroid:id="@+id/textView_message_content"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="消息内容"android:textColor="#333"android:textSize="16sp"android:layout_marginTop="4dp" /></LinearLayout></LinearLayout>
res/drawable目录下样式资源相关 XML 文件代码
edittext_rounded_bg.xml(存放在res/drawable目录下)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><solid android:color="@android:color/white" /><corners android:radius="16dp" /></shape>
button_send_bg.xml(存放在res/drawable目录下)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_pressed="true"><shape android:shape="rectangle"><solid android:color="#007AFF" /><corners android:radius="16dp" /></shape></item><item><shape android:shape="rectangle"><solid android:color="#0085FF" /><corners android:radius="16dp" /></shape></item></selector>
left_message_bg.xml(存放在res/drawable目录下)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><solid android:color="#DCF8C6" /><corners android:topLeftRadius="16dp"android:bottomLeftRadius="16dp"android:bottomRightRadius="16dp" /></shape>
right_message_bg.xml(存放在res/drawable目录下,样式与left_message_bg.xml类似,可做区分,这里简单示意)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><solid android:color="#87CEEB" /><corners android:topRightRadius="16dp"android:bottomLeftRadius="16dp"android:bottomRightRadius="16dp" /></shape>
业务逻辑代码
import java.util.Date;public class Message {private String sender;private String content;private String messageType;private long timestamp; // 添加时间戳属性,记录消息发送时间public Message(String sender, String content, String messageType) {this(sender, content, messageType, new Date().getTime()); // 默认使用当前时间作为时间戳}public Message(String sender, String content, String messageType, long timestamp) {this.sender = sender;this.content = content;this.messageType = messageType;this.timestamp = timestamp;}public String getSender() {return sender;}public String getContent() {return content;}public String getMessageType() {return messageType;}public long getTimestamp() {return timestamp;}
}
ChatAdapter.java(存放在 java 对应包名目录下)
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;import java.util.ArrayList;
import java.util.List;public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolder> {private List<Message> messageList;public ChatAdapter() {messageList = new ArrayList<>();}public void addMessage(Message message) {messageList.add(message);notifyItemInserted(messageList.size() - 1);}@NonNull@Overridepublic ChatViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {// 使用新的消息项布局文件来加载视图View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_item, parent, false);return new ChatViewHolder(view);}@Overridepublic void onBindViewHolder(@NonNull ChatViewHolder holder, int position) {Message message = messageList.get(position);holder.bind(message);}@Overridepublic int getItemCount() {return messageList.size();}class ChatViewHolder extends RecyclerView.ViewHolder {private ImageView imageViewSenderAvatar;private TextView textViewSenderName;private TextView textViewMessageContent;public ChatViewHolder(@NonNull View itemView) {super(itemView);imageViewSenderAvatar = itemView.findViewById(R.id.imageView_sender_avatar);textViewSenderName = itemView.findViewById(R.id.textView_sender_name);textViewMessageContent = itemView.findViewById(R.id.textView_message_content);}public void bind(Message message) {if ("text".equals(message.getMessageType())) {// 根据消息发送者等信息设置对应的显示内容和样式(这里简单示例,可根据实际完善)textViewSenderName.setText(message.getSender());textViewMessageContent.setText(message.getContent());if (message.getSender().equals("自己的用户名")) {// 假设自己发送的消息居右对齐等样式设置(这里只是简单示意,可通过布局属性等详细设置样式)// 比如设置背景颜色、文本对齐方式等与对方消息区分开textViewMessageContent.setBackgroundResource(R.drawable.right_message_bg);} else {textViewMessageContent.setBackgroundResource(R.drawable.left_message_bg);}}// 后续添加对图片消息等其他类型消息的展示逻辑}}
}
DBHelper.java(存放在 java 对应包名目录下)
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;public class DBHelper extends SQLiteOpenHelper {// 数据库名称private static final String DATABASE_NAME = "chat.db";// 数据库版本号,每次数据库结构变更时需要递增这个版本号private static final int DATABASE_VERSION = 1;// 聊天记录表名称public static final String TABLE_CHAT = "chat_messages";// 聊天记录各字段名称及类型定义public static final String COLUMN_ID = "_id";public static final String COLUMN_SENDER = "sender";public static final String COLUMN_CONTENT = "content";public static final String COLUMN_MESSAGE_TYPE = "message_type";public static final String COLUMN_TIMESTAMP = "timestamp";public DBHelper(Context context) {super(context, DATABASE_NAME, null, DATABASE_VERSION);}@Overridepublic void onCreate(SQLiteDatabase db) {// 创建聊天记录表的SQL语句String createTableSql = "CREATE TABLE " + TABLE_CHAT + "("+ COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"+ COLUMN_SENDER + " TEXT,"+ COLUMN_CONTENT + " TEXT,"+ COLUMN_MESSAGE_TYPE + " TEXT,"+ COLUMN_TIMESTAMP + " INTEGER"+ ")";db.execSQL(createTableSql);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 这里简单示例,如果版本升级,先删除旧表再创建新表,实际应用中可能需要更复杂的迁移逻辑db.execSQL("DROP TABLE IF EXISTS " + TABLE_CHAT);onCreate(db);}
}
MainActivity.java(存放在 java 对应包名目录下)
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity {private RecyclerView recyclerViewChat;private EditText editTextMessage;private Button buttonSend;private ChatAdapter chatAdapter;private DatabaseReference databaseReference;private ValueEventListener valueEventListener;private DBHelper dbHelper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);recyclerViewChat = findViewById(R.id.recyclerView_chat);editTextMessage = findViewById(R.id.editText_message);buttonSend = findViewById(R.id.button_send);// 初始化数据库帮助类dbHelper = new DBHelper(this);// 设置RecyclerView的布局管理器LinearLayoutManager layoutManager = new LinearLayoutManager(this);layoutManager.setStackFromEnd(true); // 让新消息显示在底部recyclerViewChat.setLayoutManager(layoutManager);chatAdapter = new ChatAdapter();recyclerViewChat.setAdapter(chatAdapter);// 初始化Firebase数据库引用databaseReference = FirebaseDatabase.getInstance().getReference("messages");// 监听数据库消息变化,实时更新聊天界面(这里可以结合本地数据库做优化,比如先展示本地已有的,再实时更新增量部分等)valueEventListener = new ValueEventListener() {@Overridepublic void onDataChange(@NonNull DataSnapshot dataSnapshot) {List<Message> messages = new ArrayList<>();for (DataSnapshot snapshot : dataSnapshot.getChildren()) {Message message = snapshot.getValue(Message.class);messages.add(message);}chatAdapter = new ChatAdapter();for (Message msg : messages) {chatAdapter.addMessage(msg);}recyclerViewChat.setAdapter(chatAdapter);}@Overridepublic void onCancelled(@NonNull DatabaseError databaseError) {Toast.makeText(MainActivity.this, "读取消息失败", Toast.LENGTH_SHORT).show();}};databaseReference.addValueEventListener(valueEventListener);// 从本地数据库读取历史聊天记录并展示loadChatHistoryFromDB();buttonSend.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String messageText = editTextMessage.getText().toString().trim();if (!messageText.isEmpty()) {// 这里简单假设当前用户名为固定的,实际要做登录获取等逻辑String sender = "user1";Message message = new Message(sender, messageText, "text");// 将消息保存到Firebase数据库(网络存储,用于实时同步等)databaseReference.push().setValue(message);// 同时将消息插入到本地SQLite数据库insertMessageToDB(message);editTextMessage.setText("");}}});}// 从本地数据库加载聊天历史记录的方法private void loadChatHistoryFromDB() {List<Message> historyMessages = new ArrayList<>();SQLiteDatabase db = dbHelper.getReadableDatabase();String[] columns
软件架构介绍
-
表现层(Presentation Layer):
主要由MainActivity和相关的布局文件(activity_main.xml、message_item.xml等)构成。MainActivity负责处理用户界面的交互逻辑,例如用户输入消息后点击发送按钮的事件响应、接收消息并展示在RecyclerView列表中等操作。布局文件则定义了聊天界面的外观,包括聊天消息展示区域、输入框、发送按钮等各部分的视觉呈现。
借助ChatAdapter来将消息数据适配并绑定到RecyclerView的每一项上,实现聊天消息列表的展示,它也是表现层与数据层进行交互的一个中间桥梁,负责把从数据层获取到的数据以合适的形式展示在界面上。 -
业务逻辑层(Business Logic Layer):
消息实体类Message属于此层,它定义了聊天消息的结构,包含发送者、消息内容、消息类型以及时间戳等属性,用于在整个应用中对消息进行统一的抽象表示,方便各层之间传递和处理消息相关的数据。
虽然示例中没有非常复杂的业务逻辑,但像判断消息类型(文本或图片等)来进行不同展示逻辑处理、处理聊天记录的一些简单排序或者筛选等功能都可以在这一层进行扩展和实现,目前简单地体现在ChatAdapter的bind方法中对文本消息根据发送者不同设置不同展示样式等逻辑上。 -
数据访问层(Data Access Layer):
包含DBHelper类,用于管理本地SQLite数据库的创建、打开、升级以及数据的增删改查操作。它封装了与数据库直接交互的细节,例如创建聊天记录表的SQL语句执行、消息数据插入到数据库(insertMessageToDB方法)以及从数据库查询加载聊天历史记录(loadChatHistoryFromDB方法)等操作,为业务逻辑层提供了统一的数据存储和读取接口。
另外还有与Firebase相关的部分(DatabaseReference以及相关的数据库监听逻辑),用于实现网络存储和实时同步聊天记录的功能,通过将消息数据推送到 Firebase 数据库以及监听数据库变化来实时更新界面展示的消息内容,实现多人之间聊天记录的同步。
技术亮点及其实现原理
类似微信聊天界面的布局展示
亮点:打造了一个视觉效果和交互体验较为接近微信聊天界面的布局,能够清晰区分不同用户发送的消息,并且包含了常见的输入框、发送按钮以及表情按钮(预留功能位)等元素,整体界面简洁美观且符合用户使用习惯。
实现原理:
-
布局嵌套与组件使用:在主布局文件(
activity_main.xml)中,采用RelativeLayout作为根布局,方便对各子布局进行相对位置的定位。内部嵌套RecyclerView用于展示聊天消息列表,通过设置其布局属性使其占满除底部输入框区域之外的空间,并允许垂直滚动来显示多条消息。底部的输入框区域则使用LinearLayout进行水平排列,依次放置表情按钮(ImageButton)、文本输入框(EditText)和发送按钮(Button),各组件设置合适的宽度、高度、背景、文本样式等属性来达到美观的效果。 -
消息项布局定制:对于聊天消息列表中的每一项(
message_item.xml),使用LinearLayout来整体布局,左边放置显示发送者头像的ImageView,右边再嵌套一个LinearLayout来放置发送者昵称(TextView)和消息内容(TextView)。通过代码逻辑根据消息发送者判断来为消息内容的TextView设置不同的背景样式(如自己发送的居右对齐、背景颜色不同,对方发送的居左对齐、对应背景颜色等),以此区分不同用户的消息,营造类似微信聊天界面的视觉感受。 -
样式资源引用:在
res/drawable目录下定义了多个 XML 样式资源文件,如用于设置EditText圆角背景的edittext_rounded_bg.xml、发送按钮不同状态下背景样式的button_send_bg.xml以及区分左右消息背景的left_message_bg.xml和right_message_bg.xml等,通过在布局文件中引用这些样式资源,进一步增强了界面的美观性和专业性。
支持多人聊天及实时消息同步
亮点:实现了多人之间进行文本聊天(图片聊天可后续进一步完善扩展),并且聊天记录能够实时同步,所有参与聊天的用户可以及时看到新发送的消息,提升了聊天的交互性和即时性。
实现原理:
-
Firebase实时数据库的使用:利用Firebase提供的实时数据库服务,在应用中初始化DatabaseReference来指向存储聊天消息的数据库节点(示例中为"messages"节点)。当用户点击发送按钮发送一条消息时(在MainActivity中处理发送按钮点击事件),将构造好的Message对象(包含发送者、消息内容、消息类型等信息)通过push().setValue(message)方法推送到Firebase数据库中,Firebase会自动为每条消息生成一个唯一的键值,并按照设定的结构存储消息数据。 -
数据库监听机制:通过添加
ValueEventListener对Firebase数据库指定节点进行监听,在onDataChange回调方法中,一旦数据库中的消息数据发生变化(有新消息插入或者已有消息修改等情况),就会获取到最新的消息数据快照(DataSnapshot),然后解析这些数据创建对应的Message对象列表,并更新到ChatAdapter中,从而实现RecyclerView展示的聊天消息列表实时更新,让所有连接到该数据库的用户都能看到最新的聊天内容。
本地数据库存储聊天记录
亮点:除了使用网络数据库(Firebase 实时数据库)进行实时同步外,还借助本地的 SQLite 数据库来存储聊天记录,既保障了在网络不佳等情况下聊天记录的本地保存,又便于后续查询历史聊天内容、实现离线查看等功能,提升了数据的可靠性和用户体验。
实现原理:
-
数据库创建与表结构定义:创建
DBHelper类继承自SQLiteOpenHelper,在其onCreate方法中执行创建聊天记录表(名为chat_messages)的 SQL 语句,定义了包含消息唯一标识(_id)、发送者(sender)、消息内容(content)、消息类型(message_type)以及时间戳(timestamp)等字段的表结构,用于存储聊天消息的详细信息。 -
数据插入操作:当用户发送消息时,在将消息推送到 Firebase 数据库的同时,会调用
insertMessageToDB方法,该方法获取到可写的SQLite数据库实例(通过dbHelper.getWritableDatabase()),然后使用ContentValues来封装要插入的消息数据,再通过db.insert方法将消息数据插入到对应的聊天记录表中,实现本地数据库的消息存储。 -
历史记录查询与加载:在
MainActivity的loadChatHistoryFromDB方法中,首先获取可读的SQLite数据库实例,然后通过指定查询的列、排序方式等条件,使用db.query方法从聊天记录表中查询出历史聊天记录数据,将获取到的数据游标(Cursor)进行解析,创建Message对象并添加到消息列表中,最后更新到ChatAdapter来展示在聊天界面上,实现了聊天历史记录的加载展示功能。
性能优化与资源管理相关亮点
亮点:注重了一些基本的性能优化和资源管理措施,保障聊天界面滑动流畅不卡顿,并且避免了因不当的资源使用(如数据库监听未及时移除等)导致的内存泄露问题,提升了应用的稳定性和性能表现。
实现原理:
-
RecyclerView优化:在ChatAdapter的onBindViewHolder方法中,尽量保持简洁高效的操作逻辑,避免复杂耗时的计算或频繁创建新的视图对象等浪费资源的行为。例如对于图片消息展示虽然示例中未完整实现,但后续可以采用异步加载图片库(如 Glide 等)结合合适的缓存策略(内存缓存和磁盘缓存)来高效加载图片,减少因图片加载导致的卡顿。同时,利用RecyclerView本身的复用ViewHolder机制,正确实现onCreateViewHolder和onBindViewHolder方法,确保视图的高效复用,提升列表滚动时的性能表现。 -
资源释放与管理:在
MainActivity的onDestroy方法中,添加了对Firebase数据库监听的移除操作(通过databaseReference.removeEventListener(valueEventListener)),当 Activity 销毁时(比如用户退出聊天界面或者切换到其他应用等情况),及时移除数据库监听,避免因持续监听数据库变化导致的内存泄露以及不必要的网络资源占用等问题。对于本地 SQLite 数据库操作,在每次数据库插入或查询等操作完成后,及时关闭数据库连接(如在insertMessageToDB方法结尾处db.close()),防止数据库连接资源的浪费和潜在的资源泄露风险。
自我总结
我是主攻C++方向的,所以在这进两个月的时间里我花了大半个月来学习JAVA、Android 开发和数据库等相关主要知识,包括RecyclerView 使用以及界面布局等知识,也学习了计算机四大件的基础知识。加之学校在大二上学期的学业问题,过量的知识整合对于我来说仍是一个巨大的挑战,我最终的代码调试,程序架构设计以及界面布局仍有很多不足,各个模块之间的耦合也没有很好完成,项目可以说是一塌糊涂,接下来我会继续优化我的项目,知道它是一个完美的APP也不必正在这里阐述自己的总结。
文章链接
在这里向老师表达我最真切的感谢,首先让我来学习到了如此多的只是,也令我深刻反省了自己在计算机领域的不足,单鞋老师!!!
相关文章:
APP聊天项目介绍
项目结构说明 res/layout目录:存放布局相关的 XML 文件,用于定义界面的外观,包含activity_main.xml(主界面布局)和message_item.xml(聊天消息项布局)。 res/drawable目录:存放一些…...
android user版本默认usb模式为充电模式
android插入usb时会切换至默认设置的模式,debug版本为adb,user版本为mtp protected long getChargingFunctions() {// if ADB is enabled, reset functions to ADB// else enable MTP as usual.if (isAdbEnabled()) {return UsbManager.FUNCTION_ADB;} e…...
常见问题QA的前端代码
这个的后端代码参见此文 使用语言向量建立常见问题的模糊搜索-CSDN博客https://blog.csdn.net/chenchihwen/article/details/144207262?spm1001.2014.3001.5501 这段代码实现了一个简单的问答页面,页面分为左右两部分,左侧用于展示对话记录,…...
float globalMapVIsualizationLeafSize; 的中文意思是什么
1.在visual studio 中新建文件 没有包含#include <string>头文件,也可以使用 str2.append(", C");吗? 在 Visual Studio 或任何其他 C 开发环境中,即使新建的文件中没有显式包含 #include <string> 头文件,…...
基于Java Springboot诗词学习APP且微信小程序
一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse微信开…...
CSS学习记录02
CSS颜色 指定颜色是通过使用预定义的颜色名称,或RGB,HEX,HSL,RGBA,HSLA值。 CSS颜色名 在CSS中,可以使用颜色名称来指定颜色: CSS背景色 您可以为HTML元素设置背景色: <h1 s…...
6.1 innoDb逻辑存储结构和架构-简介
InnoDB 是 MySQL 默认的存储引擎,以其强大的事务支持、崩溃恢复能力和高效的数据处理能力广受欢迎。本文从逻辑存储结构、内存架构、磁盘结构到后台线程,逐步剖析 InnoDB 的关键概念,帮助您更好地理解和应用。 1. 逻辑存储结构 InnoDB 的数据…...
C++看懂并使用-----回调函数
一)回调函数的定义 在 C 中,回调函数是一段作为参数传递给其他函数的可执行代码。它允许在一个函数内部的特定点调用外部定义的函数,以实现更灵活的功能。 回调函数(Callback Function)是一种通过函数指针或函数对象&a…...
构建短视频矩阵生态体系开发分享
短视频矩阵系统模型的技术开发是一个综合性强、复杂度高的工程项目,它涵盖了广泛的技术选择与架构规划。以下是该项目开发过程中的关键步骤和核心考虑因素: 需求分析阶段: 明确目标用户群体及其需求,以确保系统设计的针对性和实…...
qt QGraphicsScale详解
1、概述 QGraphicsScale是Qt框架中提供的一个类,它提供了一种简单而灵活的方式在QGraphicsView框架中实现缩放变换。通过设置水平和垂直缩放因子、缩放中心点,可以创建各种缩放效果,提升用户界面的交互性和视觉吸引力。结合QPropertyAnimati…...
CAD 文件 批量转为PDF或批量打印
CAD 文件 批量转为PDF或批量打印,还是比较稳定的 1.需要本地安装CAD软件 2.通过 Everything 搜索工具搜索,DWG To PDF.pc3 ,获取到文件目录 ,替换到代码中, originalValue ACADPref.PrinterConfigPath \ r"C:…...
Java基础面试题16:简述Servlet的体系结构
Servlet 是 JavaEE 技术中的一大核心组件,它运行在服务器端,用于处理客户端的请求并生成响应。如果你想深入了解它的体系结构,下面会用通俗的语言带你一步步搞懂。 1. Servlet API:开发者和容器沟通的桥梁 Servlet API 是开发 S…...
Web开发基础学习——理解React组件中的根节点
Web开发基础学习系列文章目录 第一章 基础知识学习之理解React组件中的根节点 文章目录 Web开发基础学习系列文章目录前言一、根节点的概念二、示例解释总结 前言 在 React 应用中,根节点(Root Node)是指 React 组件树的起始点,…...
【人工智能】探索自然语言生成(NLG):用GPT生成文本
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 自然语言生成(Natural Language Generation, NLG)是自然语言处理(NLP)领域的重要分支,旨在生成符合语法和语义的自然语言文本。近年来,基于深度学习的生成式预训练模型(GPT)在NLG任务中取得了巨大…...
挑战用React封装100个组件【004】
项目地址 https://github.com/hismeyy/react-component-100 组件描述 组件适用于展示图片的地方,提供了small,medium,large三种大小。可以删除图片,也可以全屏预览图片。 样式展示 前置依赖 今天我们的这个挑战需要用用到了…...
vue elementui layout布局组件实现规则的弹性布局
背景:遇到在一个容器里,采用弹性盒布局的时候,如果元素个数改变,元素的排列会错乱。 解决方式 方式一:之前遇到的时候,是采用计算元素个数的方式,采用透明元素补齐的方式(比如一个有…...
SpringBoot Web 开发请求参数
SpringBoot Web 开发请求参数 简单的 web 请求: @RestController public class HelloController {@RequestMapping("sayHello")public String sayHello(){System.out.println("Hello World");return "hello world";} }获取请求参数 简单参数…...
python7学习笔记-循环、迭代、pass
九九乘法表-while循环 right 1 while right < 9:left 1while left < right:print(f{left}x{right}{left * right},end\t)left 1print()right 1 # #效果: #1x11 #1x22 2x24 #1x33 2x36 3x39 #1x44 2x48 3x412 4x416 #1x55 2x510 3x515 4x520 5x525 #…...
LeetCode78:子集
链接:78. 子集 假设我们要求[1, 2, 3]的子集: 我们知道[1, 2]的子集是A: 而[1, 2, 3]就是比[1, 2]多了一个元素3;所以将3加入到上述A中的每个集合中,得到一个新集合B: 结论:[1, 2, 3]的子集就…...
Linux 安装scala
文章目录 Linux 安装scala下载环境变量配置 Linux 安装scala 前提linux需要已经安装好JDK(JDK安装),Scala对JDK版本有明确的要求。通常,Scala的稳定版本要求JDK版本不低于1.8。例如,Scala 2.11.8和2.12.7版本都要求JD…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...
