JS JSON.stringify介绍(JS序列化、JSON字符串 )(遍历输入值的所有可枚举属性,将其转换为文本表示)缓存序列化、状态管理与时间旅行、replacer

文章目录

  • JSON.stringify 全解析
    • 1. 基本概念
    • 2. 序列化原理
      • 1. 对于原始类型,直接转换为对应的字符串表示
      • 2. 对于对象和数组,递归处理其每个属性或元素
      • 3. 应用特殊规则处理日期、函数、Symbol 等特殊类型
      • 4. 检测并防止循环引用
      • 5. 应用 replacer 函数或数组进行自定义转换
      • 代码示例
    • 3. 为什么需要序列化
      • 3.1 数据传输需求
      • 3.2 数据持久化
      • 3.3 数据复制
      • 3.4 跨语言通信
    • 4. 语法结构
      • 4.1 参数详解
    • 5. 基础用法示例
    • 6. 特殊数据类型处理
      • 6.1 原始数据类型
      • 6.2 复杂对象处理
        • 注意:默认情况下,Map、Set、RegExp 等这些特殊对象类型被转换为空对象 `{}`,这会导致数据完全丢失。
          • 如何正确序列化这些特殊类型:要解决这个问题,需要在序列化前进行特殊处理:
          • 通用解决方案:可以创建一个通用的序列化工具函数,处理所有这些特殊类型:
    • 7. replacer 参数应用
      • 7.1 使用(匿名)函数作为 replacer
      • 7.2 使用数组作为 replacer
    • 8. 处理 toJSON 方法
    • 9. 易犯错的场景
      • 9.1 循环引用问题
      • 9.2 数据丢失问题
      • 9.3 精度与大数问题
    • 10. 高级应用场景
      • 10.1 深拷贝实现
      • 10.2 缓存序列化
      • 10.3 状态管理与时间旅行
    • 11. 性能考量
      • 11.1 大数据处理
    • 12. 常见陷阱与解决方案
      • 12.1 处理数值精度问题
      • 12.2 处理特殊字符
    • 13. 序列化的安全问题
    • 14. 与其他序列化方法比较
      • 14.1 JSON.stringify vs 手动序列化
      • 14.2 JSON vs 其他序列化格式
    • 15. 最佳实践
      • 15.1 序列化前数据清理
      • 15.2 错误处理最佳实践
    • 16. 总结

JSON.stringify 全解析

1. 基本概念

JSON.stringify 是 JavaScript 中的一个核心方法,用于将 JavaScript 对象或值转换为 JSON 字符串。这个方法对于数据序列化、网络传输和存储至关重要。

2. 序列化原理

JSON.stringify 的核心原理是遍历输入值的所有可枚举属性,然后将其转换为文本表示。这个过程遵循特定的规则和算法:

1. 对于原始类型,直接转换为对应的字符串表示

2. 对于对象和数组,递归处理其每个属性或元素

3. 应用特殊规则处理日期、函数、Symbol 等特殊类型

4. 检测并防止循环引用

5. 应用 replacer 函数或数组进行自定义转换

代码示例

// 序列化内部过程伪代码实现
function pseudoStringify(value, replacer, space) {// 检查循环引用const seen = new WeakSet();function serialize(key, val) {// 应用 replacer 函数(如果提供)if (typeof replacer === 'function') {val = replacer(key, val);}// 根据数据类型处理if (val === null) return 'null';if (val === undefined) return undefined;if (typeof val === 'string') return `"${escapeString(val)}"`;if (typeof val === 'number') return isFinite(val) ? String(val) : 'null';if (typeof val === 'boolean') return String(val);// 检查对象循环引用if (typeof val === 'object') {if (seen.has(val)) {throw new TypeError('循环引用无法转换为JSON');}seen.add(val);// 处理数组if (Array.isArray(val)) {// 数组序列化逻辑...}// 处理对象// 对象序列化逻辑...}}return serialize('', value);
}

3. 为什么需要序列化

3.1 数据传输需求

// 前端发送数据到服务器
async function saveUserData(userData) {try {// 将复杂的 JavaScript 对象转换为字符串// 因为网络请求只能传输字符串const jsonData = JSON.stringify(userData);const response = await fetch('/api/users', {method: 'POST',headers: {'Content-Type': 'application/json'},body: jsonData // 使用序列化后的JSON字符串});return await response.json();} catch (error) {console.error('数据传输失败:', error);}
}

3.2 数据持久化

// 将应用状态保存到本地存储
function saveAppState(state) {// JavaScript对象无法直接存储,必须转换为字符串localStorage.setItem('appState', JSON.stringify(state));
}// 从本地存储恢复应用状态
function loadAppState() {const savedState = localStorage.getItem('appState');// 将字符串转回JavaScript对象return savedState ? JSON.parse(savedState) : null;
}

3.3 数据复制

// 深拷贝对象
function deepClone(obj) {// 利用序列化再反序列化实现深拷贝// 序列化会创建全新的字符串表示// 反序列化会基于这个表示创建全新的对象结构return JSON.parse(JSON.stringify(obj));
}

3.4 跨语言通信

JSON 作为一种通用数据格式,实现了不同编程语言和系统之间的数据交换。JavaScript 的 JSON.stringify 和其他语言中的序列化工具产生兼容的输出格式。

4. 语法结构

JSON.stringify(value[, replacer[, space]])

4.1 参数详解

  • value: 要转换的 JavaScript 值,通常是对象或数组
  • replacer: 可选参数,可以是函数或数组,用于自定义转换过程
  • space: 可选参数,用于美化输出的 JSON 字符串

5. 基础用法示例

const data = {name: "张三",age: 30,isActive: true,skills: ["JavaScript", "HTML", "CSS"]
};// 最基本的转换
const jsonString = JSON.stringify(data);
// 结果: {"name":"张三","age":30,"isActive":true,"skills":["JavaScript","HTML","CSS"]}// 带缩进的美化输出
const prettyJson = JSON.stringify(data, null, 2);
// 结果会带有缩进和换行,更易于阅读

6. 特殊数据类型处理

6.1 原始数据类型

// 数字转换
JSON.stringify(42); // "42"// 字符串转换 - 注意会添加双引号
JSON.stringify("测试"); // "\"测试\""// 布尔值转换
JSON.stringify(true); // "true"// null 转换
JSON.stringify(null); // "null"// undefined、函数和 Symbol 被忽略(对象属性)或转为 null(数组元素)
JSON.stringify(undefined); // undefined
JSON.stringify([1, undefined, 2]); // "[1,null,2]"
JSON.stringify({a: undefined}); // "{}"

6.2 复杂对象处理

// 日期对象会被转换为字符串
const date = new Date();
JSON.stringify(date); // 如:"2023-11-20T08:00:00.000Z"// Map、Set、RegExp 等会被转为空对象
JSON.stringify(new Map([['key', 'value']])); // "{}"
JSON.stringify(new Set([1, 2, 3])); // "{}"
JSON.stringify(/pattern/); // "{}"// 循环引用会导致错误
const obj = {};
obj.self = obj;
// JSON.stringify(obj); // 抛出错误: TypeError: Converting circular structure to JSON
注意:默认情况下,Map、Set、RegExp 等这些特殊对象类型被转换为空对象 {},这会导致数据完全丢失。
如何正确序列化这些特殊类型:要解决这个问题,需要在序列化前进行特殊处理:
// 序列化 Map 对象
function stringifyMap(map) {return JSON.stringify({dataType: 'Map',value: Array.from(map.entries()) // 转换为二维数组});
}const myMap = new Map([['key1', 'value1'], ['key2', 'value2']]);
const mapJson = stringifyMap(myMap);
// 结果: {"dataType":"Map","value":[["key1","value1"],["key2","value2"]]}// 反序列化回 Map
function parseMap(jsonString) {const obj = JSON.parse(jsonString);if (obj.dataType === 'Map') {return new Map(obj.value);}throw new Error('不是有效的 Map JSON');
}
// 序列化 Set 对象
function stringifySet(set) {return JSON.stringify({dataType: 'Set',value: Array.from(set.values())});
}const mySet = new Set([1, 2, 3, 4]);
const setJson = stringifySet(mySet);
// 结果: {"dataType":"Set","value":[1,2,3,4]}// 反序列化回 Set
function parseSet(jsonString) {const obj = JSON.parse(jsonString);if (obj.dataType === 'Set') {return new Set(obj.value);}throw new Error('不是有效的 Set JSON');
}
// 序列化 RegExp 对象
function stringifyRegExp(regex) {return JSON.stringify({dataType: 'RegExp',source: regex.source,flags: regex.flags});
}const myRegex = /pattern/ig;
const regexJson = stringifyRegExp(myRegex);
// 结果: {"dataType":"RegExp","source":"pattern","flags":"gi"}// 反序列化回 RegExp
function parseRegExp(jsonString) {const obj = JSON.parse(jsonString);if (obj.dataType === 'RegExp') {return new RegExp(obj.source, obj.flags);}throw new Error('不是有效的 RegExp JSON');
}
通用解决方案:可以创建一个通用的序列化工具函数,处理所有这些特殊类型:
function enhancedStringify(obj) {return JSON.stringify(obj, (key, value) => {// 处理 Mapif (value instanceof Map) {return {__type: 'Map',value: Array.from(value.entries())};}// 处理 Setif (value instanceof Set) {return {__type: 'Set',value: Array.from(value.values())};}// 处理 RegExpif (value instanceof RegExp) {return {__type: 'RegExp',source: value.source,flags: value.flags};}return value;});
}function enhancedParse(jsonString) {return JSON.parse(jsonString, (key, value) => {if (value && typeof value === 'object' && value.__type) {switch(value.__type) {case 'Map':return new Map(value.value);case 'Set':return new Set(value.value);case 'RegExp':return new RegExp(value.source, value.flags);default:return value;}}return value;});
}

这样,就可以正确地序列化和反序列化这些特殊对象类型了,避免数据丢失的问题。

7. replacer 参数应用

7.1 使用(匿名)函数作为 replacer

const user = {name: "李四",password: "secret123", // 敏感信息age: 25,loginTime: new Date()
};// 使用 replacer 函数过滤敏感信息并格式化日期
const secureStringify = JSON.stringify(user, (key, value) => {// 过滤掉密码字段if (key === "password") return undefined;// 格式化日期对象if (value instanceof Date) {return value.toLocaleDateString("zh-CN");}return value;
});
// 结果中不包含密码,且日期格式化为本地格式

7.2 使用数组作为 replacer

const completeData = {id: 1001,name: "产品A",price: 299,inventory: 150,description: "这是一个很好的产品",manufacturer: "某公司",createdAt: "2023-10-01"
};// 仅选择特定字段输出
const selectedFields = ["id", "name", "price"];
const simpleJson = JSON.stringify(completeData, selectedFields, 2);
// 结果只会包含 id、name 和 price 字段

8. 处理 toJSON 方法

// 自定义对象可以实现 toJSON 方法来控制其 JSON 表示
class Person {constructor(name, age) {this.name = name;this.age = age;this._secretId = "ID12345"; // 私有数据}// 自定义 JSON 转换toJSON() {return {name: this.name,age: this.age,// 不包含 _secretIdisAdult: this.age >= 18 // 添加计算属性};}
}const person = new Person("王五", 22);
JSON.stringify(person);
// 结果: {"name":"王五","age":22,"isAdult":true}

9. 易犯错的场景

9.1 循环引用问题

// 创建循环引用
const team = {name: "开发团队",members: []
};const member = {name: "开发者",team: team // 引用team对象
};team.members.push(member); // team引用member,形成循环try {// 会抛出错误JSON.stringify(team);
} catch (error) {console.error("序列化失败:", error.message);// 输出: 序列化失败: Converting circular structure to JSON
}// 解决方案:使用replacer函数处理循环引用
function handleCircular() {const seen = new WeakSet();return (key, value) => {// 检测对象类型的循环引用if (typeof value === 'object' && value !== null) {if (seen.has(value)) {return '[循环引用]'; // 或者返回null/undefined来移除此属性}seen.add(value);}return value;};
}// 使用处理函数
const safeJson = JSON.stringify(team, handleCircular());
// 现在可以安全序列化,循环引用部分会被替换

9.2 数据丢失问题

const data = {id: 1,name: "测试",createdAt: new Date(),       // 会转为字符串regex: /^test$/,             // 会变成 {}func: function() { return 1; }, // 会被完全忽略symbol: Symbol('sym'),       // 会被完全忽略infinity: Infinity,          // 会变成 nullnan: NaN,                    // 会变成 nullundefined: undefined         // 会被完全忽略
};const jsonString = JSON.stringify(data);
const parsed = JSON.parse(jsonString);console.log(parsed);
// 结果缺少了 func、symbol、undefined
// regex 变成了 {}
// infinity 和 nan 变成了 null
// createdAt 变成了字符串,不再是 Date 对象// 解决方案:在序列化前转换特殊类型,反序列化后还原
function prepareForJSON(obj) {return Object.entries(obj).reduce((result, [key, value]) => {// 处理函数 - 转为字符串表示if (typeof value === 'function') {result[key] = `__FUNCTION:${value.toString()}`;}// 处理日期 - 添加标记else if (value instanceof Date) {result[key] = `__DATE:${value.toISOString()}`;}// 处理正则表达式else if (value instanceof RegExp) {result[key] = `__REGEXP:${value.toString()}`;}// 其他情况直接保留else {result[key] = value;}return result;}, {});
}// 反序列化后恢复特殊类型
function restoreFromJSON(obj) {return Object.entries(obj).reduce((result, [key, value]) => {if (typeof value === 'string') {// 还原日期if (value.startsWith('__DATE:')) {result[key] = new Date(value.slice(7));}// 还原正则表达式else if (value.startsWith('__REGEXP:')) {const regexParts = /^__REGEXP:\/(.*)\/([gimuy]*)$/.exec(value);if (regexParts) {result[key] = new RegExp(regexParts[1], regexParts[2]);} else {result[key] = value;}}// 其他情况直接保留else {result[key] = value;}} else {result[key] = value;}return result;}, {});
}

9.3 精度与大数问题

const data = {// JavaScript 数字精度问题decimal: 0.1 + 0.2,  // 结果是 0.30000000000000004// 大整数溢出bigInt: 9007199254740992, // 超出安全整数范围// BigInt 类型无法直接序列化reallyBig: 9007199254740992n
};const jsonStr = JSON.stringify(data); 
// 会抛出错误: BigInt 值无法转换为 JSON// 解决方案:预处理大数和 BigInt
function handleBigNumbers(obj) {return JSON.stringify(obj, (key, value) => {// 处理 BigIntif (typeof value === 'bigint') {return value.toString() + 'n'; // 添加标记}// 处理大数,确保精度if (typeof value === 'number' && !Number.isSafeInteger(value)) {return value.toString(); // 转为字符串保存}return value;});
}// 使用处理函数
const safeJsonStr = handleBigNumbers({normalNum: 42,bigNum: 9007199254740992,bigInt: 9007199254740992n
});// 反序列化时恢复
function restoreBigNumbers(jsonStr) {return JSON.parse(jsonStr, (key, value) => {// 还原 BigIntif (typeof value === 'string' && value.endsWith('n')) {return BigInt(value.slice(0, -1));}return value;});
}

10. 高级应用场景

10.1 深拷贝实现

// 使用 JSON 方法实现简单的深拷贝
// 注意:此方法有局限性,不能处理函数、undefined、Symbol、循环引用等
function simpleDeepClone(obj) {// 先将对象转为 JSON 字符串const jsonString = JSON.stringify(obj);// 再将 JSON 字符串解析回对象,生成全新的对象结构return JSON.parse(jsonString);
}const original = { info: { name: "原始对象",data: [1, 2, 3] } 
};
const copy = simpleDeepClone(original);
copy.info.name = "副本";
console.log(original.info.name); // "原始对象" - 不受影响

10.2 缓存序列化

// 将复杂数据存储到 localStorage
function saveToCache(key, data) {try {// 转换为字符串并存储localStorage.setItem(key, JSON.stringify(data));return true;} catch (error) {// 可能因为数据过大或其他原因导致存储失败console.error("缓存存储失败:", error);return false;}
}// 从缓存中读取数据
function loadFromCache(key) {try {const stored = localStorage.getItem(key);if (stored) {// 解析回 JavaScript 对象return JSON.parse(stored);}return null;} catch (error) {console.error("缓存读取失败:", error);return null;}
}

10.3 状态管理与时间旅行

// Redux 等状态管理库使用序列化实现时间旅行调试
class SimpleStore {constructor(initialState = {}) {this.state = initialState;this.history = [];}// 更新状态dispatch(action) {// 保存当前状态快照到历史记录this.history.push(JSON.stringify(this.state));// 更新状态(简化示例)this.state = {...this.state,...action.payload};return this.state;}// 时间旅行 - 回到之前的状态timeTravel(stepIndex) {if (stepIndex >= 0 && stepIndex < this.history.length) {// 从历史记录恢复状态this.state = JSON.parse(this.history[stepIndex]);return this.state;}return null;}
}

11. 性能考量

11.1 大数据处理

// 处理大型数据集时的分块处理方法
function processLargeData(data, chunkSize = 1000) {// 分割大型数组为多个小块const chunks = [];for (let i = 0; i < data.length; i += chunkSize) {chunks.push(data.slice(i, i + chunkSize));}// 逐块处理const results = [];for (const chunk of chunks) {// 每个块单独序列化,避免一次处理过多数据const jsonChunk = JSON.stringify(chunk);// 这里可以进行存储或传输results.push(jsonChunk);}return results;
}

12. 常见陷阱与解决方案

12.1 处理数值精度问题

// JavaScript 中的大数值可能超出 JSON 数值范围
const bigNumber = 9007199254740992n; // BigInt
// JSON.stringify(bigNumber); // 会抛出错误// 解决方案:转换为字符串处理
const data = {id: "9007199254740992", // 作为字符串存储normalNumber: 42
};JSON.stringify(data); // 正常工作

12.2 处理特殊字符

// Unicode 字符和转义字符的处理
const text = "包含特殊字符: \n 换行符 \t 制表符 \u2022 项目符号";// JSON.stringify 会自动处理这些特殊字符
const encoded = JSON.stringify(text);
// 结果: "包含特殊字符: \n 换行符 \t 制表符 • 项目符号"// 解码时会正确还原
JSON.parse(encoded); // 原始文本

13. 序列化的安全问题

// 不安全的 JSON 解析
function unsafeParseFromServer(jsonString) {// 永远不要这样做!return eval('(' + jsonString + ')');
}// 安全的 JSON 解析
function safeParseFromServer(jsonString) {try {// 使用标准 JSON.parse 方法return JSON.parse(jsonString);} catch (error) {console.error('无效的 JSON 字符串:', error);return null;}
}// 处理不可信数据
function validateAndParse(jsonString) {try {// 1. 使用标准方法解析const data = JSON.parse(jsonString);// 2. 验证数据结构和类型if (!data || typeof data !== 'object') {throw new Error('数据格式无效');}// 3. 验证必要字段if (!data.id || typeof data.id !== 'number') {throw new Error('缺少必要字段或类型错误');}return data;} catch (error) {console.error('数据验证失败:', error);return null;}
}

14. 与其他序列化方法比较

14.1 JSON.stringify vs 手动序列化

// 手动构建 JSON 字符串 - 容易出错
function manualStringify(obj) {// 这是一个简化示例,实际情况更复杂let result = '{';const entries = Object.entries(obj);for (let i = 0; i < entries.length; i++) {const [key, value] = entries[i];result += `"${key}":`;if (typeof value === 'string') {result += `"${value}"`;} else if (typeof value === 'number' || typeof value === 'boolean') {result += value;} else if (value === null) {result += 'null';}// 这里省略了数组、对象等复杂类型的处理if (i < entries.length - 1) {result += ',';}}result += '}';return result;
}// JSON.stringify 更可靠、更安全、更全面

14.2 JSON vs 其他序列化格式

// JSON 序列化 - 标准且跨平台
function serializeJSON(data) {return JSON.stringify(data);// 优点:标准格式,所有语言支持,人类可读// 缺点:不支持循环引用,不能保留函数和特殊数据类型
}// MessagePack 序列化示例 (需要引入库)
function serializeMsgPack(data) {// 使用 MessagePack 库 (msgpack-lite 等)return msgpack.encode(data);// 优点:二进制紧凑,比JSON小,支持更多数据类型// 缺点:需要额外库,人类不可读
}// Protocol Buffers 示例 (需要引入库和定义 schema)
function serializeProtobuf(data) {// 使用 Protocol Buffers 库和预定义 schemareturn protobuf.encode(data);// 优点:高效紧凑,强类型,适合 RPC// 缺点:需要预定义 schema,设置复杂
}

15. 最佳实践

15.1 序列化前数据清理

// 序列化前清理数据
function sanitizeForJSON(data) {// 深度复制对象并清理function sanitize(obj, seen = new WeakSet()) {// 处理基本类型if (obj === null || typeof obj !== 'object') {return obj;}// 处理循环引用if (seen.has(obj)) {return "[循环引用]";}seen.add(obj);// 数组处理if (Array.isArray(obj)) {return obj.map(item => sanitize(item, seen));}// 对象处理const result = {};for (const [key, value] of Object.entries(obj)) {// 跳过不需要的属性if (key.startsWith('_')) continue; // 跳过私有属性if (typeof value === 'function') continue; // 跳过函数// 处理特殊类型if (value instanceof Date) {result[key] = value.toISOString();} else {result[key] = sanitize(value, seen);}}return result;}return sanitize(data);
}// 使用清理过的数据序列化
const cleanData = sanitizeForJSON(complexData);
const jsonString = JSON.stringify(cleanData);

15.2 错误处理最佳实践

// 健壮的序列化函数
function robustStringify(data) {try {return JSON.stringify(data, (key, value) => {// 处理 BigIntif (typeof value === 'bigint') {return value.toString() + 'n';}// 处理 Error 对象if (value instanceof Error) {return {_error: true,name: value.name,message: value.message,stack: value.stack};}// 处理特殊对象类型if (value instanceof Map || value instanceof Set || value instanceof WeakMap || value instanceof WeakSet) {return {_type: value.constructor.name,value: value instanceof Map ? [...value.entries()] :value instanceof Set ? [...value.values()] : 'Cannot serialize'};}return value;});} catch (error) {console.error('序列化失败:', error);// 降级处理 - 尝试去除问题属性if (error.message.includes('circular structure')) {try {// 使用处理循环引用的方式重试const seen = new WeakSet();return JSON.stringify(data, (key, value) => {if (typeof value === 'object' && value !== null) {if (seen.has(value)) return '[循环引用]';seen.add(value);}return value;});} catch (e) {// 如果还失败,返回基本信息return JSON.stringify({error: '序列化失败',reason: error.message});}}// 其他错误情况返回错误信息return JSON.stringify({error: '序列化失败',reason: error.message});}
}

16. 总结

JSON.stringify 是处理数据序列化的强大工具,掌握其各种参数和用法能够有效解决数据处理中的各种问题。序列化是实现数据传输、存储和复制的基础技术,理解其原理和限制对于开发高效可靠的应用至关重要。

通过合理使用 replacer 和 space 参数,以及理解不同数据类型的处理规则,可以更精确地控制 JSON 输出。在实际应用中,需要注意特殊数据类型、循环引用、数值精度等潜在问题,采取适当的方法进行处理,避免数据丢失或安全隐患。

随着Web应用复杂度的提高,掌握高级序列化技巧和最佳实践变得尤为重要,这不仅能提高应用性能,还能增强数据处理的可靠性和安全性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/915122.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/915122.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQLite / LiteDB 单文件数据库为何“清空表后仍占几 GB”?——原理解析与空间回收实战

关键词&#xff1a; SQLite、LiteDB、VACUUM、WAL、auto_vacuum、文件瘦身、数据库维护在嵌入式或桌面、IoT 网关等场景&#xff0c;很多同学都会选择单文件数据库&#xff08;SQLite、LiteDB、SQL CE…&#xff09;。 最近群里一位朋友反馈&#xff1a;“我的 test.db 已经把业…

如何加固Web服务器的安全?

Web服务器是用户和公司联系的桥梁&#xff0c;Web服务器为用户交付网页内容和提供Web应用。正因为Web服务器是面向互联网的&#xff0c;所以成为了网络的攻击经常利用的一个入口。Web 服务器是企业数字化转型的 “前沿阵地”&#xff0c;其安全性不仅关乎技术层面的稳定运行&am…

MyBatis:配置文件完成增删改查_添加

1 实现添加操作 编写接口方法:Mapper接口编写sql语句&#xff1a;sql映射文件<insert id"add">insert into tb_brand(brand_name,company_name,ordered,description,status)values(#{brandName},#{companyName},#{ordered},#{description},#{status});</ins…

SGLang 推理框架核心组件解析:请求、内存与缓存的协同工作

SGLang 推理框架核心组件解析&#xff1a;请求、内存与缓存的协同工作 在当今大语言模型&#xff08;LLM&#xff09;服务的浪潮中&#xff0c;高效的推理框架是决定服务质量与成本的关键。SGLang 作为一个高性能的 LLM 推理和部署库&#xff0c;其内部精巧的设计确保了高吞吐量…

React学习笔记——Day2打卡

1、React表单控制 1.1 受控绑定 概念&#xff1a;使用React组件的状态&#xff08;useState&#xff09;控制表单的状态 完整示例&#xff1a; function App(){/* 1. 准备一个React状态值 */ const [value, setValue] useState()return (/* 2. 通过value属性绑定状态&#x…

用例测试方法5,6:状态迁移图和因果图

状态迁移图通过描绘系统的状态及引起状态转换的事件&#xff0c;来表示系统的行为例如&#xff1a;订机票l向航空公司打电话预定机票—>此时机票信息处于“完成”状态顾客支付了机票费用后—>机票信息就变为“已支付”状态旅行当天到达机场后&#xff0c;拿到机票后—>…

linux 脚本解释

if [ $? -ne 0 ]; thenecho "错误: 无法关闭现有 Tomcat 实例&#xff0c;终止启动流程!" >&2exit 1fi$? 是shell中的特殊变量&#xff0c;表示上一个命令的退出状态码-ne 0 表示"不等于0"(在Unix/Linux中&#xff0c;0通常表示成功&#xff0c;非…

Glary Utilities(系统优化工具) v6.20.0.24 专业便携版

GlaryUtilities 允许你清理系统垃圾文件&#xff0c;无效的注册表&#xff0c;上网记录&#xff0c;删除插件&#xff0c;查找重复文件&#xff0c;优化内存&#xff0c;修理或删除快捷方式&#xff0c;管理windows启动程序&#xff0c;卸载软件&#xff0c;安全删除文件&#…

VScode链接服务器一直卡在下载vscode服务器/scp上传服务器,无法连接成功

终极方案&#xff08;强力推荐&#xff0c;亲测有效&#xff0c;链接只需5秒钟&#xff09;&#xff1a;本地下载复制到mkdir -p ~/.vscode-server/bin/<commit_hash>里面 <commit_hash>可以从帮助->关于里面找到&#xff0c;如下所示 版本: 1.96.2 提交: fa…

基于Spring Boot的农村农产品销售系统设计与实现

随着现代农业的快速发展,传统农产品的销售模式逐渐暴露出信息闭塞、流通效率低和中间环节多等问题。为了打破这些瓶颈,我基于Spring Boot框架开发了一套农产品销售系统,旨在构建一座连接农民与消费者之间的数字桥梁,让优质农产品更高效地直达用户餐桌。 一、项目背景与目标…

Mysql默认存储引擎InnoDB和底层数据结构

在黑马点评项目实战中&#xff1a;谈到了为什么不推荐使用mysql的字段自增作为订单id传递给客户端&#xff0c;让我想到了Mysql的​​存储引擎​​和​​底层数据结构​​究竟是什么&#xff1f;它是如何实现自增的&#xff1f;本文主要是深度解析 MySQL 默认存储引擎 InnoDB 与…

原点安全签约金网络数科,共建一体化数据安全防护体系

金网络正式携手原点安全&#xff0c;基于原点安全一体化数据安全平台&#xff08;uDSP&#xff09;&#xff0c;启动企业数据安全平台建设项目&#xff0c;围绕数据资产盘点、敏感数据识别与分类分级、数据访问权限管控、数据动态脱敏、数据安全审计与风险监测等关键能力建设&a…

mix-blend-mode的了解使用

mix-blend-mode 是 CSS 的一个属性&#xff0c;用于控制元素的内容&#xff08;如文本、图像、背景等&#xff09;如何与其 父元素 或 背景 进行混合。它类似于图形设计软件&#xff08;如 Photoshop&#xff09;中的图层混合模式&#xff0c;可以实现各种视觉效果&#xff1b;…

vue自定义指令bug

问题描述&#xff1a;页面加载时&#xff0c;报已下错误。同时&#xff0c;页面数据不显示环境介绍&#xff1a;已经添加了vue自定义指令permission&#xff0c;实现如下&#xff0c;用以控制元素显示权限app.directive(permission, (el, binding) > {if (!store.hasPermiss…

Vue3 + WebSocket

Vue3与WebSocket结合能够很好地满足实时通讯的需求。通过合理设计和管理WebSocket连接的生命周期&#xff0c;以及实现必要的重连逻辑和心跳检测机制&#xff0c;可以构建出响应迅速且稳定的实时应用。WebSocketWebSocket允许服务端主动向客户端发送数据&#xff0c;无需客户端…

IPSec和HTTPS对比(一)

IPSec&#xff08;Internet Protocol Security&#xff09;是网络层&#xff08;OSI第3层&#xff09;的加密协议&#xff0c;其核心机制和与HTTPS的区别如下&#xff1a;&#x1f512; ​一、IPSec的核心机制解析​​1. 安全封装结构​┌──────────┬───────…

关于 c、c#、c++ 三者区别

1. 起源与定位语言起源时间开发者定位/特点C1972年Dennis Ritchie面向过程的编程语言&#xff0c;强调底层控制与高效性能C1983年Bjarne Stroustrup在 C 的基础上加入 面向对象编程&#xff08;OOP&#xff09;C#2000年微软&#xff08;Microsoft&#xff09;类似 Java&#xf…

项目总体框架(servlet+axios+Mybatis)

项目总体框架 先暂时这样子&#xff08;后续发现错误的话就改&#xff09; com.hope-tieba/ ← 项目根 ├─ .idea/ ← IDEA 工程配置 ├─ src/ │ ├─ main/ │ │ ├─ java/ │ │ │ └─ com/hope/ │ │ …

RestTemplate 实现后端 HTTP 调用详解

1. 方法签名解析方法名和返回类型说明了这个方法的业务意图和数据结构。Override 表示实现接口方法&#xff0c;利于规范开发和自动检查。Override public List<RobotInfo> listRobots() {这里 RobotInfo 是假设的业务数据结构&#xff0c;实际项目中按你的类名即可。2. …

Python单例模式详解:从原理到实战的完整指南

引言 单例模式是软件设计中最常用的模式之一&#xff0c;它确保一个类只有一个实例&#xff0c;并提供全局访问点。在Python中&#xff0c;实现单例模式有多种优雅的方式&#xff0c;本文将详细讲解6种主流实现方法&#xff0c;包含完整代码示例和注释。 一、模块级单例&#x…