面试套路 - 数据库
辩证唯物主义告诉我们,事物发展轨迹是波浪式前进,螺旋式上升,有的时候似乎重新回到过去,但是却有了本质的区别和进步。 MySQL为啥索引能加快查询速度 索引其实也是一种空间换时间的思路。 数据库索引使用B+树,B+树是一种N叉排序树,树的每个节点包含N个数据,这些数据按顺序排好,两个数据之间是一个指向子节点的指针,而子节点的数据则在这两个数据大小之间。 如上图所示:B+树的节点存储在磁盘上,每个节点存储1000多个数据,这样树的深度最多只要4层就可以存储数亿的数据。如果将树的根节点缓存在内存中,则最多只需要三次磁盘访问就可检索到需要的索引数据。 B+树只是加快了索引的检索速度,如何通过索引加快数据库记录的查询速度呢? 数据库索引有两种,一种是聚簇索引,聚簇索引的数据库记录和索引存储在一起,上面这张图就是聚簇索引的示意图,在叶子节点,索引1和记录行r1存储在一起,查找到索引就是查找到数据库记录。像MySQL数据库的主键就是聚簇索引,主键ID和所在的记录行存储在一起。MySQL...
面试套路 - 消息队列
...
面试套路 - Web 安全
大纲 XSS CSRF Cookie安全性 点击劫持 传输安全问题 用户密码安全 SQL注入 信息泄露&社会工程学 XSS利用的是用户对网站的信任,CSRF利用的是网站对用户的信任。 XSS跨站脚本攻击(Cross Site...
面试套路 - Redis
缓存穿透访问一个 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 '/' at...
一些想读的书
软件具有熵的特质,长期迭代维护的项目总会遇到可维护性逐渐降低的问题。 算法新解 码农翻身(done) 编码(done) 图解TCP/IP(done) http权威指南 计算机程序的构造和解释 我的第一本算法书 算法图解 素数之恋 啊哈·灵机一动 架构 从零开始学架构 《大型网站性能优化实践》 redis Redis设计与实现(done) 产品 硅谷产品-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...
LeetCode 中的位运算
No136只出现1次的数字给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗? 使用计数器比较朴素的解法是对每个元素进行计数,最后统计出数量为1的那个数,这种算法比较通用,可以解决任意多元素出现任意次,因为可以解决的问题比较多,所以往往不是最好的算法,需要维护一个HashMap,占用O(N)的空间: 123456789101112var singleNumber = function (nums) { const counter = new Map(); for (const num of nums) { let count = counter.get(num) || 0; counter.set(num, ++count); } for (const [k, v] of counter) { if (v === 1) { return k; } ...
LeetCode No.55 跳跃游戏
给定一个非负整数数组,你最初位于数组的第一个位置。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个位置。 示例 1:输入: [2,3,1,1,4]输出: true解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。 示例 2:输入: [3,2,1,0,4]输出: false解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。 回溯法首先想到的是暴力法,针对每个位置可能走的步数一个个进行测试,如果这个步数能到达或者超过最后一个位置说明就可以到达,写代码的过程中注意将已经计算过的缓存起来,使用记忆化搜索防止重复计算。还可以从最大可能走的步数开始减少代替自增这样的小技巧来优化: 123456789101112131415161718192021222324252627282930313233var canJump = function (nums) { const cache = {}; /** *...