mysql8 C++源码中创建表函数,表字段最大数量限制,表行最大存储限制
在 MySQL 8 的 C++ 源码中,表的最大字段数量限制体现在 MAX_FIELDS
宏定义中。这个宏定义了表中可以拥有的最大字段数量。
代码中的体现
在 mysql_prepare_create_table
函数中,有以下代码段检查表的字段数量是否超过最大限制:
cpp
if (alter_info->create_list.elements > MAX_FIELDS) {my_error(ER_TOO_MANY_FIELDS, MYF(0));return true;
}
这里,alter_info->create_list.elements
表示表中字段的数量,MAX_FIELDS
是最大允许的字段数量。
MAX_FIELDS
的定义
MAX_FIELDS
的定义通常在 MySQL 的头文件中,例如 include/mysql_com.h
或其他相关头文件。在 MySQL 8 中,MAX_FIELDS
的值为 4096。
源码位置
在 MySQL 8 的源码中,mysql_prepare_create_table
函数位于 sql/sql_table.cc
文件中。这个文件包含了与表创建和修改相关的许多函数。
总结
-
最大字段数量:MySQL 8 中表的最大字段数量为 4096。
-
代码中的体现:在
mysql_prepare_create_table
函数中通过MAX_FIELDS
宏检查表的字段数量。
MySQL 中,每行记录的最大长度限制为 65,535 字节。这个限制是由 MySQL 的内部实现决定的,而不是由某个特定的源码文件或函数直接定义的。这个限制适用于所有存储引擎,包括 InnoDB 和 MyISAM。
限制的体现
在 MySQL 8 的源码中,这个限制通常在多个地方体现,特别是在处理表的创建和数据插入时。以下是一些关键点:
-
表创建时的验证: 在
mysql_prepare_create_table
函数中,虽然没有直接的代码检查每行记录的长度,但这个限制会在表创建时通过存储引擎的接口进行验证。 -
存储引擎的限制: 每个存储引擎都有自己的限制。例如,InnoDB 存储引擎在处理表创建时会检查每行记录的长度是否超过最大限制。
-
数据插入时的验证: 在插入数据时,MySQL 会检查每行记录的长度是否超过 65,535 字节。如果超过,会报错。
示例代码
以下是一个简化的示例,展示如何在插入数据时检查每行记录的长度:
cpp
if (reclength > file->max_record_length()) {my_error(ER_TOO_BIG_ROWSIZE, MYF(0),static_cast<long>(file->max_record_length()));return true;
}
在这个代码片段中,reclength
是计算的每行记录的长度,file->max_record_length()
是存储引擎允许的最大记录长度。如果 reclength
超过 file->max_record_length()
,则报错。
具体实现
在 MySQL 源码中,file->max_record_length()
通常由存储引擎的实现提供。例如,在 InnoDB 存储引擎中,这个值被定义为 65,535 字节。
C++源码
// Prepares the table and key structures for table creation.
bool mysql_prepare_create_table(THD *thd, const char *error_schema_name, const char *error_table_name,HA_CREATE_INFO *create_info, Alter_info *alter_info, handler *file,bool is_partitioned, KEY **key_info_buffer, uint *key_count,FOREIGN_KEY **fk_key_info_buffer, uint *fk_key_count,FOREIGN_KEY *existing_fks, uint existing_fks_count,const dd::Table *existing_fks_table, uint fk_max_generated_name_number,int select_field_count, bool find_parent_keys) {DBUG_TRACE;/*Validation of table properties.*/LEX_STRING *connect_string = &create_info->connect_string;if (connect_string->length != 0 &&connect_string->length > CONNECT_STRING_MAXLEN &&(system_charset_info->cset->charpos(system_charset_info, connect_string->str,(connect_string->str + connect_string->length),CONNECT_STRING_MAXLEN) < connect_string->length)) {my_error(ER_WRONG_STRING_LENGTH, MYF(0), connect_string->str, "CONNECTION",CONNECT_STRING_MAXLEN);return true;}LEX_STRING *compress = &create_info->compress;if (compress->length != 0 && compress->length > TABLE_COMMENT_MAXLEN &&system_charset_info->cset->charpos(system_charset_info, compress->str, compress->str + compress->length,TABLE_COMMENT_MAXLEN) < compress->length) {my_error(ER_WRONG_STRING_LENGTH, MYF(0), compress->str, "COMPRESSION",TABLE_COMMENT_MAXLEN);return true;}LEX_STRING *encrypt_type = &create_info->encrypt_type;if (encrypt_type->length != 0 &&encrypt_type->length > TABLE_COMMENT_MAXLEN &&system_charset_info->cset->charpos(system_charset_info, encrypt_type->str,encrypt_type->str + encrypt_type->length,TABLE_COMMENT_MAXLEN) < encrypt_type->length) {my_error(ER_WRONG_STRING_LENGTH, MYF(0), encrypt_type->str, "ENCRYPTION",TABLE_COMMENT_MAXLEN);return true;}// Validate table comment stringstd::string invalid_sub_str;if (is_invalid_string({create_info->comment.str, create_info->comment.length},system_charset_info, invalid_sub_str)) {my_error(ER_COMMENT_CONTAINS_INVALID_STRING, MYF(0), "table",(std::string(error_schema_name) + "." + std::string(error_table_name)).c_str(),system_charset_info->csname, invalid_sub_str.c_str());return true;}if (validate_comment_length(thd, create_info->comment.str, &create_info->comment.length,TABLE_COMMENT_MAXLEN, ER_TOO_LONG_TABLE_COMMENT, error_table_name)) {return true;}if (alter_info->create_list.elements > MAX_FIELDS) {my_error(ER_TOO_MANY_FIELDS, MYF(0));return true;}/*Checks which previously were done during .FRM creation.TODO: Check if the old .FRM limitations still make sensewith the new DD.*//* Fix this when we have new .frm files; Current limit is 4G rows (QQ) */constexpr ulonglong u32max = UINT_MAX32;if (create_info->max_rows > UINT_MAX32) {// Values larger than uint32_max are capped to uint32_max.// Emit a warning about this.push_warning_printf(thd, Sql_condition::SL_WARNING, ER_VALUE_OUT_OF_RANGE,ER_THD(thd, ER_VALUE_OUT_OF_RANGE), "max_rows",create_info->max_rows, 0ULL, u32max, u32max);create_info->max_rows = UINT_MAX32;}if (create_info->min_rows > UINT_MAX32) {// Values larger than uint32_max are capped to uint32_max.// Emit a warning about this.push_warning_printf(thd, Sql_condition::SL_WARNING, ER_VALUE_OUT_OF_RANGE,ER_THD(thd, ER_VALUE_OUT_OF_RANGE), "min_rows",create_info->min_rows, 0ULL, u32max, u32max);create_info->min_rows = UINT_MAX32;}if (create_info->row_type == ROW_TYPE_DYNAMIC)create_info->table_options |= HA_OPTION_PACK_RECORD;/*Prepare fields, which must be done before callingadd_functional_index_to_create_list(). The reason is thatprepare_create_field() sets several properties of all Create_fields, such ascharacter set. We need the character set in order to get the correctdisplay width for each Create_field, which is in turn needed to resolve thecorrect data type/length for each hidden generated column added byadd_functional_index_to_create_list().*/int select_field_pos = alter_info->create_list.elements - select_field_count;create_info->null_bits = 0;int field_no = 0;Create_field *sql_field;List_iterator<Create_field> it(alter_info->create_list);for (; (sql_field = it++); field_no++) {if (prepare_create_field(thd, error_schema_name, error_table_name,create_info, &alter_info->create_list,&select_field_pos, file, sql_field, field_no))return true;}// Go through all functional key parts. For each functional key part, resolve// the expression and add a hidden generated column to the create list.for (Key_spec *key : alter_info->key_list) {if (key->type == KEYTYPE_FOREIGN) continue;for (size_t j = 0; j < key->columns.size(); ++j) {Key_part_spec *key_part_spec = key->columns[j];// In the case of procedures, the Key_part_spec may both have an// expression and a field name assigned to it. But the hidden generated// will not exist in the create list, so we will have to add it.if (!key_part_spec->has_expression() ||(key_part_spec->get_field_name() != nullptr &&column_exists_in_create_list(key_part_spec->get_field_name(),alter_info->create_list))) {continue;}Create_field *new_create_field = add_functional_index_to_create_list(thd, key, alter_info, key_part_spec, j, create_info);if (new_create_field == nullptr) {return true;}// Call prepare_create_field on the Create_field that was added by// add_functional_index_to_create_list().assert(is_field_for_functional_index(new_create_field));if (prepare_create_field(thd, error_schema_name, error_table_name,create_info, &alter_info->create_list,&select_field_pos, file, new_create_field,++field_no)) {return true;}}}// Now that we have all the Create_fields available, calculate the offsets// for each column.calculate_field_offsets(&alter_info->create_list);/*Auto increment and blob checks.*/int auto_increment = 0;int blob_columns = 0;it.rewind();while ((sql_field = it++)) {if (sql_field->auto_flags & Field::NEXT_NUMBER) auto_increment++;switch (sql_field->sql_type) {case MYSQL_TYPE_GEOMETRY:case MYSQL_TYPE_BLOB:case MYSQL_TYPE_MEDIUM_BLOB:case MYSQL_TYPE_TINY_BLOB:case MYSQL_TYPE_LONG_BLOB:case MYSQL_TYPE_JSON:blob_columns++;break;default:if (sql_field->is_array) blob_columns++;break;}}if (auto_increment > 1) {my_error(ER_WRONG_AUTO_KEY, MYF(0));return true;}if (auto_increment && (file->ha_table_flags() & HA_NO_AUTO_INCREMENT)) {my_error(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT, MYF(0));return true;}if (blob_columns && (file->ha_table_flags() & HA_NO_BLOBS)) {my_error(ER_TABLE_CANT_HANDLE_BLOB, MYF(0));return true;}/*CREATE TABLE[with auto_increment column] SELECT is unsafe as the rowsinserted in the created table depends on the order of the rows fetchedfrom the select tables. This order may differ on master and slave. Wetherefore mark it as unsafe.*/if (select_field_count > 0 && auto_increment)thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_SELECT_AUTOINC);/*Count keys and key segments.Also mark redundant keys to be ignored.*/uint key_parts;Mem_root_array<bool> redundant_keys(thd->mem_root,alter_info->key_list.size(), false);if (count_keys(alter_info->key_list, key_count, &key_parts, fk_key_count,&redundant_keys, file->ha_table_flags()))return true;if (*key_count > file->max_keys()) {my_error(ER_TOO_MANY_KEYS, MYF(0), file->max_keys());return true;}/*Make KEY objects for the keys in the new table.*/KEY *key_info;(*key_info_buffer) = key_info = (KEY *)sql_calloc(sizeof(KEY) * (*key_count));KEY_PART_INFO *key_part_info =(KEY_PART_INFO *)sql_calloc(sizeof(KEY_PART_INFO) * key_parts);if (!*key_info_buffer || !key_part_info) return true; // Out of memoryMem_root_array<const KEY *> keys_to_check(thd->mem_root);if (keys_to_check.reserve(*key_count)) return true; // Out of memoryuint key_number = 0;bool primary_key = false;// First prepare non-foreign keys so that they are ready when// we prepare foreign keys.for (size_t i = 0; i < alter_info->key_list.size(); i++) {if (redundant_keys[i]) continue; // Skip redundant keysconst Key_spec *key = alter_info->key_list[i];if (key->type == KEYTYPE_PRIMARY) {if (primary_key) {my_error(ER_MULTIPLE_PRI_KEY, MYF(0));return true;}primary_key = true;}if (key->type != KEYTYPE_FOREIGN) {if (prepare_key(thd, error_schema_name, error_table_name, create_info,&alter_info->create_list, key, key_info_buffer, key_info,&key_part_info, keys_to_check, key_number, file,&auto_increment))return true;key_info++;key_number++;}}// If the table is created without PK, we must check if this has// been disabled and return error. Limit the effect of sql_require_primary_key// to only those SEs that can participate in replication.if (!primary_key && !thd->is_dd_system_thread() &&!thd->is_initialize_system_thread() &&(file->ha_table_flags() &(HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)) != 0 &&thd->variables.sql_require_primary_key) {my_error(ER_TABLE_WITHOUT_PK, MYF(0));return true;}/*At this point all KEY objects are for indexes are fully constructed.So we can check for duplicate indexes for keys for which it was requested.*/const KEY **dup_check_key;for (dup_check_key = keys_to_check.begin();dup_check_key != keys_to_check.end(); dup_check_key++) {if (check_duplicate_key(thd, error_schema_name, error_table_name,*dup_check_key, *key_info_buffer, *key_count,alter_info))return true;}if (!primary_key && check_promoted_index(file, *key_info_buffer, *key_count))return true;/*Any auto increment columns not found during prepare_key?*/if (auto_increment > 0) {my_error(ER_WRONG_AUTO_KEY, MYF(0));return true;}/* Sort keys in optimized order */std::sort(*key_info_buffer, *key_info_buffer + *key_count, sort_keys());/*Normal keys are done, now prepare foreign keys.We do this after sorting normal keys to get predictable behaviorwhen searching for parent keys for self-referencing foreign keys.*/bool se_supports_fks =(create_info->db_type->flags & HTON_SUPPORTS_FOREIGN_KEYS);assert(se_supports_fks || existing_fks_count == 0);(*fk_key_count) += existing_fks_count;FOREIGN_KEY *fk_key_info;(*fk_key_info_buffer) = fk_key_info =(FOREIGN_KEY *)sql_calloc(sizeof(FOREIGN_KEY) * (*fk_key_count));if (!fk_key_info) return true; // Out of memory// Copy pre-existing foreign keys.if (existing_fks_count > 0)memcpy(*fk_key_info_buffer, existing_fks,existing_fks_count * sizeof(FOREIGN_KEY));uint fk_number = existing_fks_count;fk_key_info += existing_fks_count;/*Check if we are trying to add partitioning to the table with existingforeign keys and table's storage engine doesn't support foreign keysover partitioned tables.*/if (is_partitioned && existing_fks_count > 0 &&(!create_info->db_type->partition_flags ||create_info->db_type->partition_flags() & HA_CANNOT_PARTITION_FK)) {my_error(ER_FOREIGN_KEY_ON_PARTITIONED, MYF(0));return true;}/*Check that definitions of existing foreign keys are not broken by thisALTER TABLE. Update FOREIGN_KEY::unique_constraint_name if necessary.*/for (FOREIGN_KEY *fk = *fk_key_info_buffer;fk < (*fk_key_info_buffer) + existing_fks_count; fk++) {if (prepare_preexisting_foreign_key(thd, create_info, alter_info, error_schema_name, error_table_name,*key_info_buffer, *key_count, existing_fks_table, fk))return true;}// Prepare new foreign keys.for (size_t i = 0; i < alter_info->key_list.size(); i++) {if (redundant_keys[i]) continue; // Skip redundant keysKey_spec *key = alter_info->key_list[i];if (key->type == KEYTYPE_FOREIGN) {if (prepare_foreign_key(thd, create_info, alter_info, error_schema_name,error_table_name, is_partitioned,*key_info_buffer, *key_count, *fk_key_info_buffer,fk_number, se_supports_fks, find_parent_keys,down_cast<Foreign_key_spec *>(key),&fk_max_generated_name_number, fk_key_info))return true;if (se_supports_fks) {fk_key_info++;fk_number++;}}}/*Check if STRICT SQL mode is active and server is not started with--explicit-defaults-for-timestamp. Below check was added to prevent implicitdefault 0 value of timestamp. When explicit-defaults-for-timestamp serveroption is removed, whole set of check can be removed.Note that this check must be after KEYs have been created as thiscan cause the NOT_NULL_FLAG to be set.*/if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&!thd->variables.explicit_defaults_for_timestamp) {it.rewind();while ((sql_field = it++)) {if (!sql_field->constant_default && !sql_field->gcol_info &&is_timestamp_type(sql_field->sql_type) &&(sql_field->flags & NOT_NULL_FLAG) &&!(sql_field->auto_flags & Field::DEFAULT_NOW)) {/*An error should be reported if:- there is no explicit DEFAULT clause (default column value);- this is a TIMESTAMP column;- the column is not NULL;- this is not the DEFAULT CURRENT_TIMESTAMP column.And from checks before while loop,- STRICT SQL mode is active;- server is not started with --explicit-defaults-for-timestampIn other words, an error should be reported if- STRICT SQL mode is active;- the column definition is equivalent to'column_name TIMESTAMP DEFAULT 0'.*/my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);return true;}}}/* If fixed row records, we need one bit to check for deleted rows */if (!(create_info->table_options & HA_OPTION_PACK_RECORD))create_info->null_bits++;const ulong data_offset = (create_info->null_bits + 7) / 8;size_t reclength = data_offset;it.rewind();while ((sql_field = it++)) {const size_t length = sql_field->pack_length();if (sql_field->offset + data_offset + length > reclength)reclength = sql_field->offset + data_offset + length;}if (reclength > file->max_record_length()) {my_error(ER_TOO_BIG_ROWSIZE, MYF(0),static_cast<long>(file->max_record_length()));return true;}return false;
}
相关文章:
mysql8 C++源码中创建表函数,表字段最大数量限制,表行最大存储限制
在 MySQL 8 的 C 源码中,表的最大字段数量限制体现在 MAX_FIELDS 宏定义中。这个宏定义了表中可以拥有的最大字段数量。 代码中的体现 在 mysql_prepare_create_table 函数中,有以下代码段检查表的字段数量是否超过最大限制: cpp if (alt…...

胜任力冰山模型:深入探索职业能力的多维结构
目录 1、序言 2、什么是胜任力? 3、任职资格和胜任力的区别 4、胜任力冰山模型:职场能力的多维展现 4.1、冰山水面上的部分 4.2、冰山水面下的部分 4.3、深层的个人特质与价值观 5、如何平衡任职资格与胜任能力 6、结语 1、序言 在快速发展的I…...

什么是三层交换技术?与二层有什么区别?
什么是三层交换技术?让你的网络飞起来! 一. 什么是三层交换技术?二. 工作原理三. 优点四. 应用场景五. 总结 前言 点个免费的赞和关注,有错误的地方请指出,看个人主页有惊喜。 作者:神的孩子都在歌唱 大家好…...

Linux+Docer 容器化部署之 Shell 语法入门篇 【Shell 替代】
🎀🎀Shell语法入门篇 系列篇 🎀🎀 LinuxDocer 容器化部署之 Shell 语法入门篇 【准备阶段】LinuxDocer 容器化部署之 Shell 语法入门篇 【Shell变量】LinuxDocer 容器化部署之 Shell 语法入门篇 【Shell数组与函数】LinuxDocer 容…...
DeepSeek LLM(初代)阅读报告
概况 这个是deepseek发布的第一版模型对应的技术报告,模型发布于23年11月,本报告发布于24年1月。 模型有7B和67B两个版本。 虽然本报告中还没有用上后面V2/V3和R1中的关键技术例如MLA、MTP、GRPO,但是报告中已经指明了MoE、强化学习等未来…...
JAVA异步的TCP 通讯-服务端
一、服务端代码示例 import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousServerSocketChannel; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.Completion…...

高效协同,Tita 助力项目管理场景革新
在当今快节奏、高度竞争的商业环境中,企业面临着前所未有的挑战:如何在有限资源下迅速响应市场变化,确保多个项目的高效执行并达成战略目标?答案就在于优化项目集程管理。而在这个过程中,Tita项目管理产品以其独特的优…...
【AIGC魔童】DeepSeek v3提示词Prompt书写技巧
【AIGC魔童】DeepSeek v3提示词Prompt书写技巧 (1)基础通用公式(适用80%场景)(2)问题解决公式(决策支持)(3)创意生成公式(4)学习提升公…...
Vue | 透传 Attributes(非 prop 的 attribute )
文章目录 引言I Attribute 继承II 禁用 attribute 继承禁用 attribute 继承的常见场景通过将 inheritAttrs 选项设置为 false从 3.3 开始可在 `<script setup>` 中使用defineOptions例子引言 “透传 attribute”指的是传递给一个组件,却没有被该组件声明为 props 或 emi…...

启明星辰发布MAF大模型应用防火墙产品,提升DeepSeek类企业用户安全
2月7日,启明星辰面向DeepSeek等企业级大模型业务服务者提供的安全防护产品——天清MAF(Model Application Firewall)大模型应用防火墙产品正式发布。 一个新赛道将被开启…… DeepSeek的低成本引爆赛道规模 随着DeepSeek成为当前最热的现象级…...

Vuex 解析:从 Vue 2 到 Vue 3 的演变与最佳实践
Vuex 是 Vue.js 中的状态管理模式,广泛应用于 Vue 2 和 Vue 3 中,其内部实现存在一些差异。 1. 什么是 Vuex ? Vuex 是 Vue.js 官方提供的状态管理库,用于集中管理应用的所有组件的状态。主要是通过一种集中化的方式来管理共享状…...

一文解释nn、nn.Module与nn.functional的用法与区别
🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀零基础入门PyTorch框架_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 …...

日志统计(acWing,蓝桥杯)
题目: 1238. 日志统计 题目 提交记录 讨论 题解 视频讲解 小明维护着一个程序员论坛。现在他收集了一份”点赞”日志,日志共有 NN 行。 其中每一行的格式是: ts id 表示在 tsts 时刻编号 idid 的帖子收到一个”赞”。 现在小明想…...

3个DeepSeek隐藏玩法
大家最近是不是都被DeepSeek-R1刷屏了 这款号称“中国版O1”的模型,不仅在数学和编程领域表现出色,中文写作能力也很强。 最重要的是,它在理解提示词方面有了很大突破,只要你能打字,它就能理解你的意思。 不过&…...

部署LLM模型到云端
文章目录 1 ECS 云服务器部署2 函数计算FC3 人工智能平台PAI-EAS4 大模型服务平台百炼压测实验结果显示,由于本地设备算力有限,本地部署的模型服务无法满足低延迟和高并发的需求。针对这类线上业务,可以考虑云端部署。 下面先来看看本地部署和云端部署的特点对比。 由上可…...
Python连接不同数据库的总结
Python连接不同数据库的总结 在数据驱动的现代应用开发中,Python凭借其丰富的库和强大的生态系统,成为连接各种数据库的理想编程语言。本文将深入探讨Python连接不同类型数据库的方法、常用库以及关键注意事项。 一、连接MySQL数据库 MySQL是广泛使用…...

web直播弹幕抓取分析 signature
声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 前言 最近遇到太多难点了卡了很久&am…...

Linux ftrace 内核跟踪入门
文章目录 ftrace介绍开启ftraceftrace使用ftrace跟踪指定内核函数ftrace跟踪指定pid ftrace原理ftrace与stracetrace-cmd 工具KernelShark参考 ftrace介绍 Ftrace is an internal tracer designed to help out developers and designers of systems to find what is going on i…...

1Panel应用推荐:WordPress开源博客软件和内容管理系统
1Panel(github.com/1Panel-dev/1Panel)是一款现代化、开源的Linux服务器运维管理面板,它致力于通过开源的方式,帮助用户简化建站与运维管理流程。为了方便广大用户快捷安装部署相关软件应用,1Panel特别开通应用商店&am…...

【数据结构-C语言】绪论
文章目录 一、前言二、基本概念和术语2.1 数据元素、数据项和数据对象2.2 数据结构2.2.1 逻辑结构2.2.2 存储结构 2.3 时间复杂度 一、前言 数据结构部分是根据严蔚敏老师的《数据结构-C语言版第2版》书中内容整理的。 二、基本概念和术语 2.1 数据元素、数据项和数据对象 …...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...