Redis 作为 MySQL 缓存选择因素归类
引言:高并发时代下的数据库性能困境与缓存破局在现代应用架构中,高并发读取场景(如电商商品详情页、CMS 文章列表、用户会话查询)已成为系统性能的核心挑战。MySQL 作为主流关系型数据库,其 InnoDB 存储引擎基于磁盘 IO 实现数据持久化,在单机并发读场景下,性能通常局限于 1k-10k QPS(受磁盘寻道时间、页缓存命中率影响),难以满足秒杀、大促等峰值需求。 Redis 作为开源高性能内存数据库,凭借 内存级 IO 特性(读 QPS 可达 10 万 - 100 万,写 QPS 可达 5 万 - 50 万)、丰富的数据结构和灵活的过期策略,成为 MySQL 缓存的首选方案。 一、技术原理:Redis 与 MySQL 的协作核心Redis 作为 MySQL 缓存的本质是 “将热点数据从磁盘迁移到内存”,但需解决数据一致性、缓存命中率、异常场景处理三大核心问题。 要点 1:缓存协作模型选型(4 种经典模式)Redis 与 MySQL...
通用代码审查清单整理
一、常规功能与可读性(P1+P2) 序号 审查项 判定标准(二元可验证) 优先级 1 功能实现完整性 代码覆盖所有预期需求点(对照需求清单无遗漏,无逻辑错误,如模板特化、重载函数功能符合设计) P1 2 代码易懂性 新接手开发者可在 10 分钟内理解核心逻辑(无过度复杂模板嵌套、晦涩宏定义、无拼音 / 英文混杂命名) P1 3 编码规范符合性 完全匹配团队 C++ 规范(如大括号位置、命名空间使用、const/constexpr正确修饰、缩进无违规) P1 4 冗余代码清理 无重复代码(≥3 行相同逻辑未抽取为函数 / 模板)、无注释掉的无效代码块(如废弃的类成员、未使用的全局函数) P1 5 循环安全性 循环有明确终止条件(无死循环风险),无循环内重计算(如重复获取std::vector长度),无迭代器失效场景(如循环中增删容器元素) P1 6 全局变量 / 对象合理性 无不必要全局变量(可替换为局部变量 /...
C++/MySQL/Redis 锁机制 - 3
Redis 锁机制:分布式集群的并发控制Redis 作为分布式缓存与数据库,其锁机制主要解决跨节点、跨进程的分布式并发问题(如微服务集群中共享资源的互斥访问)。核心是 “分布式锁”,基于 Redis 原子命令和 Lua 脚本实现,支持可重入、公平锁等特性。 1. 基础分布式锁:基于 SETNX 命令核心定义利用 Redis 的 SETNX(SET if Not Exists)原子命令实现的分布式锁:若键不存在则设置值(获取锁),若已存在则失败(锁已被持有),确保同一时间仅一个节点的一个线程获取锁。 底层实现 核心命令:SET lock_key thread_id NX EX 10(NX:不存在才设置,EX:过期时间 10 秒); 锁标识:用 thread_id(如 “node1_thread2”)标记持有锁的线程,避免误释放其他线程的锁; 过期时间:防止线程崩溃导致锁无法释放(死锁),需设置合理的过期时间(大于业务执行时间)。 代码示例(Redis CLI 实现)123456789101112131415# 1. 获取锁:SETNX +...
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...
C++/MySQL/Redis 锁机制 - 1
导言在并发编程与分布式系统中,锁机制是保障数据一致性的核心技术。不同技术栈因运行环境(本地进程 / 数据库 / 分布式集群)差异,锁的实现逻辑、核心特性与适用场景存在显著区别。 一、C++ 锁机制:本地进程内的并发控制C++ 作为系统级编程语言,其锁机制基于操作系统内核态同步原语(如互斥量、信号量)与用户态原子操作实现,核心解决单进程内多线程共享内存的线程安全问题。C++11 及以后通过 <thread>、 <mutex>、 <atomic> 等标准库提供统一锁接口,同时支持自定义锁实现。 1. 互斥锁(std::mutex):C++ 基础悲观锁核心定义C++ 标准库中的基础悲观锁,通过操作系统互斥量(Mutex)实现,保证同一时间只有一个线程进入临界区,其他竞争线程会阻塞等待,直到锁释放。是解决本地线程并发冲突的 “通用方案”。 底层实现 依赖操作系统内核态同步原语(如 Linux 的 pthread_mutex_t、Windows 的...
响应式设计与媒体查询:一套代码,适配所有屏幕
一、为什么需要响应式设计?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...
线程局部存储
一、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,...
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...
读写锁技术:原理、实现
一、读写锁同步模型与核心概念1.1 核心锁类型定义读写锁(Read-Write Lock)是一种细粒度并发控制机制,通过拆分锁权限解决 “读多写少” 场景下的资源竞争问题,包含两类锁: 读锁(共享锁,Shared Lock):允许多个线程同时持有,适用于只读操作 写锁(排他锁,Exclusive Lock):仅允许单个线程持有,适用于修改操作 1.2 同步控制核心条件读写锁通过严格的权限控制实现并发安全,核心同步规则如下: 锁组合 允许并发? 核心原因 读锁 + 读锁 是 只读操作不修改数据,无竞争 读锁 + 写锁 否 读写操作存在数据一致性冲突 写锁 + 写锁 否 多写操作会导致数据覆盖 1.3 内部状态机设计读写锁通过状态计数器维护锁的持有状态,主流实现采用 “高位存读计数 + 低位存写标记” 的紧凑设计(以 32 位状态为例): 1[31位:读锁持有数量] | [1位:写锁标记(0=无写锁,1=有写锁)] 状态转换逻辑示例: 无锁状态(0x00000000)→ 加读锁 → 0x00000001(读计数 =...
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...
Git 冲突规避
导言Git 冲突的本质是并行开发中代码变更的重叠与未及时同步,而非单纯的技术问题。 一、先搞懂:Git 冲突的 3 大核心根源在解决问题前,必须明确冲突的来源,才能针对性预防: 同步滞后:长期在本地分支开发,不与主分支同步,导致累积大量差异(最常见,占冲突总量的 60%+) 范围重叠:多开发者同时修改同一文件的同一代码块(如两个开发者改同一个接口的参数) 管控缺失:无分支规范(如直接在主分支开发)、无提交标准(大提交包含多个功能)、无依赖锁定(package.json 频繁冲突) 二、核心策略 :搭建「零冲突友好型」分支体系分支管理是冲突规避的基石,90% 的高频冲突源于混乱的分支结构。推荐两种经过验证的分支模型,团队需二选一并严格执行。 2.1 选择适配的分支模型根据团队规模和项目类型选择,避免混合使用导致混乱: 分支模型 适用场景 核心分支结构 冲突风险 Git Flow 中大型项目、有固定发版周期 main (生产)+develop (开发)+feature/bugfix/hotfix 低 GitHub Flow 小型项目、敏捷迭代(如...
HTML5 语义化入门:使用语义化标签构建个人博客首页
一、HTML 是什么:网页的"结构骨架"很多人初学前端时,会问:"HTML 是一门编程语言吗?" 答案很明确:不是。 HTML 的全称是 HyperText Markup Language(超文本标记语言)。它没有变量、没有循环、没有条件判断——它唯一的职责,就是描述网页的内容结构。 一个恰当的类比是盖房子: 技术 类比 角色 HTML 钢筋水泥框架 结构骨架——哪里是墙、哪里是门、哪里是窗 CSS 装修涂料 视觉表现——颜色、字体、布局、动画 JavaScript 水电智能家居 交互行为——点击响应、数据加载、动态渲染 理解这个分工至关重要:HTML 负责"是什么",CSS 负责"长什么样",JavaScript 负责"能做什么"。三者各司其职,混乱分工是前端代码腐化的起点。 1.1 "语义化"是什么?为什么重要?在早期 Web 开发中,页面结构大量依赖 <div> 和 <span>...
单元测试在软件工程中的核心价值
一、引言:单元测试的定位与行业标准根据IEEE 829 测试文档标准,单元测试是软件测试体系中最底层、最基础的测试层级,聚焦于 “最小可测试单元”(如函数、类、模块)的功能验证。作为软件开发流程的关键环节,单元测试并非 “可选优化项”,而是经过行业实践验证的 “质量保障基础设施”。截至 2025 年,全球 Top 100 科技企业中,97% 已将单元测试纳入强制开发规范,其核心价值体现在技术合理性、风险控制、协作效率等多维度的综合收益。 二、单元测试的五大核心技术价值(附数据支撑)1. 缺陷前置预防:降低修复成本的关键机制缺陷的发现阶段直接决定修复成本。根据IBM 软件工程研究院的研究数据: 需求阶段发现的缺陷,修复成本为 “1x”; 编码阶段(未做单元测试)发现的缺陷,修复成本升至 “5x”; 系统测试阶段发现的缺陷,修复成本达 “10x”; 生产环境发现的缺陷,修复成本高达 “100x-1000x”。 单元测试可在编码阶段直接拦截 60%-70% 的逻辑缺陷,使缺陷修复成本降低 80% 以上。 2. 保障代码可维护性:支撑系统演进的...
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...
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"#...
基于 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 #...
自定义对象支持 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()...
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...

