MySQL 优化总结
思路 第一步要做的是确定问题的症结,而不是一上来就看表结构和查询语句。 开启profiling MySQL默认会开启缓存池,本地调试的时候清除缓存的命令是:reset query cache。 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950MariaDB [(none)]> show variables like '%profi%'; +------------------------+-------+| Variable_name | Value |+------------------------+-------+| have_profiling | YES || profiling | OFF || profiling_history_size | 15 |+------------------------+-------+3 rows...
面试套路 - 操作系统
文件是如何组织的文件系统将硬盘空间以块为单位进行划分,每个文件占据若干个块,然后再通过一个文件控制块 FCB 记录每个文件占据的硬盘数据块。 这个文件控制块在Linux操作系统中就是inode,要想访问文件,就必须获得文件的inode信息,在inode中查找文件数据块索引表,根据索引中记录的硬盘地址信息访问硬盘,读写数据。 inode中记录着文件权限、所有者、修改时间和文件大小等文件属性信息,以及文件数据块硬盘地址索引。 RAID5将数据划分为N-1片,再利用N-1片数据进行位运算,得到一片校验数据,然后将这N片数据写入到N个硬盘。这样任何一块硬盘损坏都可以利用校验片的数据和其他片的数据进行计算得到丢失的那个数据,而硬盘的利用率也达到了N-1 / N。这样兼顾了磁盘利用率、读写速度和数据可用性,实际生产中用的最多。 RAID5中校验位的生成采用的是异或运算。所有数据的bit位,逐位进行异或,得到的就是校验位。如果丢失部分数据,用校验数据和其余数据逐位进行异或运算,可到丢失部分数据。举例,5块磁盘做RAID5,四块磁盘上的bit为:0 1 1 1 ,那么异或计算后,校验位为...
面试套路 - 数据库
辩证唯物主义告诉我们,事物发展轨迹是波浪式前进,螺旋式上升,有的时候似乎重新回到过去,但是却有了本质的区别和进步。 索引为啥索引能加快查询速度 索引其实也是一种空间换时间的思路。 数据库索引使用 B+ 树,B+ 树是一种 N 叉排序树,树的每个节点包含 N 个数据,这些数据按顺序排好,两个数据之间是一个指向子节点的指针,而子节点的数据则在这两个数据大小之间。 如上图所示:B+ 树的节点存储在磁盘上,每个节点存储 1000 多个数据,这样树的深度最多只要 4 层就可以存储数亿的数据。如果将树的根节点缓存在内存中,则最多只需要三次磁盘访问就可检索到需要的索引数据。 B 树和 B+ 树的区别:B 树的每个节点存储了记录的索引信息,而 B+ 树存储的是索引,只有在叶子节点存储的是全量的信息。并且 B+ 树在叶子节点有一个链表的结构,在范围查找的时候横向遍历会非常方便(不需要回溯到父节点再拓展向下)。 B+...
面试套路 - 消息队列
...
面试套路 - Web 安全
XSS 利用的是用户对网站的信任,CSRF 利用的是网站对用户的信任。 XSS跨站脚本攻击(Cross Site Scripting)其简称应该是 CSS,但是 CSS 与前端的样式表重叠了,所以改为 XSS,这个 X 其实是 Cross 的通用英文缩写。XSS 攻击的原理是数据变成了脚本,常用的探测方法就是<script>alert(1)</script>这一条如果能注入成功就能以 src 的方式注入外部脚本。 危害在常用的探测脚本中都是alert(1),弹个框能有啥用,还能上天不?答案是真的能上天: 获取页面数据(你看到的东西别人也能看到,偷取网站数据) 获取 Cookies(敏感信息泄露,例如登录态) 劫持前端逻辑(欺骗用户,本来应该做 A 操作的,结果点击按钮执行了 B) 发送请求 因此 XSS 是比较危险的。 分类 反射型:url 参数直接注入(http://example.com/search?q=<script>alert('XSS')</script>) 存储型:存储到 DB...
面试套路 - Redis
注意:缓存穿透(Cache Penetration) 和缓存击穿(Cache Breakdown) 的区别。穿透强调大量恶意请求根本不存在的数据,因为这个时候就好像没有缓存层,流量全部到 DB,影响整个系统;击穿就表示有缓存,但是热点 key 失效了,主要是针对的热点数据。穿透-DB无数据,击穿-DB有数据。 缓存穿透访问一个 DB 和缓存中都不存在的 key 时,请求会直接打到 DB 上,并且因为查不到数据,没法建立缓存,下一次请求还会打到 DB 上。这个时候缓存就像被“穿透”了一样,起不到任何作用,每次请求都会打到 DB 就好像没有缓存一样,大量这样的请求可能导致 DB 挂掉。 对于系统,假设一秒 5000 个请求,结果其中 4000 个请求是黑客发出的恶意攻击。黑客发出的那 4000个攻击,缓存中查不到,每次你去数据库里查,也查不到,举个栗子。数据库 id 是从 1 开始的,结果黑客发过来的请求 id...
面试套路 - js 基础
夫大人者,与天地合其德,与日月合其明,与四时合其序,与鬼神合其吉凶。——《周易》 在 JavaScript 中, (a == 1 && a == 2 && a == 3) 是否有可能为 true 参考解决思路:a是一个对象或函数,每次调用取值都不一样,以有序的规律变化就能实现多等 方案1:使用 getter1234567let temp = 1;Object.defineProperty(global, 'a', { get() { return temp++; }});console.log(a === 1 && a === 2 && a === 3); // true 方案2:重写valueOf/toString1234567const a = { value: 1, valueOf() { return this.value++; ...
面试套路 — Linux
弱小和无知不是生存的障碍,傲慢才是。 SHELL 所能支持的最大字符串的长度是 1024 字符。 删除文件是否需要对该文件具有写权限,为什么?删除文件不需要该文件的写权限,需要文件所在目录的写权限以及执行权限。因为删除文件修改的该文件父级即其所在目录的内容,所以需要目录的写权限。 同时,删除文件先要进入到目录,进入是目录的一个操作,所以需要该目录的执行操作。 文件描述符每次打开文件都会返回一个新的文件描述符,即使是针对的同一个文件,例如: 1234while (true) { const fd = require('fs').openSync('/','r'); console.log(fd);} 上述代码中每次都打开根目录(注意linux中的文件是泛指),最后肯定会由于打开的文件描述符(使用ulimit -n)过多而报错。 1234567891011121314Error: ENFILE: file table overflow, open '/' ...
一些想读的书
软件具有熵的特质,长期迭代维护的项目总会遇到可维护性逐渐降低的问题。 算法 算法新解 码农翻身 编码 图解 TCP/IP http 权威指南 计算机程序的构造和解释 我的第一本算法书 算法图解 素数之恋 啊哈·灵机一动 架构 《从零开始学架构》 《大型网站性能优化实践》 《深入高可用系统原理与设计》 @2025-04-06 redis Redis设计与实现 产品 硅谷产品-36讲直通世界级产品经理 用数据讲故事 硬战-人工智能时代的爆款产品 人人都是产品经理 2.0 阿里巴巴四十大道 吴军的谷歌方法论 《见识》吴军 科幻 人工智能简史 文学 天浴 房思琪的初恋乐园 过劳时代 生命3.0 经济学 《无节制消费的元凶》 《超级顾客》 《英国人的消费秘密》 《金钱与我》 《隐性亿万富翁》 《致富之道》 《亿万富翁们的饕餮盛宴》 《经济机器是如何运行的》 《聪明的投资者》 《漫步华尔街》 罐头是 1810 发明出来的,可是开罐器呢,却在 1858...
你真的会二分查找么
这几天刷LeetCode中二分查找相关的题目,思想总是没什么问题,总是被各种边界条件折磨地死去活来,提交1次错一次,完全是面向测试编程,好不容易把下标调整对了,可是当下次遇到这个题目的时候还是需要从头再错一边😿。我们先来看一下最朴素的二分查找,看看存在怎样的问题: 12345678910111213141516function binarySearch(arr, target) { let l = 0, r = arr.length - 1; while (l <= r) { const mid = (l + r) >> 1; const num = arr[mid]; if (target === num) { return mid; } if (target < num) { r = mid - 1; } else { l = mid + 1; } } return...