当前位置: 首页 > news >正文

uniapp结合腾讯云及时通信IM的聊天记录本地存储方案

uniapp结合腾讯云及时通信IM的聊天记录本地存储方案

UniApp 是一个跨平台的应用开发框架,可以使用 Vue.js 开发多端应用(如H5、小程序、App等)。在 UniApp 中,可以使用 uni-app 提供的文件系统 API 完成本地文件存储的操作。

1.具体实现方式如下:

创建一个用于存储聊天记录的目录,可以使用 uni-app 提供的 uni.getFileSystemManager API 创建:

uni.getFileSystemManager().mkdirSync(`${uni.env.USER_DATA_PATH}/chat`);

将聊天记录以文件的形式存储在该目录下,可以使用 fs.writeFileSync API 实现:

const chatContent = '这是一条聊天记录'; // 假设聊天记录内容为字符串
const fileName = 'chatRecord_001.txt'; // 文件名可以按照一定的规则生成try {uni.getFileSystemManager().writeFileSync(`${uni.env.USER_DATA_PATH}/chat/${fileName}`, chatContent, 'utf-8');
} catch (e) {console.error(e);
}

读取本地存储的聊天记录,可以使用 fs.readFileSync API 实现:

const fileName = 'chatRecord_001.txt';try {const chatContent = uni.getFileSystemManager().readFileSync(`${uni.env.USER_DATA_PATH}/chat/${fileName}`, 'utf-8');console.log(chatContent);
} catch (e) {console.error(e);
}

结合腾讯云即时通信IM开发聊天软件时,可以使用uni-app提供的本地存储API将聊天记录存储在本地,具体实现方案如下:

1.1 初始化聊天记录:

当用户进入聊天界面时,可以通过查询本地存储是否存在聊天记录,如果不存在则新建一个聊天记录文件,同时将腾讯云IM服务端的聊天记录下载到本地存储中。

// 初始化聊天记录,userId表示当前用户的ID,toUserId表示聊天对象的ID
function initChatRecords(userId, toUserId) {const fileName = `chat_${userId}_${toUserId}.json`;const fileContent = {chatHistory: [], // 聊天记录数组lastReadTime: Date.now(), // 最后一条已读消息的时间戳};try {const chatContent = uni.getStorageSync(fileName);if (chatContent) {// 本地存储中已经存在聊天记录,直接读取const chatRecords = JSON.parse(chatContent);fileContent.chatHistory = chatRecords.chatHistory;fileContent.lastReadTime = chatRecords.lastReadTime;} else {// 本地存储中不存在聊天记录,从IM服务器下载并保存到本地getChatHistory(userId, toUserId).then((res) => {if (res.data) {const chatHistory = formatChatHistory(res.data);fileContent.chatHistory = chatHistory;uni.setStorageSync(fileName, JSON.stringify(fileContent));}});}} catch (e) {console.error(e);}return fileContent;
}

1.2 存储聊天记录:

当用户发送一条聊天消息时,将该消息存储到本地的聊天记录文件中,同时更新最后一条已读消息的时间戳。

// 存储聊天记录,userId表示当前用户的ID,toUserId表示聊天对象的ID,message表示聊天消息对象
function saveChatRecord(userId, toUserId, message) {const fileName = `chat_${userId}_${toUserId}.json`;try {const chatContent = uni.getStorageSync(fileName);if (chatContent) {const chatRecords = JSON.parse(chatContent);chatRecords.chatHistory.push(message);uni.setStorageSync(fileName, JSON.stringify(chatRecords));}} catch (e) {console.error(e);}
}

1.3 更新聊天记录:

当用户接收到新的聊天消息时,将该消息存储到本地的聊天记录文件中,同时更新最后一条已读消息的时间戳。

// 更新聊天记录,userId表示当前用户的ID,toUserId表示聊天对象的ID,message表示聊天消息对象
function updateChatRecord(userId, toUserId, message) {const fileName = `chat_${userId}_${toUserId}.json`;try {const chatContent = uni.getStorageSync(fileName);if (chatContent) {const chatRecords = JSON.parse(chatContent);chatRecords.chatHistory.push(message);chatRecords.lastReadTime = Date.now(); // 更新最后一条已读消息的时间戳

2.更详细的实现方案:

2.1 聊天记录的本地存储

在uni-app中,可以使用uni-storage插件来实现本地存储。为了方便管理,可以将每个聊天对象的聊天记录存储在单独的文件中。例如,对于一个名为A的用户和一个名为B的用户的聊天记录,可以将它们存储在一个名为chat_A_B.json的文件中。

为了确保在保存数据时出现任何错误时能够及时捕获和处理异常,我们可以在代码中使用try-catch块。当我们从本地存储中读取聊天记录时,需要检查该文件是否存在,如果不存在,则需要创建一个空的聊天记录文件。

以下是一个简单的实现示例:

// 存储聊天记录
function saveChatRecord(userId, toUserId, message) {const fileName = `chat_${userId}_${toUserId}.json`;try {const chatContent = uni.getStorageSync(fileName) || '{"chatHistory": []}';const chatRecords = JSON.parse(chatContent);chatRecords.chatHistory.push(message);uni.setStorageSync(fileName, JSON.stringify(chatRecords));} catch (e) {console.error(e);}
}// 读取聊天记录
function readChatRecords(userId, toUserId) {const fileName = `chat_${userId}_${toUserId}.json`;try {const chatContent = uni.getStorageSync(fileName) || '{"chatHistory": []}';return JSON.parse(chatContent).chatHistory;} catch (e) {console.error(e);return [];}
}

2.2 聊天记录的初始化

在用户打开聊天窗口时,我们需要确保该聊天记录文件存在。如果文件不存在,则需要从服务器获取聊天记录,并将其存储到本地文件中。

以下是一个示例代码:

function initChatRecords(userId, toUserId) {const fileName = `chat_${userId}_${toUserId}.json`;const fileContent = {chatHistory: [],lastReadTime: Date.now(),};try {const chatContent = uni.getStorageSync(fileName);if (chatContent) {// 如果文件存在,则读取文件中的聊天记录const chatRecords = JSON.parse(chatContent);fileContent.chatHistory = chatRecords.chatHistory;fileContent.lastReadTime = chatRecords.lastReadTime;} else {// 如果文件不存在,则从服务器获取聊天记录,并存储到本地文件中getChatHistory(userId, toUserId).then((res) => {if (res.data) {const chatHistory = formatChatHistory(res.data);fileContent.chatHistory = chatHistory;uni.setStorageSync(fileName, JSON.stringify(fileContent));}});}} catch (e) {console.error(e);}return fileContent;
}

在上述代码中,getChatHistory函数用于从服务器获取聊天记录,formatChatHistory函数用于将服务器返回的聊天记录格式化为符合本地存储要求的格式。

2.3 如何标记已读消息

我们可以在本地存储中为每个聊天记录文件添加一个lastReadTime属性来标记最后一次已读消息的时间戳。当用户打开聊天窗口时,我们可以将该属性更新为当前时间戳,表示用户已经查看了该聊天记录中的所有消息。

以下是一个示例代码:

// 标记聊天记录已读
function markChatRecordAsRead(userId, toUserId) {const fileName = `chat_${userId}_${toUserId}.json`;const chatContent = uni.getStorageSync(fileName);if (chatContent) {try {const chatRecords = JSON.parse(chatContent);chatRecords.lastReadTime = Date.now();uni.setStorageSync(fileName, JSON.stringify(chatRecords));} catch (e) {console.error(e);}}
}

2.4 何时修改本地存储

我们需要在以下情况下更新本地存储:

  • 当用户发送一条新的聊天消息时,将该消息存储到本地文件中。
  • 当用户打开聊天窗口时,需要初始化该聊天记录文件。如果该文件不存在,则需要从服务器获取聊天记录,并将其存储到本地文件中。
  • 当用户查看聊天记录时,需要将lastReadTime属性更新为当前时间戳,表示已读。

需要注意的是,我们需要确保所有本地存储的操作都是异步的,以避免阻塞应用程序。

2.5 如何在App中读取本地聊天记录

在App中,我们可以根据用户选择的聊天对象,读取该聊天对象的聊天记录文件。例如,如果用户选择与B用户聊天,则我们可以读取chat_A_B.json文件中的聊天记录。

以下是一个示例代码:

function loadChatRecords(userId, toUserId) {const fileName = `chat_${userId}_${toUserId}.json`;try {const chatContent = uni.getStorageSync(fileName);if (chatContent) {const chatRecords = JSON.parse(chatContent);return chatRecords.chatHistory;}} catch (e) {console.error(e);}return [];
}

在上述代码中,loadChatRecords函数用于从本地存储中读取指定聊天记录文件中的聊天记录。

总结

综上所述,我们可以使用uni-storage插件实现聊天记录的本地存储,并使用lastReadTime属性来标记已读消息。当用户打开聊天窗口时,我们需要初始化该聊天记录文件。如果该文件不存在,则需要从服务器获取聊天记录,并将其存储到本地文件中。当用户发送一条新的聊天消息时,将该消息存储到本地文件中。在App中,我们可以根据用户选择的聊天对象,读取该聊天对象的聊天记录文件。

3.遇到的问题

除了以上提到的实现方案外,还有一些细节问题需要考虑。以下是一些需要注意的点:

3.1 本地存储容量限制

不同的平台和设备可能对本地存储容量有不同的限制,因此我们需要根据实际情况来确定每个聊天记录文件的最大容量,并及时清理过期的聊天记录。否则,当本地存储空间不足时,将无法存储新的聊天记录。

3.2 聊天记录加密

为了保护用户隐私,我们应该将聊天记录进行加密处理。可以使用一些加密算法来对聊天记录文件进行加密,以确保用户的聊天记录不会被窃取。

3.3 消息同步

如果用户在不同的设备上使用同一个账号登录,那么他们的聊天记录应该能够同步到所有设备上。因此,在本地存储方案中,我们需要考虑如何实现聊天记录的同步。

可以使用云存储服务,如腾讯云对象存储,来实现聊天记录的云端存储和同步。每当用户在一个设备上发送了一条新的聊天消息时,我们可以将该消息同步到云端存储中。而当用户在另一个设备上打开聊天窗口时,我们可以从云端存储中获取最新的聊天记录,并将其更新到本地存储中。

3.4 数据备份

由于本地存储存在数据丢失的风险,我们需要定期对聊天记录进行备份。可以将聊天记录文件上传到云存储服务中,并在需要恢复数据时,从云存储中下载备份数据。

总结

以上是实现uniapp结合腾讯云及时通信IM开发聊天软件的聊天记录本地存储方案。在实际应用中,我们需要考虑到各种细节问题,如本地存储容量限制、聊天记录加密、消息同步和数据备份等。通过对这些问题进行细致的考虑和处理,我们可以为用户提供更加稳定和安全的聊天体验。

4.怎么解决本地存储容量限制问题?

当本地存储空间不足时,我们可以通过以下几种方式来解决:

4.1 清理过期的聊天记录

我们可以在应用中实现一个定期清理聊天记录的功能,将过期的聊天记录文件删除,从而释放存储空间。这可以通过设置定期清理的时间间隔或根据存储空间的占用率来触发清理操作。

4.2 使用本地缓存

可以使用一些本地缓存机制来存储聊天记录,如使用 uni-app 内置的本地存储 API(如 localStorage、sessionStorage)来存储数据。这种方式可以帮助我们充分利用设备的存储空间,并且可以通过设置缓存过期时间来控制存储的数据大小。

4.3 利用云存储

我们可以将聊天记录存储到云端,使用云存储服务来解决本地存储空间不足的问题。当用户在本地存储空间不足时,我们可以通过下载云端聊天记录来缓解本地存储空间的压力。

4.4 优化聊天记录文件大小

我们可以通过优化聊天记录文件的大小来减少本地存储空间的占用。比如可以压缩聊天记录中的图片、视频等多媒体文件,或者将多个聊天记录文件合并成一个文件等方式。

总之,我们需要在开发应用的过程中注意本地存储空间的使用情况,并在必要时采取相应的措施来解决空间不足的问题。同时,为了提高用户体验,我们需要在保证数据安全的前提下,尽可能地扩大应用所能使用的存储空间。

5.怎么解决聊天记录加密问题,比如加密和解密?

聊天记录的加密问题一般可以通过对消息内容进行加密来解决。在实现聊天记录加密时,我们可以采用以下的方式:

5.1 使用对称加密算法

对称加密算法可以使用同一个密钥进行加密和解密操作,比如常用的 AES、DES 等算法。在使用对称加密算法时,发送方需要先使用密钥对消息内容进行加密,然后再发送给接收方,接收方则需要使用同样的密钥对消息内容进行解密。

5.2 使用非对称加密算法

非对称加密算法需要使用公钥和私钥来进行加密和解密操作,比如常用的 RSA 算法。在使用非对称加密算法时,发送方需要使用接收方的公钥对消息内容进行加密,然后再发送给接收方,接收方则需要使用自己的私钥对消息内容进行解密。

5.3 采用混合加密方案

混合加密方案是将对称加密算法和非对称加密算法结合起来使用,利用非对称加密算法来安全地传输对称加密算法的密钥,然后使用对称加密算法对消息内容进行加密和解密。这种方案既保证了数据的安全性,又能够提高加密和解密的效率。

无论采用哪种方式,实现聊天记录加密时还需要注意以下几点:

  1. 安全存储密钥

密钥的安全存储对于加密方案的安全性至关重要。我们应该采用安全的方式存储密钥,比如使用硬件模块来存储密钥,或者将密钥加密后再存储。

  1. 避免密钥泄露

密钥的泄露会导致加密方案失去作用,因此我们需要采取措施来避免密钥的泄露。比如限制密钥的使用范围、限制密钥的使用次数等。

  1. 处理加解密性能

加解密算法的性能会影响应用的响应速度,因此我们需要在实现加密方案时注意优化加解密算法的性能,比如使用硬件加速、缓存加解密结果等方式。

总之,在实现聊天记录加密时,我们需要权衡安全性和性能,采用合适的加密方案来保障数据的安全。同时还需要考虑密钥的管理、密钥的安全存储等问题。

5.4 示例代码

结合了聊天记录的存储和读取过程,同时采用了对称加密算法 AES 进行加密和解密。

// 加密消息
function encryptMessage(message, key) {const iv = crypto.getRandomValues(new Uint8Array(16)); // 生成随机的 IVconst encodedMessage = new TextEncoder().encode(message); // 将消息编码为字节数组const cipher = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, encodedMessage); // 使用 AES-GCM 加密消息const encryptedMessage = new Uint8Array(iv.length + new Uint8Array(cipher).length);encryptedMessage.set(iv);encryptedMessage.set(new Uint8Array(cipher), iv.length); // 将 IV 和加密后的消息组合成一个字节数组return encryptedMessage;
}// 解密消息
async function decryptMessage(encryptedMessage, key) {const iv = encryptedMessage.slice(0, 16); // 从字节数组中获取 IVconst ciphertext = encryptedMessage.slice(16); // 从字节数组中获取加密后的消息const plaintext = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, ciphertext); // 使用 AES-GCM 解密消息return new TextDecoder().decode(plaintext); // 将解密后的字节数组转换为字符串
}// 存储聊天记录
function storeChatRecord(userId, chatRecord, key) {const encryptedRecord = encryptMessage(JSON.stringify(chatRecord), key); // 对聊天记录进行加密const fileName = `${userId}-chat-record.dat`;const blob = new Blob([encryptedRecord], { type: 'application/octet-stream' });const file = new File([blob], fileName);// 将加密后的聊天记录存储为本地文件window.requestFileSystem(window.PERSISTENT, 1024 * 1024, async (fs) => {const fileEntry = await createFile(fs.root, fileName);await writeFile(fileEntry, file);});
}// 读取聊天记录
async function loadChatRecord(userId, key) {const fileName = `${userId}-chat-record.dat`;// 从本地文件中读取加密后的聊天记录const file = await getFile(fileName);const encryptedRecord = await readFile(file);const chatRecord = await decryptMessage(encryptedRecord, key); // 对加密后的聊天记录进行解密return JSON.parse(chatRecord);
}// 生成 AES 密钥
async function generateAesKey() {return crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 },true,['encrypt', 'decrypt']);
}// 初始化聊天记录加密密钥
async function initChatRecordEncryption(userId) {const keyName = `${userId}-encryption-key`;let key = await getKey(keyName);if (!key) {key = await generateAesKey();await setKey(keyName, key);}return key;
}// 存储密钥
async function setKey(keyName, key) {const exportedKey = await crypto.subtle.exportKey('jwk', key);localStorage.setItem(keyName, JSON.stringify(exportedKey));
}// 获取密钥
async function getKey(keyName) {const exportedKey = localStorage.getItem(keyName);if (!exportedKey) {return null;}return crypto.subtle.importKey('jwk',JSON.parse(exportedKey),{ name: 'AES-GCM', length: 256 },true,['encrypt', 'decrypt']);
}// 创建文件
async function createFile(rootDirEntry, fileName) {return new Promise((resolve, reject) => {rootDirEntry.getFile(fileName,{ create: true, exclusive: false },resolve,reject);});
}// 写入文件
async function writeFile(fileEntry, file) {return new Promise((resolve, reject) => {fileEntry.createWriter((fileWriter) => {fileWriter.onwriteend = resolve;fileWriter.onerror = reject;fileWriter.write(file);});});
}// 获取文件
async function getFile(fileName) {return new Promise((resolve, reject) => {window.requestFileSystem(window.PERSISTENT, 1024 * 1024, (fs) => {fs.root.getFile(fileName,{},resolve,(error) => {if (error.code === FileError.NOT_FOUND_ERR) {// 如果文件不存在,返回空文件对象resolve(new File([], fileName));} else {reject(error);}});});});
}// 读取文件
async function readFile(file) {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onloadend = () => {resolve(new Uint8Array(reader.result));};reader.onerror = reject;reader.readAsArrayBuffer(file);});
}

在实现过程中,我们使用 AES-GCM 对称加密算法进行加密和解密,同时采用了随机生成的 IV,增加了加密的强度和安全性。加密密钥使用 JWK 格式进行存储和导入,可以更方便地在不同的设备和浏览器之间共享和传输。在存储聊天记录时,我们将加密后的记录存储为一个二进制文件,通过 File API 和 File System API 实现对本地文件的读写操作。在读取聊天记录时,我们首先读取本地文件,并对其中的加密数据进行解密,再将解密后的数据转换为 JSON 格式,最后返回聊天记录对象。

相关文章:

uniapp结合腾讯云及时通信IM的聊天记录本地存储方案

uniapp结合腾讯云及时通信IM的聊天记录本地存储方案 UniApp 是一个跨平台的应用开发框架,可以使用 Vue.js 开发多端应用(如H5、小程序、App等)。在 UniApp 中,可以使用 uni-app 提供的文件系统 API 完成本地文件存储的操作。 1.…...

PyQGIS开发 -- 基础学习笔记

1、自主学习QGIS开发虽然QGIS本身功能强大,但还是架不住我们要编写新的功能、新的业务流程、新的算法。前文中我们提到,扩展QGIS有2种方法,一是用Python、C来写QGIS的插件;另一种就是基于QGIS的C API开发独立应用程序。然而后者资…...

一篇了解模块打包工具之 ——webpack(1)

本篇采用问题引导的方式来学习webpack,借此梳理一下自己对webpack的理解,将所有的知识点连成一条线,形成对webpack的记忆导图。 最终目标,手动构建一个vue项目,目录结构参考vue-cli创建出来的项目 一、问问题 1. 第…...

k8s学习之路 | Day16 k8s 中的容器初探

文章目录容器镜像镜像名称镜像拉取策略私有仓库的拉取策略容器的环境变量和启动命令容器的环境变量容器的启动命令容器的生命周期钩子postStartpreStop容器的探针startupProbelivenessProbereadinessProbek8s 集群中最小的管理单元就是一个Pod,而Pod里面才是容器&am…...

export、import、commit、save、load的区别

目录1. docker export 和 docker import2. docker commit3.docker save 和 docker load1. docker export 和 docker import docker export 容器ID/容器Name > xxx.tar 导出一个容器快照 docker import xxx.tar NewImageName:tag 导入一个容器快照到本地镜像库 适用场景&a…...

多部委联合举办中国人工智能大赛启动会在厦召开,快商通亮相发言

站在“第二个百年奋斗目标”的新起点上,为深入推动我国人工智能产业创新发展,发掘一批人工智能优秀团队, 国家互联网信息办公室、工业和信息化部、公安部、国家广播电视总局、厦门市人民政府将联合主办第四届中国人工智能大赛 。快商通联合创…...

js红宝书学习笔记(1-6章)

就按照原书中写的章节顺序记笔记了, 还有可能我学过js一段时间了,可能有些对于新手的细节会忽略,但是会尽量写全的~ 1.第一章 什么是JavaScript 1.1讲了一些历史,所以我们从1.2开始看 1.2 JavaScript的实现 完整的JaveScript包…...

第十四届蓝桥杯第三期官方模拟赛C\C++题解

文章目录A-填空题题意算法参考代码(C)B-填空题题意算法参考代码(C)C-填空题题意算法参考代码(C)D-填空题题意算法参考代码(C)E-填空题题意算法参考代码(C)F题…...

API接口安全

目前项目都是前后端分离或者有对外提供接口的需求,在这些情况下,就要考虑接口安全。 如果不重视接口安全,可能导致严重的危害,例如数据盗取,服务宕机等。 可能的安全问题: 1.明文密码被攻击者抓包看到 前端可对密码或…...

2023前端一面vue面试题合集

函数式组件优势和原理 函数组件的特点 函数式组件需要在声明组件是指定 functional:true不需要实例化,所以没有this,this通过render函数的第二个参数context来代替没有生命周期钩子函数,不能使用计算属性,watch不能通过$emit 对外暴露事件&…...

【Leetcode 剑指Offer】第 5 天 查找算法(中等)

查找算法剑指 Offer 04. 二维数组中的查找剑指 Offer 11. 旋转数组的最小数字剑指 Offer 50. 第一个只出现一次的字符Python字典基础哈希表(python中是dict())有序哈希表第一个中等,后两个简单题。剑指 Offer 04. 二维数组中的查找 题&#…...

薯条投放适合哪些笔记?小红书薯条投放的3种模式

随着小红书平台的种草推广模式兴盛,薯条投放这个词也渐渐进入大众的视野,今天就来给大家讲讲什么是薯条投放,以及薯条投放适合哪些笔记。一、什么是薯条投放?薯条是一款为小红书用户打造的笔记推广工具,用户可选择推广目标&#…...

记录第一个Python练习的过程

题目如下 编写一个名为collatz()的函数,它有一个名为number的参数。如果参数是偶数,那么collatz()就打印出number // 2,并返回该值。如果number是奇数,collatz()就打印并返回3 * number 1。 然后编写一个程序,让用户…...

【Python】3.3实现多线程

程序Program进程Process线程Thread为完成特定任务而用计算机语言编写的一组计算机能识别和执行的指令的集合。程序是指令、数据及其组织形式的描述,一段静态代码,静态对象。计算机中的程序关于某数据集合上的一次执行过程。进程是程序的实体,…...

在linux中使用lftp和sftp下载文件(夹)

一、首先确保你的系统中已经下载了lftp和sftp。 1.安装lftp sudo apt install lftp sudo apt install screen 2.安装sftp 在Linux系统中,一般RedHat系统默认已经安装了openssh-client和openssh-server,即默认已经集成了sftp服务,不需要重…...

Docker简介与用法

文章目录1、Docker简介1.1、Docker能解决什么问题1.2、什么是虚拟机技术1.2.1、虚拟机的缺点1.3、什么是容器1.3.1、容器与虚拟机比较1.4、分析 Docker 容器架构1.4.1、Docker客户端和服务器1.4.2、Docker 镜像(Image)1.4.3、Docker 容器(Container)1.4.4、Docker 仓库(reposit…...

基于海鸥算法改进的DELM分类-附代码

海鸥算法改进的深度极限学习机DELM的分类 文章目录海鸥算法改进的深度极限学习机DELM的分类1.ELM原理2.深度极限学习机(DELM)原理3.海鸥算法4.海鸥算法改进DELM5.实验结果6.参考文献7.Matlab代码1.ELM原理 ELM基础原理请参考:https://blog.c…...

linux基本功系列之mount命令实战

文章目录前言一. mount命令的介绍二. 语法格式及常用选项三. 参考案例3.1 将iso镜像挂载到/mnt上3.2 把某个分区挂载到/sdb1上3.3 用只读的形式把/dev/sdb2挂载到/sdb2上3.4 设置自动挂载总结前言 大家好,又见面了,我是沐风晓月,本文是专栏【…...

力扣Top100题之两数相加(Java解法)

0 题目描述 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数…...

【测试】Python手机自动化测试库uiautomator2和weditor的详细使用

1.说明 我们之前在电脑操作手机进行自动化测试,基本上都是通过Appium的,这个工具确实强大,搭配谷歌官方的UiAutomator基本上可以完成各种测试,但缺点也很明显,配置环境太麻烦了,需要jdk、sdk等&#xff0c…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 ​ 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦&#xff0…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...

《Offer来了:Java面试核心知识点精讲》大纲

文章目录 一、《Offer来了:Java面试核心知识点精讲》的典型大纲框架Java基础并发编程JVM原理数据库与缓存分布式架构系统设计二、《Offer来了:Java面试核心知识点精讲(原理篇)》技术文章大纲核心主题:Java基础原理与面试高频考点Java虚拟机(JVM)原理Java并发编程原理Jav…...