C++/MySQL/Redis 锁机制 - 2
MySQL 锁机制:数据库事务中的数据一致性保障MySQL 作为关系型数据库,其锁机制与事务隔离级别深度绑定,核心解决多事务并发访问时的数据一致性问题(如脏读、不可重复读、幻读)。锁的粒度从 “表级” 到 “行级”,支持乐观锁与悲观锁,适配不同并发场景。 1. 表级锁:粗粒度悲观锁核心定义锁定整个数据表,同一时间仅允许特定类型的操作(读 / 写)执行,是 MySQL 中粒度最粗的锁。MyISAM 存储引擎默认支持,InnoDB 也支持但不常用。 底层实现 读锁(共享锁,S 锁):多个事务可同时获取读锁,允许读操作,禁止写操作; 写锁(排他锁,X 锁):仅一个事务可获取写锁,禁止其他事务读 / 写操作; 锁冲突检测在 MySQL 服务器层完成,无需深入存储引擎,开销低但并发度低。 代码示例(手动加表锁)1234567891011-- 1. 会话1:获取表读锁(允许其他会话读,禁止写)LOCK TABLES user_info READ;SELECT * FROM user_info WHERE id = 1; -- 允许执行UPDATE user_inf...
C++/MySQL/Redis 锁机制 - 1
导言在并发编程与分布式系统中,锁机制是保障数据一致性的核心技术。不同技术栈因运行环境(本地进程 / 数据库 / 分布式集群)差异,锁的实现逻辑、核心特性与适用场景存在显著区别。 一、C++ 锁机制:本地进程内的并发控制C++ 作为系统级编程语言,其锁机制基于操作系统内核态同步原语(如互斥量、信号量)与用户态原子操作实现,核心解决单进程内多线程共享内存的线程安全问题。C++11 及以后通过 <thread>、 <mutex>、 <atomic> 等标准库提供统一锁接口,同时支持自定义锁实现。 1. 互斥锁(std::mutex):C++ 基础悲观锁核心定义C++ 标准库中的基础悲观锁,通过操作系统互斥量(Mutex)实现,保证同一时间只有一个线程进入临界区,其他竞争线程会阻塞等待,直到锁释放。是解决本地线程并发冲突的 “通用方案”。 底层实现 依赖操作系统内核态同步原语(如 Linux 的 pthread_mutex_t、Windows 的 CRITICAL_SECTION); 线程竞争失败时会从用户态切换到内核态,进入阻塞...
响应式设计与媒体查询:一套代码,适配所有屏幕
一、为什么需要响应式设计?1.1 一个页面,千种屏幕打开你的博客,分别在以下设备上查看: 设备 典型宽度 使用场景 手机(竖屏) 375px 地铁上刷文章 手机(横屏) 812px 看视频、看代码 平板 768px - 1024px 沙发上阅读 笔记本 1366px - 1440px 日常办公 台式显示器 1920px+ 多窗口并行 超宽屏 2560px+ 专业工作站 截至 2025 年,全球超过 55% 的 Web 流量来自移动设备。如果一个网站只在桌面端好看,等于放弃了超过一半的用户。 1.2 两种策略:自适应 vs 响应式在响应式设计成为主流之前,存在两种思路: 策略 做法 缺点 自适应(Adaptive) 为手机和桌面各写一套页面(如 m.example.com) 维护两套代码,成本翻倍 响应式(Responsive) 一套 HTML/CSS,根据屏幕尺寸自动调整布局 需要对 CSS 有更深入的理解 响应式设计是 Ethan Marcotte 在 2010 年提出的概念,核心三要素: 流体网格(Flu...
线程局部存储
一、TLS 在多线程环境中的关键技术作用 核心定义:线程局部存储(Thread Local Storage,TLS)是多线程编程中的一种内存隔离机制,为每个线程分配独立的内存空间(即 “线程私有副本”),使线程对该空间的数据访问无需竞争锁资源,且数据仅对所属线程可见。 解决的核心问题: 避免多线程数据竞争:当多个线程需使用同一逻辑变量但无需共享时(如线程内计数器),TLS 替代共享内存 + 锁的方案,消除锁开销与死锁风险。 保证线程数据独立性:确保线程在生命周期内的私有数据(如上下文信息、临时计算结果)不被其他线程篡改,维持线程运行稳定性。 简化线程数据管理:无需手动为每个线程分配 / 释放私有内存,由 TLS 机制自动管理内存生命周期(随线程创建而分配,随线程退出而释放)。 二、TLS 的实现机制2.1 静态分配(编译期确定)原理: 在编译阶段,编译器将标注 “线程局部” 的变量(如 C++ 的thread_local、POSIX 的__thread)分配到特定的 TLS 段(ELF 文件中的.tbss/.tls 段),并生成访问该段的指令。 ...
Flexbox 弹性布局实战:告别浮动,拥抱现代 CSS 布局
一、从"痛苦的浮动"到"丝滑的弹性"1.1 回到那个用 float 布局的年代在 Flexbox 诞生之前,CSS 布局主要依赖 float 和 position。这些属性最初并非为复杂布局设计——float 的本意是让文字环绕图片。 但前端开发者硬是用它们做出了多栏布局、导航栏、卡片网格……代价是各种 hack 技巧: 123456789101112131415161718/* 旧时代的"圣杯布局"——每个前端都经历过 */.left { float: left; width: 200px;}.right { float: right; width: 200px;}.main { margin: 0 200px; /* 避开左右浮动元素 */}/* 还得写 clearfix 清除浮动…… */.clearfix::after { content: ""; display: table; ...
std::tuple 的使用
一、tuple 核心定位与基本特性std::tuple(定义于 头文件)是 C++17 标准库中用于打包多个异构数据类型的轻量级容器,其核心价值在于: 无需定义自定义结构体 / 类,即可承载任意数量的不同类型数据; 配合 C++17 新特性(如类模板参数推导 CTAD、结构化绑定),大幅简化异构数据的创建与访问; 无动态内存分配,内存开销与手动定义的结构体相当,性能高效。 关键区别: 与 std::array:array 仅支持同构类型(如 array<int, 3>),tuple 支持异构类型(如 tuple<int, string, double>); 与 std::pair:pair 仅支持最多 2 个元素,tuple 无元素数量限制。 二、tuple 基本用法(创建与访问)1. 创建方式(C++17 CTAD 特性重点)C++17 引入类模板参数推导(CTAD),创建 tuple 时无需显式指定模板参数,编译器会自动推导类型。 创建方式 代码示例 说明 CTAD 直接初始化 tuple t1(42, &qu...
CSS 盒模型与基础样式:给网页穿上得体的衣服
一、CSS 是什么:网页的"视觉设计师"在系列第一篇文章中我们建立了这个类比: 技术 角色 HTML 结构骨架——定义"是什么" CSS 视觉表现——定义"长什么样" JavaScript 交互行为——定义"能做什么" CSS(Cascading Style Sheets,层叠样式表)的职责就是把浏览器默认的"素颜"HTML 变成你想要的任何视觉效果。 先看一个直观对比——同样一份 HTML,不加 CSS 和加了 CSS 的差异: 1234<!-- 没有 CSS:浏览器默认样式——黑白分明,毫无美感 --><h1>我的博客首页</h1><p>欢迎来到我的技术博客。</p><a href="#">阅读更多</a> 1234<!-- 有了 CSS:字体、颜色、间距、背景——焕然一新 --><h1 style="font-size:...
读写锁技术:原理、实现
一、读写锁同步模型与核心概念1.1 核心锁类型定义读写锁(Read-Write Lock)是一种细粒度并发控制机制,通过拆分锁权限解决 “读多写少” 场景下的资源竞争问题,包含两类锁: 读锁(共享锁,Shared Lock):允许多个线程同时持有,适用于只读操作 写锁(排他锁,Exclusive Lock):仅允许单个线程持有,适用于修改操作 1.2 同步控制核心条件读写锁通过严格的权限控制实现并发安全,核心同步规则如下: 锁组合 允许并发? 核心原因 读锁 + 读锁 是 只读操作不修改数据,无竞争 读锁 + 写锁 否 读写操作存在数据一致性冲突 写锁 + 写锁 否 多写操作会导致数据覆盖 1.3 内部状态机设计读写锁通过状态计数器维护锁的持有状态,主流实现采用 “高位存读计数 + 低位存写标记” 的紧凑设计(以 32 位状态为例): 1[31位:读锁持有数量] | [1位:写锁标记(0=无写锁,1=有写锁)] 状态转换逻辑示例: 无锁状态(0x00000000)→ 加读锁 → 0x00000001(读计数 = 1,无写锁) 读锁状...
JavaScript 表单交互与现代化重构:从原生弹窗到优雅交互
一、引言:从需求出发1.1 典型场景设想一个最简单的交互需求:用户在输入框中填入自己的名字,点击提交按钮后,页面向用户打个招呼。 这是 Web 开发中最基础的用户交互模式——获取输入 → 处理数据 → 给出反馈。尽管需求简单,但从代码质量的角度看,实现方式却有"能用"和"优雅"的天壤之别。 1.2 原始代码还原以下是初学者常写出的第一版代码。它能跑,但存在诸多值得推敲的地方: 123456789101112131415161718192021222324<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8"> <title>打招呼</title></head><body> <form id="greetingForm"> <label for="name&qu...
Git 冲突规避
导言Git 冲突的本质是并行开发中代码变更的重叠与未及时同步,而非单纯的技术问题。 一、先搞懂:Git 冲突的 3 大核心根源在解决问题前,必须明确冲突的来源,才能针对性预防: 同步滞后:长期在本地分支开发,不与主分支同步,导致累积大量差异(最常见,占冲突总量的 60%+) 范围重叠:多开发者同时修改同一文件的同一代码块(如两个开发者改同一个接口的参数) 管控缺失:无分支规范(如直接在主分支开发)、无提交标准(大提交包含多个功能)、无依赖锁定(package.json 频繁冲突) 二、核心策略 :搭建「零冲突友好型」分支体系分支管理是冲突规避的基石,90% 的高频冲突源于混乱的分支结构。推荐两种经过验证的分支模型,团队需二选一并严格执行。 2.1 选择适配的分支模型根据团队规模和项目类型选择,避免混合使用导致混乱: 分支模型 适用场景 核心分支结构 冲突风险 Git Flow 中大型项目、有固定发版周期 main (生产)+develop (开发)+feature/bugfix/hotfix 低 GitHub Flow 小型项目、敏捷迭代(如 ...
Python dataclass深度解析:用装饰器干掉手写样板代码
一、写到手酸的样板代码:一个类要抄多少遍但凡用类装数据的 Python 程序员,都写过这种东西: 1234567891011121314151617class Point: def __init__(self, x, y): self.x = x self.y = y def __repr__(self): return f"Point(x={self.x}, y={self.y})" def __eq__(self, other): if not isinstance(other, Point): return NotImplemented return self.x == other.x and self.y == other.yp1 = Point(1, 2)p2 = Point(1, 2)print(p1) # Point(x=1, y=2)print(p1 == p2) ...
HTML5 语义化入门:使用语义化标签构建个人博客首页
一、HTML 是什么:网页的"结构骨架"很多人初学前端时,会问:"HTML 是一门编程语言吗?" 答案很明确:不是。 HTML 的全称是 HyperText Markup Language(超文本标记语言)。它没有变量、没有循环、没有条件判断——它唯一的职责,就是描述网页的内容结构。 一个恰当的类比是盖房子: 技术 类比 角色 HTML 钢筋水泥框架 结构骨架——哪里是墙、哪里是门、哪里是窗 CSS 装修涂料 视觉表现——颜色、字体、布局、动画 JavaScript 水电智能家居 交互行为——点击响应、数据加载、动态渲染 理解这个分工至关重要:HTML 负责"是什么",CSS 负责"长什么样",JavaScript 负责"能做什么"。三者各司其职,混乱分工是前端代码腐化的起点。 1.1 "语义化"是什么?为什么重要?在早期 Web 开发中,页面结构大量依赖 <div> 和 <span> 这两个通用容器: 1234&...
单元测试在软件工程中的核心价值
一、引言:单元测试的定位与行业标准根据IEEE 829 测试文档标准,单元测试是软件测试体系中最底层、最基础的测试层级,聚焦于 “最小可测试单元”(如函数、类、模块)的功能验证。作为软件开发流程的关键环节,单元测试并非 “可选优化项”,而是经过行业实践验证的 “质量保障基础设施”。截至 2025 年,全球 Top 100 科技企业中,97% 已将单元测试纳入强制开发规范,其核心价值体现在技术合理性、风险控制、协作效率等多维度的综合收益。 二、单元测试的五大核心技术价值(附数据支撑)1. 缺陷前置预防:降低修复成本的关键机制缺陷的发现阶段直接决定修复成本。根据IBM 软件工程研究院的研究数据: 需求阶段发现的缺陷,修复成本为 “1x”; 编码阶段(未做单元测试)发现的缺陷,修复成本升至 “5x”; 系统测试阶段发现的缺陷,修复成本达 “10x”; 生产环境发现的缺陷,修复成本高达 “100x-1000x”。 单元测试可在编码阶段直接拦截 60%-70% 的逻辑缺陷,使缺陷修复成本降低 80% 以上。 2. 保障代码可维护性:支撑系统演进的 “安全网”软件系统的长期价值依...
Python lru_cache深度解析:用备忘录把递归从指数砍到线性
一、一个被忽略的时间黑洞:重复计算写递归的人几乎都写过斐波那契: 12345678910import timedef fib(n): if n < 2: return n return fib(n - 1) + fib(n - 2)t0 = time.perf_counter()print(fib(35))print("耗时:", round(time.perf_counter() - t0, 2), "秒") 输出(64 位 Python): 129227465耗时: 2.13 秒 fib(35) 看起来不大,却把 fib 调用了约 2980 万次。一旦换成 fib(50),基本就卡死了——因为 fib(n-1) 和 fib(n-2) 各自又把 fib(n-3) 算一遍,子树大量重叠。这种"同一个子问题被反复求解"的现象叫重叠子问题(overlapping subproblems),是动态规划与记忆化要解决的核心。 问题来了:既然算过,为什么不复用? 答案是——默认情况下,Pytho...
PKGCONF依赖管理内容整理
一、安装与配置:Ubuntu 环境搭建pkgconf 是 pkg-config 的现代替代品,兼容其核心功能且解析速度更快、依赖处理更高效。在 Ubuntu 系统中,需通过官方包管理器完成安装与基础配置,确保工具可正常识别依赖包的 .pc 文件(记录编译链接参数的核心文件)。 1. Ubuntu 下的 pkgconf 安装Ubuntu 官方仓库已预装 pkgconf(通常随开发工具链默认安装),若未安装或需更新,执行以下命令: 基础安装:打开终端,执行sudo apt update && sudo apt install pkgconf,该命令会: 同步 Ubuntu 软件源索引,确保获取最新版本; 安装 pkgconf 主程序及依赖(如 libpkgconf3 库); 自动配置默认 .pc 文件搜索路径(无需手动设置基础路径)。 版本验证:安装后执行pkgconf --version,Ubuntu 20.04 输出约 0.29.2,Ubuntu 22.04 输出约 1.8.1(高版本支持更多特性,如更灵活的依赖过滤);若提示 “command not f...
Python __slots__深度解析:用固定布局干掉实例字典
一、一个被忽略的内存黑洞:每个实例都有一本"字典"写 Python 的人几乎都见过这种类: 1234class Point: def __init__(self, x, y): self.x = x self.y = y 看着简单,但它藏着一个代价。Python 为了实现"运行时随便加属性"的灵活性,默认给每个实例都挂了一本字典 __dict__,用来存 x、y 这些实例变量。这本字典本身是个哈希表,哪怕你只放两个字段,它也要预分配几十个字节的槽位。 做个实验就知道了: 1234567891011import sysclass Plain: def __init__(self, x, y): self.x = x self.y = yp = Plain(1, 2)print("实例大小:", sys.getsizeof(p)) # 实例对象自身print("__dict__ 大小:", sys.getsizeof(...
Redis gdb 调试整理
一、调试前环境准备(必须配置)调试 Redis 的核心前提是保留调试符号与开启核心日志,否则无法定位源码问题。 1. Redis 编译配置(带调试符号)默认make会开启优化(-O2)并剥离调试符号,需重新编译保留调试信息: 12345678# 1. 清理原有编译结果make distclean# 2. 编译时保留调试符号(-g)+ 关闭优化(-O0,避免代码指令重排)make CFLAGS="-g -O0"# 3. 验证调试符号是否存在(输出包含 "with debug_info" 即正常)file src/redis-server | grep debug 2. Redis 核心日志配置(辅助调试)修改redis.conf,开启详细日志以定位问题上下文: 123456789101112# 日志级别:调试阶段设为 verbose(输出核心操作)loglevel verbose# 日志文件:指定路径便于后续分析logfile "/var/log/redis/redis-debug.log"# 记录客户端命令(调试命令处...
Python元类深度解析:用「类的类」在创建期定制类(及C++模板元编程视角)
一、引子:当你写下 class 时,到底发生了什么写 Python 久了,很容易把 class 当成"定义一个模板"的声明。但 Python 里没有"声明",只有"执行"。 1234567class Person: name = "Ada" def greet(self): return f"Hi, I'm {self.name}"print(type(Person)) # <class 'type'>print(type(type(Person))) # <class 'type'> 输出: 12<class 'type'><class 'type'> Person 不是某种静态蓝图,它是 type 这个类当场造出来的一个实例。type 就是"类的类&q...
基于 Redis-cli 的核心命令与服务
第一章 Redis 安装验证与原生连接安装 Redis 后,首要任务是通过redis-cli(Redis 自带命令行客户端)验证服务可用性,并掌握基础连接参数与配置查看方式。 1.1 安装后基础验证(redis-cli 核心命令)无论通过yum/apt/ 源码编译安装,Redis 均默认自带redis-cli工具,直接在终端执行以下命令验证服务: 123456789101112131415161718192021222324# 1. 本地连接(默认端口6379,无密码时)redis-cli# 成功连接后会显示Redis服务地址与端口,提示符如下:127.0.0.1:6379> # 2. 验证服务存活(核心命令:PING)127.0.0.1:6379> PING# 返回结果:PONG(表示服务正常运行)# 3. 查看Redis版本(核心命令:INFO server)127.0.0.1:6379> INFO server# 关键输出(截取版本信息):redis_version:6.2.6 # Redis版本redis_git_sha1:0000...
Python异步编程深度解析:asyncio事件循环与async/await(及与多线程对比)
一、引子:为什么 time.sleep 会"卡死"整个服务写过网络爬虫或高并发接口的人,迟早会撞上同一个问题:明明机器有 8 个核、网络在等 I/O,程序却像单车道一样,一个请求没回来,后面的全堵着。 先看一个"看似没问题"的代码: 1234567891011import timedef fetch(name, delay): time.sleep(delay) # 模拟一次网络请求 print(f"{name} 完成,耗时 {delay}s")def main(): for i in range(3): fetch(f"任务{i}", 1)main() 输出: 1234任务0 完成,耗时 1s任务1 完成,耗时 1s任务2 完成,耗时 1s# 总耗时约 3s time.sleep 是阻塞的:线程睡着的这段时间,CPU 什么也干不了,后面的任务只能干等。三个任务串行,总耗时 ...
自定义对象支持 C++ 范围循环(Range-based for)的实现
导言范围循环(C++11 引入)是现代 C++ 中遍历容器的便捷方式,其核心依赖迭代器协议与begin/end 接口。 一、范围循环的底层实现原理C++ 标准规定,对于表达式for (range_declaration : range_expression),编译器会自动将其展开为以下逻辑(伪代码): 123456789// 1. 获取范围的起始与结束迭代器auto __begin = begin(range_expression);auto __end = end(range_expression);// 2. 遍历逻辑:依赖迭代器的 !=、++、* 操作for (; __begin != __end; ++__begin) { range_declaration = *__begin; // 解引用获取元素 loop_statement; // 循环体} 关键依赖接口要支持范围循环,自定义对象需满足: 存在可被调用的 begin() 和 end() 函数(成员函数或非成员函数); begin()...
Final/Override/Default/Delete 关键字整理
导言整理CppGuide社区内容,Final/Override/Default/Delete 均为C++ 关键字,ANSI C(如 C89、C99、C11)标准不支持这些特性。以下解析基于 C++(面向对象扩展,常与 C 语言结合使用),关联 C 语言的内存管理、代码安全思想,所有代码需用 C++ 编译器(如 g++、clang++)编译,ANSI C 编译器(如 gcc)均不支持。 一、Final 关键字:限制继承与重写1. 语义定义与作用域 作用 1:修饰类时,禁止该类被继承(作用域为整个类) 作用 2:修饰虚函数时,禁止子类重写该虚函数(作用域为单个虚函数) C 语言类比:C 中通过结构体封装 + 函数指针模拟多态时,需手动规范 “继承”(如不允许其他结构体包含父结构体模拟继承),但 Final 是 C++ 编译期强制约束,比 C 的代码规范更可靠。 2. 代码实例 1:Final 修饰类(禁止继承)123456789101112131415161718192021222324252627#include <stdio.h>...
Python装饰器的两种身份:内置语法糖与第三方注册表(及C++视角)
一、引子:为什么满屏 @ 却不用慌刚接触 Python 的人,第一次打开一个 Flask 或 pytest 项目,往往会被装饰器吓到: 12345678910111213@app.route("/")@login_required@cache(ttl=60)def index(): ...@pytest.fixturedef db(): ...@propertydef name(self): ... @app.route、@login_required、@cache、@pytest.fixture、@property…… 名字一长串,看着像某种需要逐个背诵的黑魔法。 但真相是:名字多,不等于机制多。 所有装饰器底下都只有同一句等价变换: 1f = deco(f) # 把函数当参数传进去,返回值绑回原名 @deco 只是上面这句的语法糖。理解了这一点,你就有了"防恐慌锚点"——无论遇到什么新装饰器,先问自己一句:它到底是在"包装"我的函数,还是在"登记"我的函数?...
Python上下文管理器深度解析:with语句、contextlib与C++ RAII对比
一、从一段"看起来没问题"的代码说起几乎每个 Python 初学者都写过这样的文件读取代码: 123f = open('data.txt', 'r', encoding='utf-8')content = f.read()f.close() 三行,逻辑清晰,运行也正常。但它有一个致命缺陷:如果 f.read() 抛出异常,f.close() 永远不会执行。 1234f = open('data.txt', 'r', encoding='utf-8')content = f.read()print(content[999999]) # IndexError!f.close() # 这一行被跳过了 文件描述符泄漏了。单次运行看不出问题,但如果这段代码在循环里跑一万次,进程很快就会撞上操作系统的 ulimit -n 上限,抛出 OSError: [Errno 24] Too many open files。 老...
C++ 中 struct 与 class 的核心差异与应用场景
导言在 C++ 编程中,struct与class是定义复合数据类型的核心语法元素,二者既共享大部分 OOP(面向对象编程)特性,又因设计初衷不同存在关键差异。 一、语法定义与核心共性struct源于 C 语言的结构化数据设计,class则是 C++ 为支持 OOP 引入的特性。在 C++ 标准(ISO/IEC 14882)中,二者功能上高度重合,仅在默认行为上存在差异。 1.1 核心共性 成员定义能力:均可包含数据成员(如int x)和成员函数(如void print()),支持静态成员(static)和友元(friend)。 OOP 特性支持:均支持构造函数、析构函数、拷贝 / 移动语义、继承、多态(虚函数)。 内存布局规则:数据成员的对齐(alignment)、填充(padding)逻辑完全一致,由编译器根据平台(如 32 位 / 64 位)和类型大小决定。 模板与容器适配:均可作为 STL 容器(如std::vector)的元素类型(需满足容器要求,如可拷贝性)。 1.2 共性示例代码1234567891011121314151617...

