编程导航学习总结话题讨论

学习总结

209 参与
分享

快来分享你的内容吧~

点击登录,快来和大家讨论吧~
表情
图片
话题
打卡
综合
交流
文章
问答

为什么我努力了却没有进步?——看鱼皮东华大学分享后的反思

我是一名双非院校的软件专业学生,最近一直在学习编程,从Java SE、SpringBoot到前端三件套,投入了大量时间。我一直相信努力就会有回报,于是啃书、记笔记、刷题,用最勤奋的姿态对待学习。但结果往往是:书看了不少,真正掌握的却寥寥无几,这种付出与收获的落差让我感到迷茫。 今天看了鱼皮的一次大学经历分享,他的成长轨迹让我意识到,问题可能从一开始就出在了方向上——不是我不够努力,而是努力的方式本身存在根本性的缺陷。 这篇文章不是对鱼皮经历的总结,而是借他的故事,试图回答一个我困惑已久的问题:**同样是努力,差距究竟是从哪里开始拉开的?** --- **一、我们一直在用错误的标准衡量自己** 回想我学习的方式,买一本《Java核心技术》,从第一页开始啃,遇到不懂的反复看,力求每个知识点都理解透彻再往下走。表面上看,这是一种严谨、扎实的学习态度。但现在回头看,这种方式有一个致命的问题:**我不知道自己在为什么而学。** 书本上的知识是完整的、系统的,但也是静止的。它不会告诉你哪些是企业真正需要的,哪些是已经过时的,哪些你这辈子可能都用不上。你只是在按照书本的逻辑走,而不是按照现实的需求走。 鱼皮在讲座中提到一个细节:他确定学习方向的方式,不是看书的目录,而是直接去看大厂的招聘要求。你要进腾讯,就去腾讯官网看他们要求什么,一条一条对着学。这个方法听起来很功利,但本质上它做对了一件事——**把参照系从"书本"换成了"现实"。** 这两种参照系的差距,不是努力程度的差距,而是方向的差距。用错误的地图走路,走得再快也到不了目的地。 --- **二、永远在准备,永远没准备好** 学编程以来,我给自己定过很多计划。等我把Java SE学完,我就开始做项目。等我把SpringBoot搞懂,我就去找实习。等我把前端三件套掌握了,我就开始写自己的东西。 但那个"学完"的节点,似乎永远不会到来。 因为知识是无穷尽的。你学完Java SE,发现还有JVM没懂;学完SpringBoot,发现还有微服务没碰;学完前端三件套,发现还有框架没学。每往前走一步,就看到更大的一片未知,于是继续告诉自己:还没准备好,再等等。 鱼皮在大二暑假投简历的时候,他其实也没准备好。他学的东西很杂,项目经验几乎为零,投大厂全部石沉大海。但他还是去投了,去面了,挂了之后才真正知道自己缺什么。这种"挂一次"带来的信息量,比闭门啃三个月书要真实得多。 他后来说了一句话让我印象很深:**不要不敢投,只有投了之后你才会意识到自己哪里不足。** 普通人的逻辑是:准备好了再出发。鱼皮的逻辑是:出发了才知道要准备什么。 这两种逻辑看起来只是顺序不同,但结果天差地别。前者永远在原地等一个不会到来的"准备好",后者在真实的反馈中不断校准自己的方向。 --- **三、做着学,而不是学完再做** 前两个问题其实都指向同一个根源:**我们把"学"和"做"分成了两个阶段,而鱼皮从来没有。** 我学Java SE的方式是这样的:先看书,看完一章做笔记,整理知识点,然后继续看下一章。整个过程非常完整,非常系统,笔记也记得很漂亮。但学完之后,我发现我没办法用它做任何东西。那些知识点孤零零地躺在笔记本里,和现实世界之间没有任何连接。 鱼皮大一寒假学Python的方式完全不同。他不是找一本Python教材从头开始啃,而是因为春节抢红包对红包算法产生了好奇,然后想着能不能自己用Python实现一个。他带着一个具体的问题去学,遇到不会的地方再去搜,几十行代码写完,这个知识就真正进脑子了。 这两种方式的本质差距在于**反馈**。 啃书的反馈是模糊的。你以为自己看懂了,但你不知道自己是否真的懂了,因为没有任何东西来检验你。做项目的反馈是即时的、残酷的。代码跑不起来,报错了,功能实现不了,这些都在实时告诉你:你这里没学会,回去搞懂它。 这种反馈机制的差距,日积月累下来,就是两种人之间那道越来越宽的沟。 --- **四、2022年的鱼皮,对2026年的我说了什么** 鱼皮这场讲座录制于2022年,距今已经过去四年。看完之后,我提炼出了几点对我真正有触动的启发: **1. 好奇心是最强的学习引擎,AI是它的放大器** 鱼皮等红绿灯会思考这个设计合不合理,看B站的关注功能会想背后的逻辑是什么。他不是在刻意学习,而是对身边一切保持着"我能不能搞懂它、做得更好"的冲动。这种冲动才是他持续前进的真正动力,而不是自律,不是计划,不是焦虑。 在AI时代,好奇心的价值反而比以前更大了。鱼皮那个年代想实现一个想法,要自己查资料、看文档、一行行调试,门槛很高。但现在,一个念头冒出来,借助AI可以在几小时内跑出一个原型。好奇心的成本变低了,但好奇心本身却更值钱了。 所以我给自己定了一个具体的行动方向:对生活中任何觉得有意思、有问题、可以更好的东西,先自己想一想它背后的逻辑,然后用AI帮我实现它。 不求完整,不求完美,只求把那个一闪而过的好奇心接住,让它变成一段跑过的代码,而不是一个消散的念头。 **鱼皮用好奇心驱动自己走了很远,我想借助AI,走得更远。** **2. 先自己想,再用AI实现** 我现在用AI的方式有两个问题:遇到不会的直接问AI要答案,或者想到一个问题先问AI对不对,AI回答了就放下了。这两种方式都跳过了最重要的一步——**自己先想**。 AI是放大器,放大的是你已经有的思考,而不是替代你还没开始的思考。先想再用AI,积累的是自己的判断力;遇到问题直接问AI,积累的是对AI的依赖。四年积累下来,差距不是技术上的,而是思维上的。 鱼皮的思考在行动之前,我的思考在AI之后。这是我和他最大的差距,也是我最需要改变的一件事。 **我给自己定了三条具体的行动规则:** **第一条:遇到不会的,先硬着头皮想十分钟** 不是先去把那个知识点学完,而是先动手,哪怕完全不知道从哪里下手,先打开编辑器写点什么。十分钟之后你会发现,你真正不懂的东西比你以为的要少得多。 **第二条:用AI补缺口,而不是用AI代替思考** 遇到卡住的地方,先想清楚自己卡在哪里,把问题描述清楚,再去问AI。你描述问题的过程本身就是思考,而思考这件事,AI替代不了你。 **第三条:每学一个新东西,逼自己用它做一个哪怕很小的东西** 不求完整,不求完美。学了SpringBoot的某个功能,就用它写一个接口;看了某个前端组件,就把它放进一个页面里跑起来。让每个知识点都有一个对应的、跑过的代码。 --- **结语** 写完这篇文章,我终于能回答开头那个问题:差距不是从天赋开始拉开的,也不是从努力程度开始拉开的,而是从三个认知开始的——用错了参照系,等不来的准备好,以及把学和做永远分成两件事。 这些错误藏在我们从小被教导的学习习惯里,不容易察觉,但一旦看见,就很难再假装没看见。 鱼皮2022年的经历给我最大的启发,不是某个具体的方法,而是一种态度:**永远对身边的事保持好奇,永远把当下最重要的事做好。** 在AI时代,好奇心加上行动力,能走得比任何一个时代都远。 我现在最重要的一件事是考研。那些关于学习方式、好奇心、用AI放大思考的感悟,我先记在这里,等考完研,一条一条去落地。 想太远不是规划,是焦虑。眼下把这一件事做好,才是对未来最好的交代。

进程和线程、并发和并行、同步和异步的区别

## 一、进程和线程的区别 ### 1. 基本概念 **进程(Process)**:操作系统资源分配的基本单位,是程序在计算机中的一次执行过程。每个进程都有独立的内存空间、代码段、数据段和堆栈,进程之间相互隔离。 **线程(Thread)**:CPU调度的基本单位,是进程内的执行单元。同一进程内的多个线程共享进程的资源,但每个线程有独立的执行栈和程序计数器。 ### 2. 核心区别 | 维度 | 进程 | 线程 | |------|------|------| | **资源分配** | 资源分配的基本单位 | 资源调度的基本单位 | | **内存空间** | 独立地址空间 | 共享进程地址空间 | | **创建开销** | 大,需分配内存和资源 | 小,共享进程资源 | | **通信方式** | 进程间通信(IPC)复杂 | 直接读写共享内存 | | **独立性** | 高,一个进程崩溃不影响其他进程 | 低,线程崩溃可能影响整个进程 | | **切换开销** | 大,涉及页表切换 | 小,仅需保存和恢复寄存器 | ### 3. 关系示意图 ``` ┌─────────────────────────────────────────────┐ │ 操作系统 (OS) │ ├─────────────────────────────────────────────┤ │ ┌─────────────┐ ┌─────────────┐ │ │ │ 进程 A │ │ 进程 B │ │ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ │ │ │ 线程 A1 │ │ │ │ 线程 B1 │ │ │ │ │ ├─────────┤ │ │ ├─────────┤ │ │ │ │ │ 线程 A2 │ │ │ │ 线程 B2 │ │ │ │ │ └─────────┘ │ │ └─────────┘ │ │ │ │ 独立内存空间 │ │ 独立内存空间 │ │ │ └─────────────┘ └─────────────┘ │ └─────────────────────────────────────────────┘ ``` --- ## 二、并发和并行的区别 ### 1. 基本概念 **并发(Concurrency)**:在同一时间段内处理多个任务,通过时间片轮转或上下文切换实现。单核CPU也能实现并发。 **并行(Parallelism)**:在同一时刻同时执行多个任务,需要多核CPU支持。 ### 2. 核心区别 | 维度 | 并发 | 并行 | |------|------|------| | **执行方式** | 交替执行多个任务 | 同时执行多个任务 | | **硬件要求** | 单核CPU即可 | 需要多核CPU | | **关注点** | 任务切换效率 | 任务同时执行 | | **比喻** | 一个厨师同时处理多个订单 | 多个厨师同时处理多个订单 | ### 3. 示意图对比 **并发执行(单核CPU)**: ``` 时间轴 ─────────────────────────────────────────► 任务A: ████ ████ ████ ████ 任务B: ████ ████ ████ 任务C: ████ ████ ████ ████ ``` **并行执行(多核CPU)**: ``` 时间轴 ─────────────────────────────────────────► CPU核心1: ████████████████████ (任务A) CPU核心2: ████████████████████ (任务B) CPU核心3: ████████████████████ (任务C) ``` ### 4. 实际应用场景 - **并发**:Web服务器处理多个客户端请求 - **并行**:科学计算、图像处理等CPU密集型任务 --- ## 三、同步和异步的区别 ### 1. 基本概念 **同步(Synchronous)**:调用方必须等待被调用方执行完成才能继续执行,执行顺序是线性的。 **异步(Asynchronous)**:调用方发起调用后立即返回,无需等待被调用方完成,通过回调、事件或Promise获取结果。 ### 2. 核心区别 | 维度 | 同步 | 异步 | |------|------|------| | **执行顺序** | 顺序执行,阻塞等待 | 非阻塞,立即返回 | | **资源利用** | CPU空闲等待,效率低 | CPU可处理其他任务,效率高 | | **编程复杂度** | 简单,顺序思维 | 复杂,需处理回调/事件 | | **适用场景** | 简单任务、需要立即结果 | IO密集型任务、耗时操作 | ### 3. 执行流程对比 **同步调用**: ``` 调用方 ──► 执行任务 ──► 等待完成 ──► 获取结果 ──► 继续执行 ``` **异步调用**: ``` 调用方 ──► 发起任务 ──► 立即返回 ──► 继续执行其他任务 │ ▼ 后台执行任务 │ ▼ 完成后通知调用方(回调/事件) ``` ### 4. Java中的同步与异步示例 **同步代码**: ```java public void syncMethod() { String result = doSomething(); // 阻塞等待 processResult(result); // 等待完成后才执行 } ``` **异步代码**: ```java public void asyncMethod() { CompletableFuture.supplyAsync(this::doSomething) .thenAccept(this::processResult); // 立即返回,结果通过回调处理 doOtherWork(); // 无需等待,立即执行 } ``` --- ## 四、总结对比表 | 概念对 | 核心区别 | 关键词 | |--------|----------|--------| | **进程 vs 线程** | 资源分配 vs 资源调度 | 独立内存 vs 共享内存 | | **并发 vs 并行** | 交替执行 vs 同时执行 | 时间片轮转 vs 多核并行 | | **同步 vs 异步** | 阻塞等待 vs 非阻塞 | 顺序执行 vs 回调通知 | ### 一句话理解 - **进程**:程序的一次执行,有独立"房间" - **线程**:进程内的执行单元,共享"房间"资源 - **并发**:一个人同时处理多件事(快速切换) - **并行**:多个人同时处理多件事 - **同步**:做完一件再做下一件 - **异步**:先做别的,等结果出来再处理

SpringCloud学习总结

学习的核心板块 一、将单体架构拆分为微服务架构 1. 拆分原则 2. 服务调用 二、服务注册(注册中心)和 服务发现 1. Nacos注册中心 三、不同微服务之间通过openFeign进行远程调用(注册中心,负载均衡) 1. 编写OpenFeign客户端 2. 连接池 3. 最佳实践:抽取Feign客户端 4. 日志配置 四、网关路由 1. 路由过滤 五、网关登录校验 1. 网关过滤器:GatewayFilter路由过滤器 GlobalFilter全局过滤器 2. 自定义过滤器:自定义GatewayFilter路由过滤器 自定义GlobalFilter全局过滤器 3. 登录校验:JWT工具,登录校验过滤器(使用 自定义GlobalFilter全局过滤器) 4. 微服务获取用户信息 六、配置管理 1. 配置共享 2. 配置热更新(添加配置到Nacos) 3. 动态路由 七、微服务保护 1. 服务保护方案:请求限流,线程隔离,服务熔断 2. Sentinel实现流控,隔离,fallback,熔断 八、分布式事务 1. Seata分布式事务解决方案 2. 部署TC服务,微服务继承Seata(TC,TM,RM) 3. Seata的工作模式之:XA模式(等待,一起提交或者回滚) 4. Seata的工作模式之:AT模式(执行前先做备份,执行sql然后马上提交,全局事务成功删除备份,全局失败让备份数据生效,然后再删除备份事务。) 开心,之后也要继续加油!

春节假期马上就要结束,打工人准备复工啦~ 还记得往年春节,总爱立下许多 Flag,要看 xx 本书,做 xx 个项目,风风火火背了好几本书回家过年,年后又原原本本地带回来,书皮都没打开过。 今年因一些原因没回老家,最终留在上海过年,虽说少了些热闹,倒也格外清静,而且今年春节总算学了一丢丢东西,已是挺大的进步,索性简单做一个总结。 1. 金铲铲福星版本 青铜 => 大师 ✅(这个版本的赌狗阵容真好玩,可选性多,强度也很在线) 2. 怪物火车(肉鸽游戏)爽玩 ✅ (B 站刷视频被安利的游戏,通关了几次,每次通关后难度都骤升,后面打了一天都没通关,遂弃游) 3. 日常工作处理 ✅ 4. 粗看一遍《Vibe Coding 零基础入门教程》https://ai.codefather.cn/vibe ✅(对 Vibe Coding 有了更全面的了解,实操了几个小 demo,挺有意思的) 5. 看书《两晋悲歌》✅(挺喜欢这位博主讲的历史视频,于是找来他写的书看,索性当作小说读了) 6. 看书《段永平投资问答录》(80%,今天应该能读完了,前几年朋友就推荐的书,拖到最近才开始读,实在惭愧) 7. 每天睡午觉、每天晒太阳 ✅(假期过得格外悠闲) 8. 得到听书《薛兆丰的经济学课》(朗朗上口的开头语:薛兆丰的经济学课,只教你地道的经济学。结合一些小故事来讲解经济学知识,挺有意思的,不愧是得到榜一的课程,不过春节听得不多,前几天主要打游戏,后几天就专心看书了) 9. 还有一些年前制定的计划没完成(不纠结,接下来继续干就好) 虽然学到的内容不多,但相比前些年的春节,至少在学了。 另外大年初四到初七都去了图书馆,原以为没几个人,没想到每次下午到馆都没有自习的位置,下到 10 岁小儿写作业,上到 70 岁老头图书馆炒股。 好家伙,这些人咋这么闲,都不在家过年的吗? 随手记一记,发现自己比起刚毕业那几年,现在的学习积极性下降了挺多,也希望在新的一年里,能保持持续学习的能力,和大伙一起加油!

WebPack学习

webpack是Vue中涉及的一个知识点。现在项目多使用vite来代替webpack(在伙伴匹配项目中涉及到vite的使用) ## webpack的定义 webPack是一个模块加载器兼打包工具。他可以把各种资源(JS JSX ES6 图片) 作为模块来处理和使用 ## 安装webPack 1. 安装打包工具: npm install webpack -g 2. 安装客户端: npm install webpack-cli -g 3. 测试是否安装成功: webpack -v , webpack-cli -v ## 项目练习 webpack的使用步骤如下: 1. 创建一个项目 2. 创建一个叫modules的目录,用于放置JS模块等资源文件 3. 在modules下创建模块文件,如hello.js 用于编写JS模块相关的代码 ``` //暴露一个方法:sayHello: exports.sayHello=function(){ document.write("<h1>Vue基础笔记</h1>"); } ``` 4. 在modules下创建一个名字叫main.js的入口文件,用于打包时设置entry属性 ``` // require 导入一个模块,就可以调用这个模块中的方法了 var hello = require("/hello"); hello.sayHello();``` ``` 5. 在项目目录下创建webpack.config.js 配置文件,使用webpack命令打包(如果显示未找到webpack则以管理员身份运行webpack) ``` module.exports={ //进入路径 entry: "./modules/main.js", // 输出路径 output: { filename: "./js/budle.js" } } ``` 6. 在项目目录下创建HTML页面,如index.html, 导入webPack打包后的JS文件 ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue学习</title> </head> <body> <!--通过html文件就可以直接运行打包后的文件了--> <script src="dist/js/bundle.js"></script> </body> </html> ``` 7. 运行HTML查看效果 8. 最终效果的得到的感悟: 可以将打包后的js文件通过html启动,然后直接运行 9. 补充: 参数 --watch用于监听变化 :webpack --watch 背了5个新单词,复习了6个单词 周一作业已补完

2025年度总结

现在是2025年12.30晚上九点十九分,离图书馆闭馆还有约莫三四十分钟的时间 刚完成今天的八股任务 也没想到做点别的 刚好就趁着这段时间来回顾一下我即将过去的2025 “逝者如斯夫,不舍昼夜” 我一向是一个健忘的人 又或者是生活实在是没有波澜 总之我觉得好像去年的这个时候和在昨天差不多 于是翻开手机的相册 希冀能回忆起一些难忘 美好 和遗憾 嗯 一月还是在学校准备期末周 大一上的我还是很很很有干劲的 普遍都是七点多起床吧 或者是六点多 然后还是糖糖的短发 这里就不放照片了 [图片] 还有一张感觉还行的照片 考完试之后就溜了 回家 然后刚好过了几天去看望老师 然后还和另外一位同学一起给还是高一的学弟学妹讲高考填志愿这事 想来还是很帅的 之后老师还请我们大家一起吃了夜宵 很惬意 之后就是平淡摆烂的寒假 嗯 容我找个理由 家里面和广州比起来 实在是太冷了 所以我一上午都在被窝里面玩手机很合理吧 然后还每天挎个睡衣懒得换衣服 嘻嘻 不过希望今年能摆脱掉 毕竟我计划着初八的时候出来准备春招 (这也是为什么今年我有点一直拖着不想写总结的原因 作为一个稍微带着点完美主义的人,真的很想把这个任务在今年就完成) 然后过完寒假 一方面自己在投资领域上投入了一部分时间 不说学到吧 至少见识了很多东西 然后也选择了最朴实的道路 (这个稍微不方便透露) 然后我是大二上这个学期学的java吧 然后快期末的时候做的苍穹外卖 但是我想着做个苍穹外卖应该找不到工作 刚好家里面说回去考个驾照 就这么回去了 回家其实我原计划是准备学一下数据结构的 但是 好吧 夏天总不能说是家里面比广州冷很多吧 嗯但是我还是摆烂 了 (现在想来真想给自己两个巴掌) 不过驾照还是顺利的40天拿下了 之后就差不多开学了 开学学了一个月的数据结构 然后就基本保持一周一个项目的速度学 (算是囫囵吞枣吧 很多过的都很水 导致我现在准备春招要重新过一遍) 然后到了12月18号的时候 那时候刚好有个拿了腾讯等很多大厂offer的学长宣讲 然后我突然就被点醒自己是要准备实习了 (其实自己内心一直是觉得技术不到位作为借口 然后对实习稍微有点恐惧 但是 我潜意识里面一直是觉得大二的时候我就一定得找到实习的)所以这次被点醒之后 我做了规划 上文提到的我初八准备回学校弄春招 就是说这个 然后我刚好是凑巧吧 把初八的时间弄早了一个月 所以我规划里面是 提前了一个月的 也算是多给自己一个选择吧 1月26是下个月初八 刚好是期末考完过了一周 可能到时候会试试看能不能找到工作? 还有值得一提的是12月初的时候,看到朋友圈很多高中的好朋友都晒跑步数据 很厉害 然后想起自己挺久没跑步了的 然后开始跑 [图片] [图片] 当然还是很菜啦 不过一个月这个进度我自己觉得还行了 阅读方面 下半年少了很多 上半年还行 一共读了227个小时(虽然还没有我小说读得多 七猫统计都有425小时了) 今年这一路走来 还算勉强吧 选了java后端作为未来的职业发展方向 选了自己以后的投资策略 生活也没啥太大的压力 唯一的遗憾就是假期学的太少导致我找实习的进度慢了 零零碎碎记了一大笔流水账 先就这样吧 你好 2026 今年的目标是拿到字节的offer #2025年度总结

记录自己的学习过程

我认为知识是一定要系统化的学习,结构化梳理,这样在运用或思考的时候,能够回忆起自己在这一块梳理的知识结构,如果有记录那么能快速回忆并理解,如果没有记录,那么说明对自己来说超纲了,把知识进行分类,写入自己的知识库,那就对知识点有了一个快速的定位和理解。能够梳理清晰自己所学的知识,并定位知识点。这就是我认为系统化知识的意义。 我在学习过程中发现,我自己的思维方式和理解方式,想要学会和理解一个知识点,使用它是最快的方式,将这个知识点实战一次,就基本知道了这东西的作用。 * **使用层面** 1)起步入门:粗读是什么?有什么用?解决了什么问题? 怎么用?(来一个快速实战,上手做一做) 2)运用核心功能:也是基础功能,学习基础功能使用步骤以及基础知识点。 3)最佳实践:核心知识要实践,知识运用有无数种方式,最佳实践能避免错误的运用知识。理论是在原理层面指导实践。如果有最佳实践的总结,那便是最好的理论。比如:【关系型数据库设计理论】就是指导如何设计出高质量的关系型数据库。 4)小总结:技术优缺点,适用场景。 学到这里,我可以说我会用 CRUD 了。 当然仅仅会用是不够的,要想用的好、用的灵活,必须要知道它的内部结构和工作原理,比如MySQL ,如果仅仅停留在使用层面,那可能只会CRUD, 如果深入学习了MySQL 内部是B+树索引,二级索引等,那么在创建表时会酌情新增索引,毕竟每新增一个索引就要创建一棵新的B+树,另外在查询表的时候知道如何利用索引高效查询,如果了解MySQL内部有redo log ,DoubleWrtie pool , 就不那么担心 SQL 语句执行过程中断电的问题。知道了 buffer pool ,就明白 InnoDB 是有缓存的,缓存优先存储最常用的数据,这可能为编写SQL 带来一些便利,不过学习到最后明白了 MySQL 调优有限,不如 redis 或者业务优化来的更快更高效。 这便是深入学习和仅仅停留在使用层面的不同之处,我们想要用好一个技术,自然是要学习技术内部原理,明白技术内部是如何工作的,这就是我最喜欢的两个学习思维,学习技术**内部层次结构**和**工作流程**,这两个方面弄明白了,思维就通畅了。 以今天学到的 MySQL 为例,看看**内部层次结构**和**工作流程**。直接上图了 这是通用关系型数据库的内部结构图 ![](https://pic.code-nav.cn/post_picture/1625164612255182850/Bxc1rB09GVSujDDJ.webp) 这是MySQL 内部结构图 ![](https://pic.code-nav.cn/post_picture/1625164612255182850/0bJ21njFYsfzDyuu.webp) 这是 InnoDB 内部存储结构图 ![](https://pic.code-nav.cn/post_picture/1625164612255182850/DC073YoTFeeKMCb1.webp) 画出了这三张图,我基本上了解 MySQL 内部结构的全貌,当然以上的图并没有画出 MySQL 的所有结构,所有的部分,随着我对 MySQL 知识面的扩展,我会继续追加,这些图有助于我定位正在学习知识点属于 MySQL 结构的哪一个部分。比如 Doublewrite buffer, 将它定位到结构中,看三分钟文档我就理解了。 ![](https://pic.code-nav.cn/post_picture/1625164612255182850/02uJuImzLOppG9UZ.webp) 我另一个热爱的学习方式是工作流程,看看这玩意是咋工作的,就能把内部结构串起来,理解MySQL 各个结构的作用。当然它的工作流程不止一种,不同情况会有不同的工作流程,可能很多很复杂。不过我们先掌握正常运转的工作流程,意外情况掌握几个经典的~ 再拿 MySQL 举例,我们来看看工作原理: 左边红色的块是 Java 程序,集成了 MYSQL 驱动并且引用线程池,避免频繁创建和销毁连接带来的损耗。 中间是**发送网络请求**,java 应用发送的 SQL 语句的请求在 MySQL 中是由一个个的线程去处理的。 那么可以得出, 一个 SQL 请求会产生 **两个活跃的线程**:一个在 Java 应用侧等待/处理结果,一个在 MySQL 侧执行 SQL。 注意不是占用哈,占用的意思是拿着不放,活跃的线程是可以调度,切换,阻塞。 右边是MySQL 数据库,同样用一个连接池接收 SQL 请求,线程读取网络请求后在MySQL内部执行。 ![](https://pic.code-nav.cn/post_picture/1625164612255182850/VQfdG8Qz8LnhdvUp.webp) Java 程序通过网络请求将 SQL 语句字符串发送给 MySQL 服务后,我们看看MySQL 服务内部怎么处理。 ### 1. MYSQL 处理请求流程 * SQL 接口:MySQL 中处理请求的线程在获取到请求以后获取 SQL 语句去交给 SQL 接口去处理。 * SQL 解析器:他会将 SQL 接口传递过来的 SQL 语句进行解析,翻译成 MySQL 自己能认识的语言 * SQL 优化器:MySQL 会帮我去使用他自己认为的最好的方式去优化这条 SQL 语句,并生成一条条的执行计划 * 执行器:前面那些组件的操作最终必须通过执行器去调用存储引擎接口才能被执行 * 存储引擎:执行器会调用存储引擎的接口,去执行 SQL,也就是说真正执行 SQL 的动作是在存储引擎中完成的。 ![](https://pic.code-nav.cn/post_picture/1625164612255182850/6om1XCumafLO5zCR.webp) **接下来看看存储引擎做了什么!** ### 2. 存储引擎执行 SQL 流程 1)Buffer Pool (缓冲池)是 InnoDB 存储引擎中非常重要的内存结构, InnoDB 级别的缓存。缓冲池中的数据和数据库(磁盘)中的数据不一致时候,我们就认为缓存中的数据是**脏数据**, ![](https://pic.code-nav.cn/post_picture/1625164612255182850/tE2Bp2u6p5EodSGH.png) 2)undo 日志文件:记录数据被修改前的样子,事务回滚时发挥作用。我们程序是正常运作,这里仅仅记录。 ![](https://pic.code-nav.cn/post_picture/1625164612255182850/oybqXKsbBLaoy7Eg.png) 3)redo 日志文件:记录数据被修改后的样子,**redo 日志文件是 InnoDB 特有的,他是存储引擎级别的,不是 MySQL 级别的,**缓存池更新后记录到缓存日志中,缓存日志默认是立刻写入磁盘。缓存池数据是延迟。 ![](https://pic.code-nav.cn/post_picture/1625164612255182850/OQRAQtAhX4fZPjbW.png) InnoDB 目前整体执行流程: * 准备更新一条 SQL 语句 * MySQL(innodb)会先去缓冲池(BufferPool)中去查找这条数据,没找到就会去磁盘中查找,如果查找到就会将这条数据加载到缓冲池(BufferPool)中 * 在加载到 Buffer Pool 的同时,会将这条数据的原始记录保存到 undo 日志文件中 * innodb 会在 Buffer Pool 中执行更新操作 * 更新后的数据会记录在 redo log buffer 中 * MySQL 提交事务的时候,会将 redo log buffer 中的数据写入到 redo 日志文件中 刷磁盘可以通过 innodb_flush_log_at_trx_commit 参数来设置 * 值为 0 表示不刷入磁盘 * 值为 1 表示立即刷入磁盘 * 值为 2 表示先刷到 os cache * myslq 重启的时候会将 redo 日志恢复到缓冲池中 4) binlog : 记录整个操作过程,bin log 通过追加的方式记录,当文件大小大于给定值后,后续的日志会记录到新的文件上,bin log 适用于主从复制和数据恢复。 bin log 刷盘有三种模式 * **STATMENT :**基于 SQL 语句的复制(statement-based replication, SBR),每一条会修改数据的 SQL 语句会记录到 bin log 中 * **ROW:**基于行的复制(row-based replication, RBR),不记录每条SQL语句的上下文信息,仅需记录哪条数据被修改了 * **MIXED:**基于 STATMENT 和 ROW 两种模式的混合复制( mixed-based replication, MBR ),一般的复制使用 STATEMENT 模式保存 bin log ,对于 STATEMENT 模式无法复制的操作使用 ROW 模式保存 bin log ![](https://pic.code-nav.cn/post_picture/1625164612255182850/s6AJhyByQzEfH0am.png) 5) MySQL 会有一个后台线程,它会在某个时机从 Buffer Pool 中挑选出脏数据刷到 MySQL 数据库中 ![](https://pic.code-nav.cn/post_picture/1625164612255182850/qTM9CHIfVg3K8Mre.webp) 如果在数据被写入到bin log文件的时候,刚写完,数据库宕机了,数据会丢失吗? 首先可以确定的是,只要redo log最后没有 commit 标记,说明本次的事务一定是失败的。但是数据是没有丢失了,因为已经被记录到redo log的磁盘文件中了。在 MySQL 重启的时候,就会将 redo log 中的数据恢复(加载)到Buffer Pool中。 最后返回到查询执行器,经过封装后发回给调用的客户端。 **SQL 执行过程完~** 从这两个角度学习新技术,基本上就能掌握技术,但是并不能掌握高级使用场景,依靠上面的知识,做 MySQL 性能优化,如:慢SQL分析 、主从复制,读写分离、分库分表的场景,可能会手足无措。优化与主从属于 MySQL 的高阶用法、深入提升技术,这条路可能没有学习的上限,掌握经典场景即可,下面以分库分表场景举例,掌握了内部结构分层与技术原理后,凡是使用层面上的知识,都很简单了。 当使用分库分表,比如将数据库做了一个水平分库,把一个库分成多个库,这样的数据存在多个数据库中,在高并发场景下,对多个数据库读写肯定比对一个库读写要快不少,做一个性能优化,这是一种 MySQL 的高阶使用。 分库的代价是什么呢? 此时思维要切换到管理多个数据库带来了什么麻烦? 我们都知道 SQL 语句是在数据库中执行的,也就是说 SQL 中的 Order By 排序仅仅是对于单个数据库排序,而我的数据库有多个,这并不算是对我系统的全部数据排序。 另外还有 count(*) , `START TRANSACTION` 都会出现这种情况。这是第一个代价,管理数据库变得更复杂。 第二个代价,要把思维切换到存储数据层面,你能想到什么? ID 要保持唯一性,多个数据库就有可能发生 ID 重复,那么 ID 失去了唯一性还能叫 ID 吗?根据一个ID 查出两个人这合理吗?我不希望有人跟我的身份证同号呀,可想而知这个问题会带来多少麻烦。 问题的解决办法不加以探索了,我要学习一些更核心的知识,毕竟我还是太菜了。 这一套学习下来,我对MySQL 基础到高阶用法都接触到了,当然MySQL还有很多使用细节,配置细节,日后我会将其归纳成最佳使用实践去积累。 把知识体系比喻成一棵B+树,树已经建立起来了,往后新增知识那就是往树种插入新的索引或节点,依旧保持有条不紊

八月份的总结

【智能协同云图库项目结束!】这给了我一点信心,这个网站我是给我自己做的,源码就不分享了,因为没有值得学习的必要,我太菜了,后面域名www.justshoot.life如果备案好,希望各位大佬以宽容的心态来看待这个网站,毕竟这是我转码以后认认真真做的第一个项目,也很符合自己的需求。一句话:不容易但也做出来了。

day1 各位鱼友大家好啊,虽然今天确切的说并不是我第一天加入编程导航的第一天了,但是这毕竟是我第一次发布信息,我就估且算作第一天了。 分享一下我最近几天的学习心得吧 首先是我心态的转变,我是从去年秋天我大一开学我才逐渐了解到编程的,那时候我选择学了一点点python但除了会输出一点“hello world”之类的就别无进展了,后来我又听说了古老的C语言,我当时觉得很靠谱,能接近底层,我就觉得我学会C语言之后肯定能做很多,谁知道学着学着就不会了…… 我在番茄免费小说上看了很多与C语言有关的书(当然只是看看而已),行经典的C primer plus(第六版)中文书,看了一点虽然我看只有两千多页吧,但我感觉看了一点,它好像讲了很多,但其实啥也没记住,后来觉得看着太难受了就不看了,后来我又找到了小甲鱼写的《带你学C带你飞》这个我感觉看着还是很简单的,尤其是其中有很多的代码可以看和跟着写,一直到今年五一假期我又突发奇想,想发奋图强学好C语言了,于是把其中的代码又从头开始敲了,就边写边看,直到我写到结构体……五一假期的五天结束了,我感觉这样太难了,我学了这么久一直是反复的输入和输出,而且我感觉我就算熬到最后把C语言学完了也很难有明显的成果。 偶尔之下我加入了编程导航,觉得在这里我好像能学到更多的东西,想很多与AI有关的项目啊,后来我看了点项目开始介绍,我才知道万里长征还没有开始呢,这里大多项目似乎都是用JAVA语言写的,这对我来说就很难接受了,我TM的学了那么久的C语言就白学了(虽然我已经没多大动力去学C语言了,但突然就不学了我还是有点气闷的,毕竟我就会这么点东西,而且经过C语言的洗礼我终于懂得了学一门编程语言的困难),后来我还是想学点JAVA,看了几天关于韩顺平的视频,我觉得JAVA和C还是很像的(心里有点平复了,这么久的C没白学啊) 言归正传,聊聊我最近学习JAVA的主要内容,首先刚开始韩顺平讲了一点关于JAVA的历史吧,更重要的是我初步了解了JAVA语言编写的主要框架和几个常用的转义字符“/n /t”等,后来又讲了基本数据结构,有整型(int short byte long chat double float等),以及这些数据的用法和主要细节和一点存储知识,接着还有一些运算符(算数,关系,逻辑等)和进制转换的知识,还有选择分支和循环等,还有最近学的数组

下载 APP