自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(95)
  • 收藏
  • 关注

原创 HTTP 和 HTTPS 的区别

大家好,我是程序员有点困。很多人第一次学 HTTP 和 HTTPS 的时候,最容易记住一句话:HTTPS 比 HTTP 多了一个 SSL/TLS 加密。这句话不能说错,但如果面试只答到这里,基本就停在表层了。HTTP 为什么不安全?HTTPS 到底解决了什么问题?HTTPS 是怎么保证安全的?为什么有了加密还需要证书?HTTPS 会不会影响性能?项目里什么时候必须用 HTTPS?先醒醒神,我们别急着背定义,先从一个真实场景开始看。

2026-06-04 13:26:25 259

原创 MCP 是什么,为什么 AI Agent 都在用它

大家好,我是程序员有点困。MCP。很多人第一次看到它,会觉得这又是一个新概念:什么 MCP Client?什么 MCP Server?什么 Tool?为什么大家突然都在讲它?先别急着背定义。MCP 是让 AI 模型统一连接外部工具和系统的一套协议。如果说大模型本身像一个“会思考的大脑”,那 MCP 就是在帮这个大脑接上手脚、眼睛和工具箱。模型怎么连接工具?工具怎么统一暴露?Agent 怎么安全调用外部系统?MCP Client 负责代表 AI 应用发起调用。

2026-05-31 20:25:18 361

原创 JUC八股:线程池及ThreadLocal

线程池的核心思路是:复用线程。避免了来一个任务就new,不需要就销毁的开销流程:任务来了,先判断当前线程数量是否小于corePoolSize如果小于,则创建核心线程立即执行任务如果核心线程数已满,则尝试将任务加入到阻塞队列如果阻塞队列满了,就创建非核心线程执行任务;未满继续等待。

2026-05-27 15:58:26 352

原创 JUC常用工具类

以1.8位例,计算hash-定位桶位-判断桶是否为空-不为空(发生hash冲突)用锁锁住桶-链表插入-若链表过长,则转为红黑树对于为何空桶不需加锁,而非空桶需加锁的疑惑:空桶时 一个 CAS 就能完成插入 所以不用加锁非空桶涉及链表/红黑树修改 不是一次 CAS 能完成 所以必须加锁通过hash定位数组下标如果有hash冲突,沿着next指针遍历链表,next是volatile的找到目标节点后读取val,val也是volatile的。

2026-05-25 16:59:31 306

原创 JUC八股:AQS机制

线程想要获取资源,先CAS改state,成功就拿到资源,失败就包装成Node节点加入队列尾部,然后park挂起等待。前面的吸纳成释放资源后会unpark环形队列的后续节点。ReentrantLock,Semaphore,CountDownLatch,ReentrantReadWriteLock这些都是基于它实现的。AQS把排队,阻塞,唤醒这些操作都封装好了。CAS是工具,AQS是基于这个工具诞生的框架。——park挂起线程(阻塞休眠)——unpark唤醒后继线程。——后继线程重新抢锁。

2026-05-25 13:50:37 161

原创 JUC八股:线程基础

NEW(新建) 就绪(Runnable) 运行(Running) 阻塞(Blocked) 终止(Terminated)新建:当线程创建后就进入。已经有了相应的内存空间和其他资源,还没开始运行就绪:对象调用start方法,进入就绪。具备运行条件,只等CPU分配资源让其运行运行:当线程获得CPU资源后,开始执行run中的代码,线程处于运行态阻塞:线程在某些情况下被挂起,暂停执行。当线程处于阻塞状态时,并不会占用CPU资源终止:当线程的run方法执行完毕或者异常退出时,线程进入终止。

2026-05-24 14:33:39 374

原创 JUC:锁机制/关键字

可重入锁:同一个线程能重复获取同一把锁,而不会死锁直观理解就是以嵌套为例,当线程第一次调用a获取到锁时,第二次调用时发现a已经被锁,只能阻塞等待锁释放。锁永远无法释放。这就是死锁所以可重入锁的产生背景就是Java方法调用经常嵌套。synchronized 和 ReentrantLock 都是可重入锁。底层通过:记录当前持有锁线程(owner)和计数器(count)实现两者区分的本质时:多个线程抢锁时,是否按先来后到的顺序默认时非公平锁,业务性能更高。

2026-05-24 14:32:55 545

原创 20天速通LeetCodeday17:一维动态规划

作为入门的一维动态规划。核心需要理解:一维DP就是沿着线性状态从前往后累积计算,每个状态只依赖前两个状态本题重点只有一个,就是理解dp[i]的递增实现理解dp[i] = max(dp[i-1] + nums[i], nums[i])就能掌握本题想要讲的重点是关于递归和一维动态规划的区别递归的特点是:自己调用自己,没有记录已经计算过的结果DP的特点是:讲递归的重复计算结果记住用一个数组dp[i]存储每个状态的结果自底向上(从小状态开始计算到大状态)

2026-05-17 18:51:37 441

原创 [HashMap]模拟put/get操作流程助你理解高频考点HashMap

put流程需要注意的点一共有两种:链表切换成红黑树以及扩容的触发时机,两者时机要进行区分:一个是链表长度,一个是数组长度。以及扩容逻辑与具体操作上面我们了解了put/get的具体流程,接下来讲述的是上述流程的一些具体细节。

2026-05-17 18:17:50 665

原创 Java并发八股学习日记

StampedLock是Java8引入的一种锁机制,相比ReentrantReadWriteLock最大的改进是引入了乐观读锁。传统的读写锁再读的时候也要加锁,而StampedLock的乐观锁压根不加锁,只是拿到一个时间戳,读完再校验一下这期间有没有什么写操作。如果没有,读就成功了;如果有写操作介入;再降级成悲观读锁重试。这种设计在读多写少的场景下性能提升非常明显,因为大部分读操作都不用真正竞争锁。写锁:独占模式,和ReentrantLock一样,同一时刻只能由一个线程持有写锁。

2026-05-14 19:36:35 381

原创 20天速通LeetCodeday15:BFS广度优先搜索

兄弟们可以发现这道题出现在DFS中,现在他又出现在BFS中了。因为本质上来说DFS和BFS都是一种搜索策略。两种搜索思路都能实现题目的解答。我们来通过这道题来分析两种搜索的实现有哪些不一样。我们先来看相同的地方i<rows;这一块实现的功能都是先通过遍历找到一地块陆地。只有在找到陆地之后,我们才能开展不同的搜索策略。于是区别就来了。while(!//标记访问BFS事先维护了一个队列queue(存放第一块陆地)。

2026-05-14 19:32:27 544

原创 Java并发八股学习日记:关于什么是线程同步/安全/生命周期,及线程池

当多个线程同时访问同一段代码或数据时,不管运行时环境怎么调度这些线程,程序都能表现出正确的行为,不会出现数据不一致或逻辑错乱的情况举例子就是上述讲的超卖问题,出现问题的核心是:不同线程同时读到了还没更新的旧值,导致出现的脏读。互斥同步:用ReentrantLock和synchronized给临界区间加锁,同一时刻只允许一个线程对资源进行修改线程隔离:用ThreadLocal让每个线程持有自己的变量副本,压根就不共享。数据库连接池就常用这招,每个线程从池里连接时帮到自己的ThreadLocal上。

2026-05-12 18:36:48 376

原创 20天速通LeetCodeday14:DFS深度优先搜索

遍历网格,每当遇到1,计数就+1,然后通过dfs算法将所有链接在一起的岛屿一块淹掉。最终返回count和上一题的区别就是需要额外记录岛屿的最大面积通过观察:发现变化的主要有dfs中面积的增加方式,主函数中最大值的维护方式都是DFS+回溯,本题的区别在于需要判断路径是否存在,返回布尔值多了保存原值来保证回溯之前的结果。

2026-05-12 18:18:08 226

原创 20天速通LeetCodeday13:关于回溯

作为掌握回溯算法的第一题,重点回溯的实现原理:通过for循环选择第一个作为开始的数字;将该数字放在判断是否使用过的boolean数组中;继续递归重新挑选数字,直到将第一个完整排列选出来之后,就进行回溯,从叶子节点往上直到根节点。与上一题进行比较,进一步了解回溯所在的精华。path记录路径,以及后续的撤销也需要path,backtrack的for循环,用来挑选数字。回溯的套路依然是:选择-递归-回溯区别是path的选择:每一个path都是正确的。

2026-05-10 20:56:37 298

原创 20天速通LeetCodeday12:递归

翻转左右子树,先通过遍历得到左右子树,然后将其进行翻转。中间注意条件终止的时机。将本题与上一题进行区分,本题是判断对称,上一题是修改二叉树。堆对称需要左右子树进行判断,所以需要构造两个函数。上一题只需在二叉树中进行修改两个函数类型都是boolean,因为最终是需要返回判断值题目:要求我们通过前序与中序数组来推断出二叉树创建一颗二叉树从根节点入手我们需要了解前序遍历与中序遍历的特点;来得到根节点从前序遍历知道根节点的值,通过值来得到根节点在中序数组的位置;进一步得到二叉树的左子树与右子树。

2026-05-10 20:56:07 317

原创 20天速通LeetCodeday11:二叉树进阶

递归属于抽象理解,想要掌握递归思路,要再脑海中想象出递归的流程步骤就非常容易掌握。通过递归中序遍历整棵树,来判断是否满足二叉搜索树通过递归来遍历整个树。每次遍历完成后都更新targetSum的值,最后与叶子节点的值进行比较判断。二叉树中的left和right不是定值,题目会随着递归而更新。本题的核心思路就是“创建根节点(中点),通过递归的方法创建左子树与右子树,最后返回根节点用编号+BFS的方法来解决掌握编号的计算本题要求最后一个节点,想到用BFS层遍历来获取最后一个节点。

2026-05-08 11:52:33 342

原创 Redis八股学习日记:Redis如何删除过期数据;内存淘汰策略

惰性删除(被动清理):每次读写某一个key之前,Redis先检查这个key是不是过期了,过期的就顺手删除,然后返回空。好处是不额外占用CPU去扫描,坏处是如果一个过期key一直没被访问,它就会一直再内存中。定期删除(主动清理):Redis每100ms触发一次定时任务,随机抽一批设了过期时间的key检查,发现过期就删除。不是一下直接全表扫描,而是采样处理,因为清除动作也是占用CPU开销的。惰性删除可能会漏删,定期删除可能删不完。必须两者协助。

2026-05-06 18:45:58 407

原创 Redis八股学习日记:数据结构;跳表的底层;Reids的事务机制

是最基础的类型,能存储文本数字,二进制,最大位512MB。典型场景:缓存用户会话,页面数据,计数器。本质是键值对集合,。像一个商品数据,ID作为key,价格,库存,名称都可以存储在一个hash中,改个字段不用整体覆盖。是有序的字符串列表,底层是双向链表,支持两端操作。常见的场景是消息队列。LPUSH生产消息,RPOP消费消息。是无序不重复的集合,。适合做标签系统,记录某个页面的独立访客,共同关注等需要去重或集合运算的场景。和Set类似,但每个元素自带 一个score分数来排序,底层用跳表来实现。

2026-04-29 18:53:41 450

原创 Redis八股学习日记:布隆过滤器

特点是:存在误判,但原理:布隆过滤器由一个位数组和k个独立的哈希函数组成。,通过k个哈希函数将元素映射到数组的k个位置上,将这些位置设置为1。:同样计算k个位置,乳沟所有位置都是1,说明元素可能存在;只要有一个位置是0,代表一定不存在。图为假设:某个key通过hash-1和hash-2两个哈希函数,定位到数组中的值都为1,则说明存在。如果布隆过滤器判断一个元素不存在集合中,那么这个元素一定不在集合中,如果判断元素存在集合中则不定是真的,因为。因此布隆过滤器有误判的概率。

2026-04-29 15:59:51 527

原创 Redis:分布式锁,Redisson以及看门狗机制解析

Redis集群引入了哈希槽的概念,将整个数据集群划分为16384个槽。集群中每一个主节点复制维护一部分槽。存一个key时,redis先对key计算一个CRC16值,然后对16384取模,算出属于哪个槽,再把数据放到槽对应的节点。节点之间怎么联系集群中的节点是去中心化的。他们之间通过Gossip协议连接。通俗理解就像八卦协议,各个节点之间通过交流来保证数据的一致。客户端怎么找数据客户端随机连接一个节点。如果数据真好再这个节点,直接返回结果。

2026-04-27 20:45:51 567

原创 MySQL八股知识合集

具体由四点原因构成写性能急剧下降优化器选择困难空间占用膨胀DDL操作变慢MVCC是InnoDB引擎的一种并发控制机制,通过保存数据 的多个版本来管理事务之间的并发访问。它允许事务在读取数据时无需加锁,而是读取数据的历史快照,从而减少锁争用,提高并发性能,同时保证事务的隔离性。MVCC解决的问题:在高并发下,既要支持多事务并发操作,又尽量避免了因为锁竞争而导致的性能瓶颈。乐观锁和悲观锁是两种并发控制思想。面试从三点回答定义的解释两种锁实现的机制是什么根据不同业务怎么去选择锁。

2026-04-26 17:05:16 1010

原创 MySQL学习笔记:乐观锁VS悲观锁/八股总结

乐观锁和悲观锁是两种并发控制思想。面试从三点回答定义的解释两种锁实现的机制是什么根据不同业务怎么去选择锁乐观锁假设冲突不会发生,不加锁。在提交数据时如果发现数据被修改,则会拒绝当前事务并尝试,直到成功。悲观锁假设冲突一致存在,在操作的时候就加锁,其他事务不可访问机制:乐观锁:版本号或CAS。版本号需要维护额外字段,但不会产生CAS的ABA问题选择:读多写少用乐观,冲突多用悲观说清楚MySQL中怎么处理死锁的(两种方式)额外可说怎么避免死锁优化SQL的本质是为了。

2026-04-24 20:04:07 526

原创 20天速通LeetCodeday09:关于链表

掌握链表的语法:listNode prev=null掌握虚拟头节点的创建:ListNode dummy=new ListNode(0);遍历的逻辑返回dummy的语法:return dummy.next要求做到升序链表,想到用双指针来判断头节点的大小用剩余链表直接收尾本题的核心是:链表逐位相加 + 进位 carry核心三要素当前位 = sum % 10。

2026-04-24 20:03:28 289

原创 MySQL八股总结:B+树的优势

具体由四点原因构成写性能急剧下降优化器选择困难空间占用膨胀DDL操作变慢。

2026-04-23 20:00:57 455

原创 MySQL学习日记:关于MVCC及一些八股总结

MVCC是InnoDB引擎的一种并发控制机制,通过保存数据 的多个版本来管理事务之间的并发访问。它允许事务在读取数据时无需加锁,而是读取数据的历史快照,从而减少锁争用,提高并发性能,同时保证事务的隔离性。MVCC解决的问题:在高并发下,既要支持多事务并发操作,又尽量避免了因为锁竞争而导致的性能瓶颈。

2026-04-23 20:00:39 417

原创 MySQL常见八股:索引

一句话概括:当MySQL在使用联合索引时,查询条件必须从索引的最左列开始匹配。这是因为联合索引在B+树中的排列方式是"从左到右"的顺序。比如联合索引(first_name,last_name,age)会先按 first_name 排序,first_name 相同再按last_name 排序,last_name 相同再按 age 排序。MySQL 查找时会优先用first_name作为匹配依据,然后依次用last_name和 age。跳过最左侧字段,后面的列在B+树中是无序的,压根没法利用索引快速定位。

2026-04-21 20:40:08 430

原创 MySQL有哪些锁,他们各自的特点是什么?死锁是什么,产生的原因,如何避免

尽量避免在使用innodb引擎的表使用表锁,业务表锁的颗粒多太大,会影响并发性能,

2026-04-19 20:55:08 362

原创 MySQL:事务机制

事务是在MySQL引擎层实现的,常见的innodb是支持事务的,事务的四大特性是原子性,一致性,隔离性,持久性。当事务并发执行时,会引发脏读,不可重复读,幻读这些问题,为了避免这些问题,SQL提出了四种隔离级别,分别是读未提交,读已提交,可重复读,串行化,隔离级别一次递增,性能越差。要解决脏读问题,就要将隔离级别上升为读已提交以上级别。要解决不可重复读问题,就要将隔离级别升级到可重复读以上级别对于脏读,不建议将隔离级别升级到串行化,因为会导致数据库并发性能很差。

2026-04-18 20:41:02 488

原创 MySQL:count(1)与count(*)有什么区别,深分页问题

可以看出,当offset非0时,server层会从引擎层获取到很多无用的数据,而获取的这些无用数据都是要耗时的。mysql查询中 limit 1000,10 会比 limit 10 更慢。原因是 limit 1000,10 会取出1000+10条数据,并抛弃前1000条,这部分耗时更大。

2026-04-17 20:57:47 671

原创 20天速通LeetCode day08:关于栈

今日练习目的:掌握栈的核心特点后进先出,掌握队列核心特点先进先出。栈和队列是后续知识点的重要前置栈可以有效解决括号匹配的问题遇到左括号入栈,遇到右括号匹配栈顶元素最后判断栈是否为空用两个栈来解决嵌套问题countStack(数字栈):存储每个括号前面的重复次数kstirngStack(字符串栈):存储括号外点给钱已经累积的字符串。例如 “3[a2[c]]” → 内层 [ 前,已经累积 “a”,压入 “a”。遍历字符串,分情况处理遇到数字,累积到k遇到[,说明进入字串。

2026-04-17 19:10:05 363

原创 20天速通LeetCode day07:前缀和

今日练习目的:掌握前缀和思维。前缀和的核心价值是能实现在O(1)时间求区间和,是各类子数组问题的常用工具本题本质:通过前缀和+哈希表的方式。哈希表用来统计前缀和出现的次数本题有点像两数之和,都是用哈希表快速查找差值不同点在于两数之和是找出下标本题是统计出现的次数核心技巧:用前缀积记录左边乘积用后缀积记录右边乘积相乘即可得到每个位置除自身外的乘积优化空间:先存前缀积在 answer用一个变量 R 代替后缀积数组。

2026-04-16 11:31:26 254 1

原创 总结了最近GitHub上很火的26个skill,怎么还有张雪峰的事?

7. 博主.skill 把社媒语料转成可对话、风格改写的Persona Skill(支持推特、小红书)3. X导师.skill X/Twitter运营导师,分析账号数据、写推文、出诊断报告。22. 特朗普.skill 谈判风格、推文艺术、现实扭曲力场(复刻度极高)8. 蒸馏.skill(人格蒸馏引擎) 蒸馏自己、亲友,保留人格与记忆。25. 奇门遁甲、紫微斗数.skill 低幻觉、固定排盘的术数AI工具。14. 纳瓦尔.skill 财富、幸福、人生哲学(播客级智慧)

2026-04-16 10:44:55 1242

原创 20天速刷力扣 day06:二分查找

对于左闭右开的做法,有几注意点while中 left<rightright=mid上一题的变种,返回值类型不一样。本题返回目标值下标索引。题目要求:给定一个神仙古列表的整数数组nums和整数target要求:长出target在整数组中的起始和结束位置。因为本题需要用到两次二分查找方法,所以我们通过自己构造二分查找的方法来达到实现目标。掌握两次使用二分查找的思路,注意找到start与end的实现方法本题多了一个变量因素就是将数组翻转,导致数组不是递增的。

2026-04-15 19:53:33 196

原创 MySQL为什么抛弃了B树,选择B+树?(含面试回答)

在关于数据库的知识内容中,InnoDB存储引擎默认采用B+树作为索引结构,这是为什么,B+树与B树之间的差异是什么,回到开头的问题,为什么InnoDB存储索引使用B+树呢:磁盘IO次数最少。数据库的数据存在磁盘上,磁盘随机读写比内存慢10万倍。树矮。B+树是多叉树,一个节点能存几百上千给key。3层的B+树就能存两千多万跳数据,查任何一条最多3次磁盘IO。红黑树是二叉树,存同样的数据量要20多层。非叶子节点只存key和指针,不存数据。

2026-04-15 19:21:03 682

原创 (小林coding) MySQL:索引(保姆级漫画版)

本篇,我们从了解什么是索引开始,再到索引的具体分类:按数据结构分;物理存储分;字段特性分;字段个数分。然后理解了索引不是必须的,究竟什么时候需要,什么时候不需要索引?进一步了解了有什么方式能够对索引进行优化。

2026-04-13 20:09:45 825

原创 【Leet Code】滑动窗口

先思考一个问题:互动窗口的左右边界也是两个指针,也是一前一后一快一慢,滑动窗口和同向快慢指针核心区别在哪?快慢指针的操作对象仅限于指针指向的两个元素,而滑动窗口通常要对窗口内的区间做统计。通常依赖哈希表。暴力解法:注意双层for循环的边界要掌握本题的本质:掌握本题核心思路,注意left的更新细节掌握这道题,需要:掌握本题解法思路;判断计数数组中元素是否相等的实现办法;注意移除窗口左边元素字符的实现方法,牵扯到获得pCount与sCount的统计方法的不同。

2026-04-12 22:03:12 191

原创 一条SQL语句在MySQL中究竟发生了什么?执行全链路讲解

连接器:建立连接,管理连接、校验用户身份;查询缓存:查询语句如果命中查询缓存则直接返回,否则继续往下执行。MySQL 8.0 已删除该模块;解析 SQL:通过解析器对 SQL 查询语句进行词法分析、语法分析,然后构建语法树,方便后续模块读取表名、字段、语句类型;执行 SQL:执行 SQL 共有三个阶段:预处理阶段:检查表或字段是否存在;将select *中的符号扩展为表上的所有列。优化阶段:基于查询成本的考虑,选择查询成本最小的执行计划;

2026-04-12 21:43:24 768

原创 【LeetCode】哈希表

今日联系:掌握哈希表的高频使用方法,理解hashmap的优势1.查找更快2.天然去重:哈希表key唯一3.统计:经常被用于统计记住hash表的优势以及一些语法:.containsKey记住核心思路语法知识:map.computeIfAbsent(key,k->new ArrayList<>());等价于:if (!核心:哈希表 + 找起点 + 递增计数语法基础,理解本题思路流程,做出了就很流畅了。

2026-04-11 14:19:23 510

原创 【LeetCode】双指针:同向快慢针

今日练习目的:掌握两个指针通向遍历同一序列的解法,快针通常用于寻找目标,慢针用于记录写入位置要有快慢指针思想:同一个数组中寻找元素进阶写法:减少时间复杂度把非0往前放,同时把0自动丢到后面与上一题同样的思路直接return slow,slow即为新数组长度情况方法有序数组双指针无序数组HashSet无序 + 不允许额外空间排序 + 双指针掌握链表的语法详见核心思路。

2026-04-09 18:40:58 310

原创 【LeetCode Hot100】双指针:分离指针

本章学习目的:掌握两个指针分别遍历不同序列解法。这个解法通常用于两个序列之间做匹配,合并,插入,交换。双指针分别从后向前遍历两个数组。用双指针分别遍历两个字符串,通过比较字符是否相等来完成解答掌握字符串于数组之间转换的语法StringBuilder可变字符串类型添加append(charAt)本章学习的是双指针:分离指针一般都是定义多个指针,每一个指针遍历多个数组,进行判断或者拼接。

2026-04-08 16:46:08 353

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除