├── 01.阿里篇 ├── .gitkeep ├── 1.1.1 如何实现一个高效的单向链表逆序输出?.md ├── 1.1.2 已知sqrt(2)约等于1.414,要求不用数学库,求sqrt(2)精确到小数点后10位.md ├── 1.1.3 给定一个二叉搜索树(BST),找到树中第 K 小的节点.md ├── 1.1.4 LRU缓存机制.md ├── 1.1.5 关于epoll和select的区别,以下哪些说法是正确的.md ├── 1.1.6 从innodb的索引结构分析,为什么索引的 key 长度不能太长.md ├── 1.1.7 MySQL的数据如何恢复到任意时间点?.md ├── 1.1.8 NFS与SMB的区别?.md ├── 1.1.9 输入 ping IP 后敲回车,发包前会发生什么?.md ├── 1.2.0 请解释下为什么鹿晗发布恋情的时候,微博系统会崩溃,如何解决?.md ├── 1.2.1 现有一批邮件需要发送给订阅顾客,且有一个集群(集群的节点数不定,会动态扩容缩容)来负责具体的邮件发送任务,如何让系统尽快地完成发送?.md ├── 1.2.2 有一批气象观测站,现需要获取这些站点的观测数据,并存储到 Hive 中。但是气象局只提供了 api 查询,每次只能查询单个观测点。那么如果能够方便快速地获取到所有的观测点的数据?.md ├── 1.2.3 如何实现两金额数据相加(最多小数点两位).md ├── 1.2.4 关于并行计算的一些基础开放问题.md ├── 1.2.5 请计算XILINX公司VU9P芯片的算力相当于多少TOPS,给出计算过程与公式.md ├── 1.2.6 一颗现代处理器,每秒大概可以执行多少条简单的MOV指令,有哪些主要的影响因素.md ├── 1.2.7 请分析 MaxCompute 产品与分布式技术的关系、当前大数据计算平台类产品的市场现状和发展趋势.md ├── 1.2.8 对大数据平台中的元数据管理是怎么理解的,元数据收集管理体系是怎么样的,会对大数据应用有什么样的影响.md ├── 1.2.9 你理解常见如阿里,和友商大数据平台的技术体系差异以及发展趋势和技术瓶颈,在存储和计算两个方面进行概述.md ├── 1.3.0 在云计算大数据处理场景中,每天运行着成千上万的任务,每个任务都要进行 IO 读写.md ├── 1.3.1 最大频率栈.md ├── 1.3.2 给定一个链表,删除链表的倒数第N个节点,并且返回链表的头结点.md ├── 1.3.3 如果让你设计一个通用的、支持各种数据库秒级备份和恢复的系统,你会如何设计.md ├── 1.3.4 如果让你来设计一个支持数据库、NOSQL 和大数据之间数据实时流动的数据流及处理的系统,你会考虑哪些问题?如何设计?.md ├── 1.3.5 给定一个整数数组和一个整数,返回两个数组的索引,这两个索引指向的数字的加和等于指定的整数。需要最优的算法,分析算法的空间和时间复杂度.md ├── 1.3.6 假如给你一个新产品,你将从哪些方面来保障它的质量?.md ├── 1.3.7 请评估一下程序的执行结果?.md ├── 1.3.8 如何测试一辆自行车.md └── 1.3.9 如何判断两个链表是否相交.md ├── 02.华为篇 ├── .gitkeep ├── 2.1.1 static有什么用途?(请至少说明两种).md ├── 2.1.2 引用与指针有什么区别?.md ├── 2.1.3 描述实时系统的基本特性.md ├── 2.1.4 全局变量和局部变量在内存中是否有区别?如果有,是什么区别?.md ├── 2.1.5 什么是平衡二叉树?.md ├── 2.1.6 堆栈溢出一般是由什么原因导致的?.md ├── 2.1.7 什么函数不能声明为虚函数?.md ├── 2.1.8 冒泡排序算法的时间复杂度是什么?.md ├── 2.1.9. Internet采用哪种网络协议?该协议的主要层次结构?.md ├── 2.2.0 IP地址的编码分为哪俩部分?.md ├── 2.2.1 用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序.md └── 2.2.2 某32位系统下, C++程序,请计算sizeof 的值.md ├── 03.百度篇 ├── .gitkeep ├── 3.4.8 找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数。.md └── 3.4.9 找出被修改过的数字.md ├── 04.腾讯篇 └── .gitkeep ├── 05.美团篇 ├── .gitkeep └── 5.2.0 浅复制和深复制?怎样实现深复制?.md ├── 06.头条篇 ├── .gitkeep └── 一棵二叉树,求最大通路长度(即最大左右子树高度之和).md ├── 07.滴滴篇 └── .gitkeep ├── 08.京东篇 ├── .gitkeep └── 简单说一下hadoop和spark的shuffle过程.md ├── 09.MySQL篇 ├── .gitkeep ├── 9.1.0 主键 超键 候选键 外键.md ├── 9.1.1 数据库事务的四个特性及含义.md ├── 9.1.2 视图的作用,视图可以更改么?.md ├── 9.1.3 drop,delete与truncate的区别.md ├── 9.1.4 索引的工作原理及其种类.md ├── 9.1.5 连接的种类.md ├── 9.1.6 数据库范式.md ├── 9.1.7 数据库优化的思路.md ├── 9.1.8 存储过程与触发器的区别.md └── 9.1.9 解释 SQL 的 left join 和 right join.md ├── 10.Redis篇 ├── .gitkeep ├── 10.1.0 使用Redis有哪些好处?.md ├── 10.1.1 redis相比memcached有哪些优势?.md ├── 10.1.2 redis常见性能问题和解决方案.md ├── 10.1.3 MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据.md ├── 10.1.3 zookeeper的四种类型的znode.md ├── 10.1.4 Memcache与Redis的区别都有哪些?.md ├── 10.1.5 Redis 常见的性能问题都有哪些?如何解决?.md ├── 10.1.6 redis最适合的场景.md ├── 10.1.7 Redis的同步机制了解么?.md └── 10.1.8 是否使用过Redis集群,集群的原理是什么?.md ├── 11.MongoDB篇 ├── .gitkeep ├── 11.1.0 什么是MongoDB?.md ├── 11.1.1 MongoDB是由哪种语言写的?.md ├── 11.1.2 MongoDB的优势有哪些?.md ├── 11.1.3 什么是数据库?.md ├── 11.1.4 什么是集合?.md ├── 11.1.5 什么是文档?.md ├── 11.1.6 MongoDB和关系型数据库术语对比图.md ├── 11.1.7 什么是“mongod”?.md ├── 11.1.8 “mongod”参数有什么?.md ├── 11.1.9 什么是“mongo”?.md ├── 11.2.0 MongoDB哪个命令可以切换数据库?.md ├── 11.2.1 什么是非关系型数据库?.md ├── 11.2.2 非关系型数据库有哪些类型?.md ├── 11.2.3 为什么用MOngoDB?.md ├── 11.2.4 在哪些场景使用MongoDB?.md ├── 11.2.5 MongoDB中的命名空间是什么意思.md ├── 11.2.6 哪些语言支持MongoDB.md ├── 11.2.7 在MongoDB中如何创建一个新的数据库?.md ├── 11.2.8 在MongoDB中如何查看数据库列表?.md ├── 11.2.9 MongoDB中的分片是什么意思?.md ├── 11.3.0 如何查看使用MongoDB的连接?.md ├── 11.3.1 什么是复制?.md ├── 11.3.2 在MongoDB中如何在集合中插入一个文档?.md ├── 11.3.3 在MongoDB中如何除去一个数据库?.md ├── 11.3.4 在MongoDB中如何创建一个集合?.md ├── 11.3.5 在MongoDB中如何查看一个已经创建的集合?.md ├── 11.3.6 在MongoDB中如何删除一个集合?.md ├── 11.3.7 为什么要在MongoDB中使用分析器?.md ├── 11.3.8 MongoDB支持主键外键关系吗?.md ├── 11.3.9 MongoDB支持哪些数据类型?.md ├── 11.4.0 为什么要在MongoDB中用Code数据类型?.md ├── 11.4.1 为什么要在MongoDB中用Regular Expression数据类型?.md ├── 11.4.2 为什么在MongoDB中使用Object ID数据类型?.md ├── 11.4.3 如何在集合中插入一个文档?.md ├── 11.4.4 “ObjectID”有哪些部分组成?.md ├── 11.4.5 在MongoDb中什么是索引?.md ├── 11.4.6 如何添加索引?.md ├── 11.4.7 MongoDB有哪些可替代产品?.md ├── 11.4.8 如何查询集合中的文档?.md ├── 11.4.9 用什么方法可以格式化输出结果?.md ├── 11.5.0 如何使用AND或OR条件循环查询集合中的文档?.md ├── 11.5.1 在MongoDB中如何更新数据?.md ├── 11.5.2 如何删除文档?.md ├── 11.5.3 在MongoDB中如何排序?.md ├── 11.5.4 什么是聚合?.md ├── 11.5.5 在MongoDB中什么是副本集?.md └── 11.5.6 Mongodb存储特性与内部原理.md ├── 12.Zookeeper篇 ├── .gitkeep ├── 12.1.0 zookeeper是什么?.md ├── 12.1.1 zookeeper提供了什么?.md ├── 12.1.2 zookeeper文件系统.md ├── 12.1.3 zookeeper的四种类型的znode.md ├── 12.1.4 zookeeper通知机制.md ├── 12.1.5 zookeeper有哪些应用场景?.md ├── 12.1.6 zk的命名服务.md ├── 12.1.7 zk的配置管理服务.md ├── 12.1.8 zk的集群管理.md ├── 12.1.9 zk的分布式锁.md ├── 12.2.0 zk队列管理.md ├── 12.2.1 zk数据复制.md ├── 12.2.2 zk中zab的工作原理.md ├── 12.2.3 zk是如何保证事务的顺序一致性.md ├── 12.2.4 zk集群下server工作状态.md ├── 12.2.5 zk是如何选举Leader的?.md ├── 12.2.6 zk同步流程.md ├── 12.2.7 分布式通知和协调.md ├── 12.2.8 zk的session机制.md ├── zk_distributed_locker1.png ├── zk_distributed_locker2.png ├── zk_sync.png ├── zk_zab_basic_paxos.png └── zk_zab_fast_paxos.png ├── 13.Nginx篇 └── .gitkeep ├── 14.算法篇 └── .gitkeep ├── 15.内存篇 └── .gitkeep ├── 16.CPU篇 └── .gitkeep ├── 17.磁盘篇 └── .gitkeep ├── 18.网络通信篇 └── .gitkeep ├── 19.安全篇 └── .gitkeep ├── 20.并发篇 └── .gitkeep ├── 2023adding.md ├── 21.面经 └── 2020秋招面经总结.md ├── README.md ├── arch.jpg ├── contact.jpg └── sync_link /01.阿里篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/01.阿里篇/.gitkeep -------------------------------------------------------------------------------- /01.阿里篇/1.1.1 如何实现一个高效的单向链表逆序输出?.md: -------------------------------------------------------------------------------- 1 | ##### **问题**:如何实现一个高效的单向链表逆序输出? 2 | 3 | ##### **出题人**:阿里巴巴出题专家:昀龙/阿里云弹性人工智能负责人 4 | 5 | ##### **参考答案**:下面是其中一种写法,也可以有不同的写法,比如递归等。供参考。 6 | 7 | 8 | ``` 9 | typedef struct node{ 10 | int data; 11 | struct node* next; 12 | node(int d):data(d), next(NULL){} 13 | }node; 14 | 15 | void reverse(node* head) 16 | { 17 | if(head == NULL){ 18 | return; 19 | } 20 | 21 | node* pleft = NULL; 22 | node* pcurrent = head; 23 | node* pright = head->next; 24 | 25 | while(pright){ 26 | pcurrent->next = pleft; 27 | node *ptemp = pright->next; 28 | pright->next = pcurrent; 29 | pleft = pcurrent; 30 | pcurrent = pright; 31 | pright = ptemp; 32 | } 33 | 34 | while(pcurrent != NULL){ 35 | cout<< pcurrent->data << "\t"; 36 | pcurrent = pcurrent->next; 37 | } 38 | } 39 | 40 | ``` 41 | 42 | ``` java 43 | class Solution { 44 | 45 | public void reverse(ListNode head) { 46 | if (head == null || head.next == null) { 47 | return ; 48 | } 49 | ListNode currentNode = head; 50 | Stack> stack = new Stack<>(); 51 | while (currentNode != null) { 52 | stack.push(currentNode); 53 | ListNode tempNode = currentNode.next; 54 | currentNode.next = null; // 断开连接 55 | currentNode = tempNode; 56 | } 57 | 58 | head = stack.pop(); 59 | currentNode = head; 60 | 61 | while (!stack.isEmpty()) { 62 | currentNode.next = stack.pop(); 63 | currentNode = currentNode.next; 64 | } 65 | } 66 | } 67 | 68 | class ListNode{ 69 | T val; 70 | public ListNode(T val) { 71 | this.val = val; 72 | } 73 | ListNode next; 74 | } 75 | ``` 76 | -------------------------------------------------------------------------------- /01.阿里篇/1.1.2 已知sqrt(2)约等于1.414,要求不用数学库,求sqrt(2)精确到小数点后10位.md: -------------------------------------------------------------------------------- 1 | #### **题目**:已知 sqrt (2)约等于 1.414,要求不用数学库,求 sqrt (2)精确到小数点后 10 位。 2 | #### **出题人**:——阿里巴巴出题专家:文景/阿里云 CDN 资深技术专家 3 | #### **参考答案**: 4 | #### * 考察点 5 | 6 | 1. 基础算法的灵活应用能力(二分法学过数据结构的同学都知道,但不一定往这个方向考虑;如果学过数值计算的同学,应该还要能想到牛顿迭代法并解释清楚) 7 | 2. 退出条件设计 8 | 9 | #### 二分法 10 | ##### 1. 已知 sqrt(2)约等于 1.414,那么就可以在(1.4, 1.5)区间做二分 11 | 查找,如: 12 | a) high=>1.5 13 | b) low=>1.4 14 | c) mid => (high+low)/2=1.45 15 | d) 1.45*1.45>2 ? high=>1.45 : low => 1.45 16 | e) 循环到 c) 17 | 18 | ##### 2. 退出条件 19 | a) 前后两次的差值的绝对值<=0.0000000001, 则可退出 20 | 21 | ``` 22 | const double EPSILON = 0.0000000001; 23 | 24 | double sqrt2() { 25 | double low = 1.4, high = 1.5; 26 | double mid = (low + high) / 2; 27 | 28 | while (high - low > EPSILON) { 29 | if (mid * mid > 2) { 30 | high = mid; 31 | } else { 32 | low = mid; 33 | } 34 | mid = (high + low) / 2; 35 | } 36 | 37 | return mid; 38 | } 39 | ``` 40 | 41 | #### 牛顿迭代法 42 | ##### 1.牛顿迭代法的公式为: 43 | xn+1 = xn-f(xn)/f'(xn) 44 | 45 | 对于本题,需要求解的问题为:f(x)=x2-2 的零点 46 | ``` 47 | EPSILON = 0.1 ** 10 48 | def newton(x): 49 | if abs(x ** 2 - 2) > EPSILON: 50 | return newton(x - (x ** 2 - 2) / (2 * x)) 51 | else: 52 | return x 53 | ``` -------------------------------------------------------------------------------- /01.阿里篇/1.1.3 给定一个二叉搜索树(BST),找到树中第 K 小的节点.md: -------------------------------------------------------------------------------- 1 | #### **题目**:给定一个二叉搜索树(BST),找到树中第 K 小的节点。 2 | #### **出题人**:阿里巴巴出题专家:文景/阿里云 CDN 资深技术专家 3 | #### **参考答案**: 4 | 5 | ##### * 考察点 6 | 1. 基础数据结构的理解和编码能力 7 | 2. 递归使用 8 | 9 | ##### * 示例 10 | ``` 11 | 5 12 | / \ 13 | 3 6 14 | / \ 15 | 2 4 16 | / 17 | 1 18 | 19 | ``` 20 | 说明:保证输入的 K 满足 1<=K<=(节点数目) 21 | 22 | 解法1:树相关的题目,第一眼就想到递归求解,左右子树分别遍历。联想到二叉搜索树的性质,root 大于左子树,小于右子树,如果左子树的节点数目等于 K-1,那么 root 就是结果,否则如果左子树节点数目小于 K-1,那么结果必然在右子树,否则就在左子树。因此在搜索的时候同时返回节点数目,跟 K 做对比,就能得出结果了。 23 | 24 | ``` 25 | /** 26 | * Definition for a binary tree node. 27 | **/ 28 | 29 | public class TreeNode { 30 | int val; 31 | TreeNode left; 32 | TreeNode right; 33 | TreeNode(int x) { val = x; } 34 | } 35 | 36 | class Solution { 37 | private class ResultType { 38 | 39 | boolean found; // 是否找到 40 | 41 | int val; // 节点数目 42 | ResultType(boolean found, int val) { 43 | this.found = found; 44 | this.val = val; 45 | } 46 | } 47 | 48 | public int kthSmallest(TreeNode root, int k) { 49 | return kthSmallestHelper(root, k).val; 50 | } 51 | 52 | private ResultType kthSmallestHelper(TreeNode root, int k) { 53 | if (root == null) { 54 | return new ResultType(false, 0); 55 | } 56 | 57 | ResultType left = kthSmallestHelper(root.left, k); 58 | 59 | // 左子树找到,直接返回 60 | if (left.found) { 61 | return new ResultType(true, left.val); 62 | } 63 | 64 | // 左子树的节点数目 = K-1,结果为 root 的值 65 | if (k - left.val == 1) { 66 | return new ResultType(true, root.val); 67 | } 68 | 69 | // 右子树寻找 70 | ResultType right = kthSmallestHelper(root.right, k - left.val - 1); 71 | if (right.found) { 72 | return new ResultType(true, right.val); 73 | } 74 | 75 | // 没找到,返回节点总数 76 | return new ResultType(false, left.val + 1 + right.val); 77 | } 78 | } 79 | 80 | ``` 81 | 82 | 解法2:基于二叉搜索树的特性,在中序遍历的结果中,第k个元素就是本题的解。 83 | 最差的情况是k节点是bst的最右叶子节点,不过`每个节点的遍历次数最多是1次`。 84 | 遍历并不是需要全部做完,使用计数的方式,找到第k个元素就可以退出。 85 | 下面是go的一个简单实现。 86 | 87 | ``` 88 | // BST is binary search tree 89 | type BST struct { 90 | key, value int 91 | left, right *BST 92 | } 93 | 94 | func (bst *BST) setLeft(b *BST) { 95 | bst.left = b 96 | } 97 | 98 | func (bst *BST) setRight(b *BST) { 99 | bst.right = b 100 | } 101 | 102 | // count 查找bst第k个节点的值,未找到就返回0 103 | func count(bst *BST, k int) int { 104 | if k < 1 { 105 | return 0 106 | } 107 | 108 | c := 0 109 | ok, value := countRecursive(bst, &c, k) 110 | 111 | if ok { 112 | return value 113 | } 114 | 115 | return 0 116 | } 117 | 118 | // countRecurisive 对bst使用中序遍历 119 | // 用计数方式控制退出遍历,参数c就是已遍历节点数 120 | func countRecursive(bst *BST, c *int, k int) (bool, int) { 121 | if bst.left != nil { 122 | ok, value := countRecursive(bst.left, c, k) 123 | if ok { 124 | return ok, value 125 | } 126 | } 127 | 128 | if *c == k-1 { 129 | return true, bst.value 130 | } 131 | 132 | *c++ 133 | 134 | if bst.right != nil { 135 | ok, value := countRecursive(bst.right, c, k) 136 | if ok { 137 | return ok, value 138 | } 139 | } 140 | 141 | return false, 0 142 | } 143 | 144 | // 下面是测试代码,覆盖了退化的情况和普通bst 145 | 146 | func createBST1() *BST { 147 | b1 := &BST{key: 1, value: 10} 148 | b2 := &BST{key: 2, value: 20} 149 | b3 := &BST{key: 3, value: 30} 150 | b4 := &BST{key: 4, value: 40} 151 | b5 := &BST{key: 5, value: 50} 152 | b6 := &BST{key: 6, value: 60} 153 | b7 := &BST{key: 7, value: 70} 154 | b8 := &BST{key: 8, value: 80} 155 | b9 := &BST{key: 9, value: 90} 156 | 157 | b9.setLeft(b8) 158 | b8.setLeft(b7) 159 | b7.setLeft(b6) 160 | b6.setLeft(b5) 161 | b5.setLeft(b4) 162 | b4.setLeft(b3) 163 | b3.setLeft(b2) 164 | b2.setLeft(b1) 165 | 166 | return b9 167 | } 168 | 169 | func createBST2() *BST { 170 | b1 := &BST{key: 1, value: 10} 171 | b2 := &BST{key: 2, value: 20} 172 | b3 := &BST{key: 3, value: 30} 173 | b4 := &BST{key: 4, value: 40} 174 | b5 := &BST{key: 5, value: 50} 175 | b6 := &BST{key: 6, value: 60} 176 | b7 := &BST{key: 7, value: 70} 177 | b8 := &BST{key: 8, value: 80} 178 | b9 := &BST{key: 9, value: 90} 179 | 180 | b1.setRight(b2) 181 | b2.setRight(b3) 182 | b3.setRight(b4) 183 | b4.setRight(b5) 184 | b5.setRight(b6) 185 | b6.setRight(b7) 186 | b7.setRight(b8) 187 | b8.setRight(b9) 188 | 189 | return b1 190 | } 191 | 192 | func createBST3() *BST { 193 | b1 := &BST{key: 1, value: 10} 194 | b2 := &BST{key: 2, value: 20} 195 | b3 := &BST{key: 3, value: 30} 196 | b4 := &BST{key: 4, value: 40} 197 | b5 := &BST{key: 5, value: 50} 198 | b6 := &BST{key: 6, value: 60} 199 | b7 := &BST{key: 7, value: 70} 200 | b8 := &BST{key: 8, value: 80} 201 | b9 := &BST{key: 9, value: 90} 202 | 203 | b5.setLeft(b3) 204 | b5.setRight(b7) 205 | b3.setLeft(b2) 206 | b3.setRight(b4) 207 | b2.setLeft(b1) 208 | b7.setLeft(b6) 209 | b7.setRight(b8) 210 | b8.setRight(b9) 211 | 212 | return b5 213 | } 214 | 215 | func createBST4() *BST { 216 | b := &BST{key: 1, value: 10} 217 | last := b 218 | 219 | for i := 2; i < 100000; i++ { 220 | n := &BST{key: i, value: i * 10} 221 | last.setRight(n) 222 | 223 | last = n 224 | } 225 | 226 | return b 227 | } 228 | 229 | func createBST5() *BST { 230 | b := &BST{key: 99999, value: 999990} 231 | last := b 232 | 233 | for i := 99998; i > 0; i-- { 234 | n := &BST{key: i, value: i * 10} 235 | last.setLeft(n) 236 | 237 | last = n 238 | } 239 | 240 | return b 241 | } 242 | 243 | func createBST6() *BST { 244 | b := &BST{key: 50000, value: 500000} 245 | last := b 246 | 247 | for i := 49999; i > 0; i-- { 248 | n := &BST{key: i, value: i * 10} 249 | last.setLeft(n) 250 | 251 | last = n 252 | } 253 | 254 | last = b 255 | 256 | for i := 50001; i < 100000; i++ { 257 | n := &BST{key: i, value: i * 10} 258 | last.setRight(n) 259 | 260 | last = n 261 | } 262 | 263 | return b 264 | } 265 | 266 | func TestK(t *testing.T) { 267 | bst1 := createBST1() 268 | bst2 := createBST2() 269 | bst3 := createBST3() 270 | bst4 := createBST4() 271 | 272 | check(t, bst1, 1, 10) 273 | check(t, bst1, 2, 20) 274 | check(t, bst1, 3, 30) 275 | check(t, bst1, 4, 40) 276 | check(t, bst1, 5, 50) 277 | check(t, bst1, 6, 60) 278 | check(t, bst1, 7, 70) 279 | check(t, bst1, 8, 80) 280 | check(t, bst1, 9, 90) 281 | 282 | check(t, bst2, 1, 10) 283 | check(t, bst2, 2, 20) 284 | check(t, bst2, 3, 30) 285 | check(t, bst2, 4, 40) 286 | check(t, bst2, 5, 50) 287 | check(t, bst2, 6, 60) 288 | check(t, bst2, 7, 70) 289 | check(t, bst2, 8, 80) 290 | check(t, bst2, 9, 90) 291 | 292 | check(t, bst3, 1, 10) 293 | check(t, bst3, 2, 20) 294 | check(t, bst3, 3, 30) 295 | check(t, bst3, 4, 40) 296 | check(t, bst3, 5, 50) 297 | check(t, bst3, 6, 60) 298 | check(t, bst3, 7, 70) 299 | check(t, bst3, 8, 80) 300 | check(t, bst3, 9, 90) 301 | 302 | check(t, bst4, 1, 10) 303 | check(t, bst4, 2, 20) 304 | check(t, bst4, 3, 30) 305 | check(t, bst4, 4, 40) 306 | check(t, bst4, 5, 50) 307 | check(t, bst4, 6, 60) 308 | check(t, bst4, 7, 70) 309 | check(t, bst4, 8, 80) 310 | check(t, bst4, 9, 90) 311 | 312 | check(t, bst4, 99991, 999910) 313 | check(t, bst4, 99992, 999920) 314 | check(t, bst4, 99993, 999930) 315 | check(t, bst4, 99994, 999940) 316 | check(t, bst4, 99995, 999950) 317 | check(t, bst4, 99996, 999960) 318 | check(t, bst4, 99997, 999970) 319 | check(t, bst4, 99998, 999980) 320 | check(t, bst4, 99999, 999990) 321 | } 322 | 323 | func check(t *testing.T, b *BST, k, value int) { 324 | t.Helper() 325 | 326 | checkCall(t, b, k, value, count) 327 | // 此处可添加其他解法的实现 328 | } 329 | 330 | func checkCall(t *testing.T, b *BST, k, value int, find func(bst *BST, kth int) int) { 331 | t.Helper() 332 | 333 | got := find(b, k) 334 | if got != value { 335 | t.Fatalf("want:%d, got:%d", value, got) 336 | } 337 | } 338 | ``` 339 | -------------------------------------------------------------------------------- /01.阿里篇/1.1.4 LRU缓存机制.md: -------------------------------------------------------------------------------- 1 | **题目**:LRU 缓存机制 2 | 设计和实现一个 LRU(最近最少使用)缓存数据结构,使它应该支持一下操作:get 和 put。 3 | get(key) - 如果 key 存在于缓存中,则获取 key 的 value(总是正数),否则返回 -1。 4 | put(key,value) - 如果 key 不存在,请设置或插入 value。当缓存达到其容量时,它应该在插入新项目之前使最近最少使用的项目作废。 5 | 6 | **出题人**:文景/阿里云 CDN 资深技术专家 7 | 8 | **参考答案**: 9 | 10 | python版本的: 11 | 12 | ``` 13 | class LRUCache(object): 14 | def __init__(self, capacity): 15 | """ 16 | :type capacity: int 17 | """ 18 | self.cache = {} 19 | self.keys = [] 20 | self.capacity = capacity 21 | 22 | def visit_key(self, key): 23 | if key in self.keys: 24 | self.keys.remove(key) 25 | self.keys.append(key) 26 | 27 | def elim_key(self): 28 | key = self.keys[0] 29 | self.keys = self.keys[1:] 30 | del self.cache[key] 31 | 32 | def get(self, key): 33 | """ 34 | :type key: int 35 | :rtype: int 36 | """ 37 | if not key in self.cache: 38 | return -1 39 | self.visit_key(key) 40 | return self.cache[key] 41 | 42 | def put(self, key, value): 43 | """ 44 | :type key: int 45 | :type value: int 46 | :rtype: void 47 | """ 48 | if not key in self.cache: 49 | if len(self.keys) == self.capacity: 50 | self.elim_key() 51 | self.cache[key] = value 52 | self.visit_key(key) 53 | 54 | def main(): 55 | s = 56 | [["put","put","get","put","get","put","get","get","get"],[[1,1],[2,2],[1],[3,3],[2],[ 57 | 4,4],[1],[3],[4]]] 58 | obj = LRUCache(2) 59 | l=[] 60 | for i,c in enumerate(s[0]): 61 | if(c == "get"): 62 | l.append(obj.get(s[1][i][0])) 63 | else: 64 | obj.put(s[1][i][0], s[1][i][1]) 65 | print(l) 66 | 67 | if __name__ == "__main__": 68 | main() 69 | 70 | ``` 71 | 72 | c++版本的: 73 | 74 | ``` 75 | class LRUCache{ 76 | public: 77 | LRUCache(int capacity) { 78 | cap = capacity; 79 | } 80 | 81 | int get(int key) { 82 | auto it = m.find(key); 83 | if (it == m.end()) return -1; 84 | l.splice(l.begin(), l, it->second); 85 | return it->second->second; 86 | } 87 | 88 | void set(int key, int value) { 89 | auto it = m.find(key); 90 | if (it != m.end()) l.erase(it->second); 91 | l.push_front(make_pair(key, value)); 92 | m[key] = l.begin(); 93 | if (m.size() > cap) { 94 | int k = l.rbegin()->first; 95 | l.pop_back(); 96 | m.erase(k); 97 | } 98 | } 99 | } 100 | 101 | ``` 102 | -------------------------------------------------------------------------------- /01.阿里篇/1.1.5 关于epoll和select的区别,以下哪些说法是正确的.md: -------------------------------------------------------------------------------- 1 | ##### **问题**:关于 epoll 和 select 的区别,哪些说法是正确的?(多选) 2 | A. epoll 和 select 都是 I/O 多路复用的技术,都可以实现同时监听多个 I/O 事件的状态。 3 | 4 | B. epoll 相比 select 效率更高,主要是基于其操作系统支持的I/O事件通知机制,而 select 是基于轮询机制。 5 | 6 | C. epoll 支持水平触发和边沿触发两种模式。 7 | 8 | D. select 能并行支持 I/O 比较小,且无法修改。 9 | 10 | ##### **出题人**:阿里巴巴出题专家:寈峰/阿里技术专家 11 | 12 | ##### **参考答案**:A,B,C 13 | 14 | 15 | **【延伸】那在高并发的访问下,epoll使用那一种触发方式要高效些?当使用边缘触发的时候要注意些什么东西?** 16 | 17 | 18 | -------------------------------------------------------------------------------- /01.阿里篇/1.1.6 从innodb的索引结构分析,为什么索引的 key 长度不能太长.md: -------------------------------------------------------------------------------- 1 | #### **题目**:从 innodb 的索引结构分析,为什么索引的 key 长度不能太长? 2 | 3 | #### **出题人**:阿里巴巴出题专家:近秋/阿里云数据库产品技术部技术专家 4 | 5 | #### **参考答案**:key 太长会导致一个页当中能够存放的 key 的数目变少,间接导致索引树的页数目变多,索引层次增加,从而影响整体查询变更的效率。 6 | -------------------------------------------------------------------------------- /01.阿里篇/1.1.7 MySQL的数据如何恢复到任意时间点?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:MySQL 的数据如何恢复到任意时间点? 2 | 3 | #### **出题人**:阿里巴巴出题专家:近秋/阿里云数据库产品技术部技术专家参考答案 4 | 5 | #### **参考答案**:恢复到任意时间点以定时的做全量备份,以及备份增量的 binlog 日志为前提。恢复到任意时间点首先将全量备份恢复之后,再此基础上回放增加的 binlog 直至指定的时间点。 6 | -------------------------------------------------------------------------------- /01.阿里篇/1.1.8 NFS与SMB的区别?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:NFS 和 SMB 是最常见的两种 NAS(Network Attached Storage)协议,当把一个文件系统同时通过 NFS 和 SMB 协议共享给多个主机访问时,以下哪些说法是错误的:(多选) 2 | 3 | A. 不可能有这样的操作,即把一个文件系统同时通过 NFS 和 SMB协议共享给多个主机访问。 4 | 5 | B. 主机 a 的用户通过NFS 协议创建的文件或者目录,另一个主机 b的用户不能通过 SMB 协议将其删除。 6 | 7 | C. 在同一个目录下,主机 a 通过 NFS 协议看到文件 file.txt,主机b 通过 SMB 协议也看到文件 file.txt,那么它们是同一个文件。 8 | 9 | D. 主机 a 通过 NFS 协议,以及主机 b 通过 SMB 协议,都可以通过主机端的数据缓存,提升文件访问性能。 10 | 11 | #### **出题人**:阿里巴巴出题专家:起影/阿里云文件存储高级技术专家 12 | 13 | #### **参考答案**:A,B,C 14 | 15 | 16 | -------------------------------------------------------------------------------- /01.阿里篇/1.1.9 输入 ping IP 后敲回车,发包前会发生什么?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:输入 ping IP 后敲回车,发包前会发生什么? 2 | 3 | #### **出题人**:阿里巴巴出题专家:怀虎/阿里云云效平台负责人 4 | 5 | #### **参考答案**: 6 | ping目标ip时,先查路由表,确定出接口 7 | - 如果落在直连接口子网内,此时若为以太网等 _多路访问网络_ 则先查询arp缓存,命中则直接发出,否则在该接口上发arp询问目标ip的mac地址,取得后发出,若为ppp等 _点对点网络_ ,则直接可以发出; 8 | - 如果查表落在缺省路由上,此时若为以太网等 _多路访问网络_ 则先查询网关arp缓存,命中则直接发出,否则在该接口上发arp询问网关的mac地址,取得后发出,若为ppp等 _点对点网络_ ,则直接可以发出; 9 | - 若查表未命中,则返回不可达。 10 | -------------------------------------------------------------------------------- /01.阿里篇/1.2.0 请解释下为什么鹿晗发布恋情的时候,微博系统会崩溃,如何解决?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:请解释下为什么鹿晗发布恋情的时候,微博系统会崩溃,如何解决? 2 | 3 | #### **出题人**:阿里巴巴出题专家:江岚/阿里巴巴数据技术高级技术专家 4 | 5 | #### **参考答案**: 6 | 7 | A. 获取微博通过 pull 方式还是 push 方式 8 | 9 | B. 发布微博的频率要远小于阅读微博 10 | 11 | C. 流量明星的发微博,和普通博主要区分对待,比如在 sharding的时候,也要考虑这个因素 12 | 13 | -------------------------------------------------------------------------------- /01.阿里篇/1.2.1 现有一批邮件需要发送给订阅顾客,且有一个集群(集群的节点数不定,会动态扩容缩容)来负责具体的邮件发送任务,如何让系统尽快地完成发送?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:现有一批邮件需要发送给订阅顾客,且有一个集群(集群的节点数不定,会动态扩容缩容)来负责具体的邮件发送任务,如何让系统尽快地完成发送?请详述技术方案! 2 | 3 | #### **出题人**:阿里巴巴出题专家:江岚/阿里巴巴数据技术高级技术专家 4 | 5 | ### **参考答案**: 6 | 7 | A. 借助消息中间件,通过发布者订阅者模式来进行任务分配 8 | 9 | B. master-slave 部署,由 master 来分配任务 10 | 11 | C. 不借助任何中间件,且所有节点均等。通过数据库的 update-returning,从而实现节点之间任务的互斥 12 | -------------------------------------------------------------------------------- /01.阿里篇/1.2.2 有一批气象观测站,现需要获取这些站点的观测数据,并存储到 Hive 中。但是气象局只提供了 api 查询,每次只能查询单个观测点。那么如果能够方便快速地获取到所有的观测点的数据?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:有一批气象观测站,现需要获取这些站点的观测数据,并存储到 Hive 中。但是气象局只提供了 api 查询,每次只能查询单个观测点。那么如果能够方便快速地获取到所有的观测点的数据? 2 | 3 | #### **出题人**:阿里巴巴出题专家:江岚/阿里巴巴数据技术高级技术专家 4 | 5 | #### **参考答案**: 6 | 7 | A. 通过 shell 或 python 等调用 api,结果先暂存本地,最后将本地文件上传到 Hive 中。 8 | 9 | B. 通过 datax 的 httpReader 和 hdfsWriter 插件,从而获取所需的数据。 10 | 11 | C. 比较理想的回答,是在计算引擎的 UDF 中调用查询 api,执行UDF 的查询结果存储到对应的表中。一方面,不需要同步任务的导出导入;另一方面,计算引擎的分布式框架天生提供了分布式、容错、并发等特性。 -------------------------------------------------------------------------------- /01.阿里篇/1.2.3 如何实现两金额数据相加(最多小数点两位).md: -------------------------------------------------------------------------------- 1 | #### **题目**:如何实现两金额数据相加(最多小数点两位)? 2 | 3 | #### **出题人**:阿里巴巴出题专家:御术/蚂蚁金服数据可视化高级技术专家 4 | 5 | #### **参考答案**: 6 | 7 | 其实问题并不难,就是考察候选人对 JavaScript 数据运算上的认知以及考虑问题的缜密程度,有很多坑,可以用在笔试题,如果用在面试,回答过程中还可以随机加入有很多计算机基础的延伸。 8 | 9 | 回到这个问题,由于直接浮点相与加会失精,所以要转整数;(可以插入问遇到过吗?是否可以举个例子?)。 10 | 11 | 转整数是第一个坑,虽然只有两位可以通过乘以100转整数,但由于乘以一百和除以一百都会出现浮点数的运算,所以也会失精,还是要通过字符串来转;(可以插入问字符串转整数有几种方式?)字符串转整是第二个坑,因为最后要对齐计算,如果没考虑周全先toFixed(2),对于只有一位小数点数据进入计算就会错误;转整数后的计算是个加分点,很多同学往往就是直接算了,如果可以考虑大数计算的场景,恭喜同学进入隐藏关卡,这就会涉及如何有效循环、遍历、算法复杂度的问题。 -------------------------------------------------------------------------------- /01.阿里篇/1.2.4 关于并行计算的一些基础开放问题.md: -------------------------------------------------------------------------------- 1 | #### **题目**: 关于并行计算的一些基础开放问题。 2 | 3 | ◼ 如何定义并计算,请分别阐述分布式内存到共享内存模式行编程的区别和实现(例子代码)? 4 | 5 | ◼ 请使用 MPI 和 OpenMP 分别实现 N 个处理器对 M 个变量的求和? 6 | 7 | ◼ 请说明 SIMD 指令在循环中使用的权限?向量化优化有哪些手段? 8 | 9 | ◼ 请用 Amdahl 定律说明什么是并行效率以及并行算法的扩展性?并说明扩展性的性能指标和限制因素,最后请说明在共享内存计算机中,共享内存的限制?OpenMP 是怎样实现共享内存编程环境的?MPI 阻塞和非阻塞读写的区别? 10 | 11 | #### **出题人**:阿里巴巴出题专家:何万青/阿里云高性能计算资深技术专家 12 | 13 | #### **参考答案**: 14 | 15 | (简要答案,但必须触及,可以展开) 16 | ◼ 同时执行多个/算法/逻辑操作/内存访问/IO,相互独立同时运行,分三个层次:进程级,多个节点分布式内存通过MPI通信并行;线程级,共享内存的多路机器,通过OpenMP实现多线程并行;指令集:通过SIM指令实现单指令多数据。。。。举例吧啦吧啦。 17 | 18 | ◼ MPI代码,,,OpenMP代码,分别写出来 M个元素,N个处理器的累加,后者注意private 参数。 19 | 20 | ◼ SIMD在循环中的应用,限制在于 SIMD指令处理的每一个数组的长度,cache line利用,内部循环间的依赖和条件调用等。 21 | 22 | ◼ 向量化,主要看SSE和AVX指令占比率,通过编译器优化...... 在loop代码中使用。 23 | 24 | ◼ 性能和计算规模随处理器增加的变化曲线,实测HPL和峰值HPL比率,能用用Amdahl定律表达Tpar(N) = (an + (1-a)n/N )t + C (n,N), 能够讲明白串行部分对整个并行的天花板效应,扩展性能够解释清楚算法的扩展性=并行效率随处理器数目的变化关系,画出来。 25 | 26 | ◼ 共享内存计算机OpenMP对变量的限制描述,EREW,CREW,ERCW,CRCW等区别,NUMA概念,如何保持coherent等。 27 | 28 | ◼ 写出OpenMP和MPI的核心函数,回答问题即可。 -------------------------------------------------------------------------------- /01.阿里篇/1.2.5 请计算XILINX公司VU9P芯片的算力相当于多少TOPS,给出计算过程与公式.md: -------------------------------------------------------------------------------- 1 | #### **题目**:请计算XILINX公司VU9P芯片的算力相当于多少TOPS,给出计算过程与公式。 2 | 3 | #### **出题人**: 阿里巴巴出题专家:隐达/阿里云异构计算资深专家 4 | 5 | #### **参考答案**:基于不同的算法,这个值在十几到几百之间。但是,如果只是单纯比算力,FPGA和ASIC、GPU相比并无太大优势,甚至大多时候有较大劣势。FPGA的优势在于高度的灵活性和算法的针对性。 -------------------------------------------------------------------------------- /01.阿里篇/1.2.6 一颗现代处理器,每秒大概可以执行多少条简单的MOV指令,有哪些主要的影响因素.md: -------------------------------------------------------------------------------- 1 | #### **题目**:一颗现代处理器,每秒大概可以执行多少条简单的MOV指令,有哪些主要的影响因素? 2 | 3 | #### **出题人**:阿里巴巴出题专家:子团/创新产品虚拟化&稳定性资深技术专家 4 | 5 | #### **参考答案**: 6 | 7 | **及格:** 8 | 每执行一条mov指令需要消耗1个时钟周期,所以每秒执行的mov指令和CPU主频相关。 9 | 10 | **加分:** 11 | 在CPU微架构上,要考虑数据预取,乱序执行,多发射,内存stall(前端stall和后端stall)等诸多因素,因此除了cpu主频外,还和流水线上的效率(IPC)强相关,比较复杂的一个问题。 -------------------------------------------------------------------------------- /01.阿里篇/1.2.7 请分析 MaxCompute 产品与分布式技术的关系、当前大数据计算平台类产品的市场现状和发展趋势.md: -------------------------------------------------------------------------------- 1 | #### **题目**:请分析 MaxCompute 产品与分布式技术的关系、当前大数据计算平台类产品的市场现状和发展趋势。 2 | 3 | #### **出题人**:阿里巴巴出题专家:云郎/阿里 MaxCompute 高级产品专家 4 | 5 | #### **参考答案**: 6 | 7 | 开放性问题,无标准答案。 -------------------------------------------------------------------------------- /01.阿里篇/1.2.8 对大数据平台中的元数据管理是怎么理解的,元数据收集管理体系是怎么样的,会对大数据应用有什么样的影响.md: -------------------------------------------------------------------------------- 1 | #### **题目**: 对大数据平台中的元数据管理是怎么理解的,元数据收集管理体系是怎么样的,会对大数据应用有什么样的影响。 2 | 3 | #### **出题人**: 阿里巴巴出题专家:映泉/阿里巴巴高级技术专家 4 | 5 | #### **参考答案**:开放性问题,无标准答案。 6 | 7 | -------------------------------------------------------------------------------- /01.阿里篇/1.2.9 你理解常见如阿里,和友商大数据平台的技术体系差异以及发展趋势和技术瓶颈,在存储和计算两个方面进行概述.md: -------------------------------------------------------------------------------- 1 | #### **题目**: 你理解常见如阿里,和友商大数据平台的技术体系差异以及发展趋势和技术瓶颈,在存储和计算两个方面进行概述。 2 | 3 | #### **出题人**: 阿里巴巴出题专家:映泉/阿里巴巴高级技术专家 4 | 5 | #### **参考答案**:开放性问题,无标准答案。 -------------------------------------------------------------------------------- /01.阿里篇/1.3.0 在云计算大数据处理场景中,每天运行着成千上万的任务,每个任务都要进行 IO 读写.md: -------------------------------------------------------------------------------- 1 | #### **题目**:在云计算大数据处理场景中,每天运行着成千上万的任务,每个任务都要进行 IO 读写。存储系统为了更好的服务,经常会保证高优先级的任务优先执行。当多个作业或用户访问存储系统时,如何保证优先级和公平性。 2 | 3 | #### **出题人**:阿里巴巴出题专家:田磊磊/阿里云文件存储高级技术专家 4 | 5 | #### **参考答案**:开放性问题,无标准答案。 -------------------------------------------------------------------------------- /01.阿里篇/1.3.1 最大频率栈.md: -------------------------------------------------------------------------------- 1 | #### **题目**:最大频率栈。 2 | 实现 FreqStack,模拟类似栈的数据结构的操作的一个类。FreqStack 有两个函数:
push(int x),将整数 x 推入栈中。pop(),它移除并返回栈中出现最频繁的元素。如果最频繁的元素不只一个,则移除并返回最接近栈顶的元素。 3 | ◼ 示例: 4 | push [5,7,5,7,4,5] 5 | pop() -> 返回 5,因为 5 是出现频率最高的。
栈变成 6 | [5,7,5,7,4]。 7 | pop() -> 返回 7,因为 5 和 7 都是频率最高的,但 7 最接近栈 8 | 顶。
栈变成 [5,7,5,4]。 9 | pop() -> 返回 5 。
栈变成 [5,7,4]。 10 | pop() -> 返回 4 。
栈变成 [5,7]。 11 | 12 | #### **出题人**:阿里巴巴出题专家:屹平/阿里云视频云边缘计算高级技术专家 13 | 14 | #### **参考答案**: 15 | 16 | 令 freq 作为 x 的出现次数的映射 Map。 17 | 18 | 此外 maxfreq,即栈中任意元素的当前最大频率,因为我们必须弹出频率最高的元素。 19 | 20 | 当前主要的问题就变成了:在具有相同的(最大)频率的元素中,怎么判断那个元素是最新的?我们可以使用栈来查询这一信息:靠近栈顶的元素总是相对更新一些。 21 | 22 | 为此,我们令 group 作为从频率到具有该频率的元素的映射。到目前,我们已经实现了 FreqStack 的所有必要的组件。 23 | 24 | 算法: 25 | 26 | 实际上,作为实现层面上的一点细节,如果 x 的频率为 f,那么我们将获取在所有 group[i] (i <= f) 中的 x,而不仅仅是栈顶的那个。这是因为每个 group[i] 都会存储与第 i 个 x 副本相关的信息。 27 | 28 | 最后,我们仅仅需要如上所述维持 freq,group,以及 maxfreq。 29 | 30 | **参考代码***: 31 | ``` 32 | class FreqStack { 33 | Map freq; 34 | Map> group; 35 | int maxfreq; 36 | 37 | public FreqStack() { 38 | freq = new HashMap(); 39 | group = new HashMap(); 40 | maxfreq = 0; 41 | } 42 | 43 | public void push(int x) { 44 | int f = freq.getOrDefault(x, 0) + 1; 45 | freq.put(x, f); 46 | if (f > maxfreq) maxfreq = f; 47 | group.computeIfAbsent(f, z-> new Stack()).push(x); 48 | } 49 | 50 | public int pop() { 51 | int x = group.get(maxfreq).pop(); 52 | freq.put(x, freq.get(x) - 1); 53 | if (group.get(maxfreq).size() == 0) 54 | maxfreq--; 55 | return x; 56 | } 57 | } 58 | ``` -------------------------------------------------------------------------------- /01.阿里篇/1.3.2 给定一个链表,删除链表的倒数第N个节点,并且返回链表的头结点.md: -------------------------------------------------------------------------------- 1 | #### **题目**:给定一个链表,删除链表的倒数第 N 个节点,并且返回链表的头结点。 2 | 3 | ◼ 示例: 4 | 给定一个链表: 1->2->3->4->5, 和 n = 2. 5 | 当删除了倒数第二个节点后,链表变为 1->2->3->5. 6 | 说明: 7 | 给定的 n 保证是有效的。 8 | 要求: 9 | 只允许对链表进行一次遍历。 10 | 11 | #### **出题人**:阿里巴巴出题专家:屹平/阿里云视频云边缘计算高级技术专家 12 | 13 | #### **参考答案**: 14 | 15 | 我们可以使用两个指针而不是一个指针。第一个指针从列表的开头向前移动 n+1 步,而第二个指针将从列表的开头出发。现在,这两个指针被 n 个结点分开。我们通过同时移动两个指针向前来保持这个恒定的间隔,直到第一个指针到达最后一个结点。此时第二个指针将指向从最后一个结点数起的第 n 个结点。我们重新链接第二个指针所引用的结点的 next 指针指向该结点的下下个结点。 16 | 17 | **参考代码**: 18 | 19 | ``` 20 | public ListNode removeNthFromEnd(ListNode head, int n) 21 | { 22 | ListNode dummy = new ListNode(0); 23 | dummy.next = head; 24 | ListNode first = dummy; 25 | ListNode second = dummy; 26 | // Advances first pointer so that the gap between first 27 | and second is n nodes apart 28 | for (int i = 1; i <= n + 1; i++) { 29 | first = first.next; 30 | } 31 | // Move first to the end, maintaining the gap 32 | while (first != null) { 33 | first = first.next; 34 | second = second.next; 35 | } 36 | second.next = second.next.next; 37 | return dummy.next; 38 | } 39 | ``` 40 | 41 | **复杂度分析:** 42 | * 时间复杂度:O(L),该算法对含有 L 个结点的列表进行了一次遍历。因此时间复杂度为 O(L)。 43 | 44 | * 空间复杂度:O(1),我们只用了常量级的额外空间。 45 | -------------------------------------------------------------------------------- /01.阿里篇/1.3.3 如果让你设计一个通用的、支持各种数据库秒级备份和恢复的系统,你会如何设计.md: -------------------------------------------------------------------------------- 1 | #### **题目**:如果让你设计一个通用的、支持各种数据库秒级备份和恢复的系统,你会如何设计? 2 | 3 | #### **出题人**:阿里巴巴出题专家:千震/阿里云数据库高级技术专家 4 | 5 | #### **参考答案**:开放性问题,无标准答案。 -------------------------------------------------------------------------------- /01.阿里篇/1.3.4 如果让你来设计一个支持数据库、NOSQL 和大数据之间数据实时流动的数据流及处理的系统,你会考虑哪些问题?如何设计?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:如果让你来设计一个支持数据库、NOSQL 和大数据之间数据实时流动的数据流及处理的系统,你会考虑哪些问题?如何设计? 2 | 3 | #### **出题人**:阿里巴巴出题专家:千震/阿里云数据库高级技术专家 4 | 5 | #### **参考答案**:开放性问题,无标准答案。 -------------------------------------------------------------------------------- /01.阿里篇/1.3.5 给定一个整数数组和一个整数,返回两个数组的索引,这两个索引指向的数字的加和等于指定的整数。需要最优的算法,分析算法的空间和时间复杂度.md: -------------------------------------------------------------------------------- 1 | 2 | 题目:给定一个整数数组和一个整数,返回两个数组的索引,这两个索引指向的数字的加和等于指定的整数。需要最优的算法,分析算法的空间和时间复杂度 3 | 4 | 参考答案: 5 | ```Java 6 | public int[] twoSum(int[] nums, int target) { 7 | if(nums==null || nums.length<2) 8 | return new int[]{0,0}; 9 | 10 | HashMap map = new HashMap(); 11 | for(int i=0; i queue = new 6 | SynchronousQueue<>(); 7 | System. out .print(queue.offer(1) + " "); 8 | System. out .print(queue.offer(2) + " "); 9 | System. out .print(queue.offer(3) + " "); 10 | System. out .print(queue.take() + " "); 11 | System. out .println(queue.size()); 12 | } 13 | } 14 | 15 | ``` 16 | A. true true true 1 3 17 | 18 | B. true true true (阻塞) 19 | 20 | C. false false false null 0 21 | 22 | D. false false false (阻塞) 23 | 24 | #### **出题人**:阿里巴巴出题专家:桃谷/阿里云中间件技术专家 25 | 26 | #### **参考答案**:D 27 | 28 | -------------------------------------------------------------------------------- /01.阿里篇/1.3.8 如何测试一辆自行车.md: -------------------------------------------------------------------------------- 1 | #### **题目**:如何测试一辆自行车 2 | #### **出题人**:阿里巴巴新零售技术质量部 3 | 4 | #### **参考答案**: 5 | 6 | 开放性问题,如果联系到测试角度上看的话,可以这么作答: 7 | 8 | 1. 骑车试一试,看有没有问题,对应测试能不能跑通 9 | 2. 看看车的核心部件,例如车闸,车把等,对应软件的核心功能 10 | 3. 看看车是否安全,配锁质量如何,对应软件是否有安全问题 11 | 12 | -------------------------------------------------------------------------------- /01.阿里篇/1.3.9 如何判断两个链表是否相交.md: -------------------------------------------------------------------------------- 1 | #### **题目**:如何判断两个链表是否相交 2 | 3 | #### **出题人**:阿里巴巴新零售技术质量部 4 | 5 | #### **参考答案**: 6 | 7 | $O(n^2)$: 两层遍历,总能发现是否相交 8 | 9 | $O(n)$: 一层遍历,遍历完两个链表,如果两个链表的最后一个结点指针相同,则相交,否则不相交 10 | 11 | -------------------------------------------------------------------------------- /02.华为篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/02.华为篇/.gitkeep -------------------------------------------------------------------------------- /02.华为篇/2.1.1 static有什么用途?(请至少说明两种).md: -------------------------------------------------------------------------------- 1 | #### **题目**: static有什么用途?(请至少说明两种) 2 | 3 | #### **参考答案**: 4 | 1) 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。 5 | 2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。 6 | 3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用 7 | -------------------------------------------------------------------------------- /02.华为篇/2.1.2 引用与指针有什么区别?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:引用与指针有什么区别? 2 | 3 | #### **参考答案**: 4 | 1) 引用必须被初始化,指针不必。 5 | 2) 引用初始化以后不能被改变,指针可以改变所指的对象。 6 | 3) 不存在指向空值的引用,但是存在指向空值的指针。 7 | -------------------------------------------------------------------------------- /02.华为篇/2.1.3 描述实时系统的基本特性.md: -------------------------------------------------------------------------------- 1 | #### **题目**:描述实时系统的基本特性 2 | 3 | #### **参考答案**: 4 | 在特定时间内完成特定的任务,实时性与可靠性。 5 | -------------------------------------------------------------------------------- /02.华为篇/2.1.4 全局变量和局部变量在内存中是否有区别?如果有,是什么区别?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:全局变量和局部变量在内存中是否有区别?如果有,是什么区别? 2 | 3 | 4 | #### **参考答案**: 5 | 全局变量储存在静态数据库,局部变量在堆栈。 6 | -------------------------------------------------------------------------------- /02.华为篇/2.1.5 什么是平衡二叉树?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:什么是平衡二叉树? 2 | 3 | #### **参考答案**: 4 | 左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1。 -------------------------------------------------------------------------------- /02.华为篇/2.1.6 堆栈溢出一般是由什么原因导致的?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:堆栈溢出一般是由什么原因导致的? 2 | 3 | #### **参考答案**: 4 | 没有回收垃圾资源。 -------------------------------------------------------------------------------- /02.华为篇/2.1.7 什么函数不能声明为虚函数?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:什么函数不能声明为虚函数? 2 | 3 | #### **参考答案**: 4 | constructor函数不能声明为虚函数。 -------------------------------------------------------------------------------- /02.华为篇/2.1.8 冒泡排序算法的时间复杂度是什么?.md: -------------------------------------------------------------------------------- 1 | #### **题目**: 冒泡排序算法的时间复杂度是什么? 2 | 3 | #### **参考答案**: 4 | 时间复杂度是O(n^2)。 -------------------------------------------------------------------------------- /02.华为篇/2.1.9. Internet采用哪种网络协议?该协议的主要层次结构?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:Internet采用哪种网络协议?该协议的主要层次结构? 2 | 3 | 4 | #### **参考答案**: 5 | Tcp/Ip协议 6 | 主要层次结构为: 应用层/传输层/网络层/数据链路层/物理层。 7 | -------------------------------------------------------------------------------- /02.华为篇/2.2.0 IP地址的编码分为哪俩部分?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:IP地址的编码分为哪俩部分? 2 | 3 | #### **参考答案**: 4 | IP地址由两部分组成,网络号和主机号。不过是要和“子网掩码”按位与上之后才能区分哪些是网络位哪些是主机位。 5 | 6 | 7 | -------------------------------------------------------------------------------- /02.华为篇/2.2.1 用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序.md: -------------------------------------------------------------------------------- 1 | #### **题目**:用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。 2 | 3 | #### **参考答案**: 4 | 循环链表,用取余操作做 -------------------------------------------------------------------------------- /02.华为篇/2.2.2 某32位系统下, C++程序,请计算sizeof 的值.md: -------------------------------------------------------------------------------- 1 | #### **题目**:某32位系统下, C++程序,请计算sizeof 的值. 2 | 3 | 4 | #### **参考答案**: 5 | ``` 6 | char str[] = “http://www.ibegroup.com/” 7 | char *p = str ; 8 | int n = 10; 9 | 请计算 10 | sizeof (str ) = ?(1) 11 | sizeof ( p ) = ?(2) 12 | sizeof ( n ) = ?(3) 13 | void Foo ( char str[100]){ 14 | 请计算 15 | sizeof( str ) = ?(4) 16 | } 17 | void *p = malloc( 100 ); 18 | 请计算 19 | sizeof ( p ) = ?(5) 20 | 21 | (1)17 (2)4 (3) 4 (4)4 (5)4 22 | ``` 23 | -------------------------------------------------------------------------------- /03.百度篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/03.百度篇/.gitkeep -------------------------------------------------------------------------------- /03.百度篇/3.4.8 找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数。.md: -------------------------------------------------------------------------------- 1 | #### **题目**:找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数。 2 | 3 | #### **出题人**:阿里巴巴新零售技术质量部 4 | 5 | #### **参考答案**: 6 | 7 | 遍历数组的同时用Object来储存每个元素出现的个数,每次遍历都跟max比较 8 | 9 | #### **参考代码**: 10 | ``` 11 | const arr =[1,2,3,4,5,6,7,8,89,9,9,9,9,99]; 12 | 13 | const maxNumObj =(arr)=>{ 14 | return arr.reduce((obj,cur)=>{ 15 | if(!obj['max']){ 16 | obj['max']=arr[0]; 17 | } 18 | obj[cur] = ++obj[cur]||1; 19 | if(obj[cur]>obj['max']){ 20 | obj['max'] = obj[cur] 21 | } 22 | return obj; 23 | },{})['max']; 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /03.百度篇/3.4.9 找出被修改过的数字.md: -------------------------------------------------------------------------------- 1 | #### **题目**: 找出被修改过的数字 2 | 3 | #### **出题人**:阿里巴巴新零售技术质量部 4 | 5 | #### **参考答案**: 6 | 7 | emmm假设背景是寻找数组中被修改的数字或者元素,我使用代理的方式来监听数组中元素的变化,并将变化的最后数值和次数储存在额外空间中 8 | 9 | #### **参考代码**: 10 | 11 | ``` 12 | const arr =[1,2,3,4,5,6,7,8,89,9,9,9,9,99]; 13 | 14 | const saveModifyNum={ 15 | 16 | } 17 | const watchNumChangeProxy=new Proxy(arr,{ 18 | set:function(target,key,value){ 19 | let {count} = Reflect.get(saveModifyNum,target[key])||{count:0,value}; 20 | ++count; 21 | return Reflect.set(saveModifyNum,target[key],{ 22 | count, 23 | value 24 | }); 25 | } 26 | }) 27 | watchNumChangeProxy[0]=2; 28 | watchNumChangeProxy[0]=3; 29 | watchNumChangeProxy[0]=4; 30 | //{ '1': { count: 3, value: 4 } } 31 | ``` 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /04.腾讯篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/04.腾讯篇/.gitkeep -------------------------------------------------------------------------------- /05.美团篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/05.美团篇/.gitkeep -------------------------------------------------------------------------------- /05.美团篇/5.2.0 浅复制和深复制?怎样实现深复制?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:浅复制和深复制?怎样实现深复制? 2 | 3 | #### **出题人**:阿里巴巴新零售技术质量部 4 | 5 | #### **参考答案**: 6 | 7 | #### **参考代码**; 8 | ``` 9 | const isObject = (item)=>{ 10 | return Object.prototype.toString.call(item) === '[object Object]'; 11 | } 12 | const isArray = (item)=>{ 13 | return Object.prototype.toString.call(item) === '[object Array]'; 14 | } 15 | 16 | const deepClone=(obj)=>{ 17 | const cloneObj=isArray(obj)?[]:isObject(obj)?{}:''; 18 | for(let key in obj){ 19 | if(isObject(obj[key])||isArray(obj[key])){ 20 | Object.assign(cloneObj,{ 21 | [key]: deepClone(Reflect.get(obj,key)) 22 | }); 23 | } 24 | else{ 25 | cloneObj[key] = obj[key]; 26 | } 27 | } 28 | return cloneObj; 29 | } 30 | ``` 31 | 32 | PS:可以处理这样的格式,仅处理了对象类型和数组类型 33 | ``` 34 | const obj111 ={ 35 | a:1, 36 | b:{ 37 | c:2, 38 | d:{ 39 | e:3 40 | }, 41 | f:[1,{a:1,b:2},3] 42 | } 43 | } 44 | ``` 45 | 46 | -------------------------------------------------------------------------------- /06.头条篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/06.头条篇/.gitkeep -------------------------------------------------------------------------------- /06.头条篇/一棵二叉树,求最大通路长度(即最大左右子树高度之和).md: -------------------------------------------------------------------------------- 1 | #### **题目**:一棵二叉树,求最大通路长度(即最大左右子树高度之和) 2 | 3 | #### **参考答案**: 4 | 5 | 该题与leetcode第104题同题型,定义TreeNode结构如下: 6 | 7 | ```java 8 | class TreeNode { 9 | 10 | int val; 11 | TreeNode left; 12 | TreeNode right; 13 | 14 | public TreeNode(int val) { 15 | this.val = val; 16 | } 17 | } 18 | ``` 19 | 20 | 解法一(递归求解) 21 | ```java 22 | class Solution { 23 | 24 | public int maxHeight(TreeNode root) { 25 | if (root == null) { 26 | return 0; 27 | } 28 | return maxChildHeight(root.left) + maxChildHeight(root.right); 29 | } 30 | 31 | public int maxChildHeight(TreeNode root) { 32 | if (root == null) { 33 | return 0; 34 | } 35 | int leftHeight = maxChildHeight(root.left); 36 | int rightHeight = maxChildHeight(root.right); 37 | return Math.max(leftHeight, rightHeight) + 1; 38 | } 39 | } 40 | ``` 41 | 42 | 解法二(迭代求解) 43 | ```java 44 | public class Solution { 45 | 46 | public int maxHeight(TreeNode root) { 47 | if (root == null) { 48 | return 0; 49 | } 50 | return maxChildHeight(root.left) + maxChildHeight(root.right); 51 | } 52 | 53 | public int maxChildHeight(TreeNode root) { 54 | int height = 0; 55 | Queue queue = new LinkedList<>(); 56 | queue.add(root); 57 | 58 | while (!queue.isEmpty()) { 59 | int size = queue.size(); 60 | for (int i = 0; i < size; i++) { 61 | TreeNode node = queue.poll(); 62 | height++; 63 | if (node.left != null) { 64 | queue.add(node.left); 65 | } 66 | if (node.right != null) { 67 | queue.add(node.right); 68 | } 69 | } 70 | } 71 | return height; 72 | } 73 | } 74 | ``` 75 | -------------------------------------------------------------------------------- /07.滴滴篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/07.滴滴篇/.gitkeep -------------------------------------------------------------------------------- /08.京东篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/08.京东篇/.gitkeep -------------------------------------------------------------------------------- /08.京东篇/简单说一下hadoop和spark的shuffle过程.md: -------------------------------------------------------------------------------- 1 | ##### 问题:**简单说一下hadoop和spark的shuffle过程** 2 | 3 | ##### 出题人:京东出题专家:阿昀/京东数据中台 4 | 5 | ##### 参考答案: 6 | 7 | Hadoop:map端保存分片数据,通过网络收集到reduce端。 8 | 9 | Spark:spark的shuffle实在DAGSchedular划分Stage的时候产生的,TaskSchedular要分发Stage到各个worker的executor。减少shuffle可以提高性能。 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /09.MySQL篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/09.MySQL篇/.gitkeep -------------------------------------------------------------------------------- /09.MySQL篇/9.1.0 主键 超键 候选键 外键.md: -------------------------------------------------------------------------------- 1 | #### **题目**:主键 超键 候选键 外键是什么 2 | 3 | #### 定义 4 | 5 | **超键(super key)**: 在关系中能唯一标识元组的属性集称为关系模式的超键 6 | 7 | **候选键(candidate key)**: 不含有多余属性的超键称为候选键。也就是在候选键中,若再删除属性,就不是键了! 8 | 9 | **主键(primary key)**: 用户选作元组标识的一个候选键程序主键 10 | 11 | **外键(foreign key)**:如果关系模式R中属性K是其它模式的主键,那么k在模式R中称为外键。 12 | 13 | #### 举例 14 | 15 | 比如有如下数据: 16 | 17 | | 学号 | 姓名 | 性别 | 年龄 | 系别 | 专业 18 | |:---:|:---:|:---:|:---:|:---:|:---: 19 | |20020612 |李辉 |男 |20 |计算机 |软件开发 20 | |20060613| 张明| 男 |18 |计算机 |软件开发 21 | |20060614| 王小玉| 女 |19 |物理 |力学 22 | |20060615| 李淑华| 女 |17 |生物 |动物学 23 | |20060616| 赵静| 男 |21 |化学 |食品化学 24 | |20060617| 赵静| 女 |20 |生物 |植物学 25 | 26 | 1. 超键 27 | 28 | 在关系中能唯一标识元组的属性集称为关系模式的超键。 29 | 30 | 于是我们从例子中可以发现 学号是标识学生实体的唯一标识。那么该元组的超键就为学号。 31 | 32 | 除此之外我们还可以把它跟其他属性组合起来,比如: 33 | 34 | (`学号`,`性别`) 35 | 36 | (`学号`,`年龄`) 37 | 38 | 这样也是超键. 39 | 40 | 2. 候选键 41 | 42 | 不含多余属性的超键为候选键。 43 | 44 | 根据例子可知,学号是一个可以唯一标识元组的唯一标识,因此学号是一个候选键,实际上,候选键是超键的子集,比如 (学号,年龄)是超键,但是它不是候选键。因为它还有了额外的属性。 45 | 46 | 3. 主键 47 | 48 | 用户选择的候选键作为该元组的唯一标识,那么它就为主键。 49 | 50 | 简单的说,例子中的元组的候选键为学号,但是我们选定他作为该元组的唯一标识,那么学号就为主键。 51 | 52 | 4. 外键 53 | 54 | 外键是相对于主键的,比如在学生记录里,主键为学号,在成绩单表中也有学号字段,因此学号为成绩单表的外键,为学生表的主键。 55 | 56 | #### 总结 57 | 58 | **主键为候选键的子集,候选键为超键的子集,而外键的确定是相对于主键的。** -------------------------------------------------------------------------------- /09.MySQL篇/9.1.1 数据库事务的四个特性及含义.md: -------------------------------------------------------------------------------- 1 | #### **题目**:数据库事务的四个特性及含义 2 | 3 | #### **参考答案**: 4 | 5 | 数据库事务transanction正确执行的四个基本要素。ACID,原子性(Atomicity)、一致性(Correspondence)、隔离性(Isolation)、持久性(Durability)。 6 | 7 | * 原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。 8 | 9 | * 一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。 10 | 11 | * 隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行 相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请 求,使得在同一时间仅有一个请求用于同一数据。 12 | 13 | * 持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。 -------------------------------------------------------------------------------- /09.MySQL篇/9.1.2 视图的作用,视图可以更改么?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:视图的作用,视图可以更改么? 2 | 3 | #### **参考答案**: 4 | 5 | 视图是虚拟的表,与包含数据的表不一样,视图只包含使用时动态检索数据的查询;不包含任何列或数据。使用视图可以简化复杂的sql操作,隐藏具体的细节,保护数据;视图创建后,可以使用与表相同的方式利用它们。 6 | 7 | 视图不能被索引,也不能有关联的触发器或默认值,如果视图本身内有order by 则对视图再次order by将被覆盖。 8 | 9 | 创建视图:create view XXX as XXXXXXXXXXXXXX; 10 | 11 | 对于某些视图比如未使用联结子查询分组聚集函数Distinct Union等,是可以对其更新的,对视图的更新将对基表进行更新;但是视图主要用于简化检索,保护数据,并不用于更新,而且大部分视图都不可以更新。 -------------------------------------------------------------------------------- /09.MySQL篇/9.1.3 drop,delete与truncate的区别.md: -------------------------------------------------------------------------------- 1 | #### **题目**:drop,delete与truncate的区别 2 | 3 | #### **参考答案**: 4 | 5 | drop直接删掉表 truncate删除表中数据,再插入时自增长id又从1开始 delete删除表中数据,可以加where字句。 6 | 7 | (1) DELETE语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作。TRUNCATE TABLE 则一次性地从表中删除所有的数据并不把单独的删除操作记录记入日志保存,删除行是不能恢复的。并且在删除的过程中不会激活与表有关的删除触发器。执行速度快。 8 | 9 | (2) 表和索引所占空间。当表被TRUNCATE 后,这个表和索引所占用的空间会恢复到初始大小,而DELETE操作不会减少表或索引所占用的空间。drop语句将表所占用的空间全释放掉。 10 | 11 | (3) 一般而言,drop > truncate > delete 12 | 13 | (4) 应用范围。TRUNCATE 只能对TABLE;DELETE可以是table和view 14 | 15 | (5) TRUNCATE 和DELETE只删除数据,而DROP则删除整个表(结构和数据)。 16 | 17 | (6) truncate与不带where的delete :只删除数据,而不删除表的结构(定义)drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger)索引(index);依赖于该表的存储过程/函数将被保留,但其状态会变为:invalid。 18 | 19 | (7) delete语句为DML(Data Manipulation Language),这个操作会被放到 rollback segment中,事务提交后才生效。如果有相应的 tigger,执行的时候将被触发。 20 | 21 | (8) truncate、drop是DDL(Data Define Language),操作立即生效,原数据不放到 rollback segment中,不能回滚 22 | 23 | (9) 在没有备份情况下,谨慎使用 drop 与 truncate。要删除部分数据行采用delete且注意结合where来约束影响范围。回滚段要足够大。要删除表用drop;若想保留表而将表中数据删除,如果于事务无关,用truncate即可实现。如果和事务有关,或老是想触发trigger,还是用delete。 24 | 25 | (10) Truncate table 表名 速度快,而且效率高,因为: truncate table 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少。DELETE 语句每次删除一行,并在事务日志中为所删除的每行记录一项。TRUNCATE TABLE 通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。 26 | 27 | (11) TRUNCATE TABLE 删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用 DELETE。如果要删除表定义及其数据,请使用 DROP TABLE 语句。 28 | 29 | (12) 对于由 FOREIGN KEY 约束引用的表,不能使用 TRUNCATE TABLE,而应使用不带 WHERE 子句的 DELETE 语句。由于 TRUNCATE TABLE 不记录在日志中,所以它不能激活触发器。 30 | -------------------------------------------------------------------------------- /09.MySQL篇/9.1.4 索引的工作原理及其种类.md: -------------------------------------------------------------------------------- 1 | #### **题目**:索引的工作原理及其种类 2 | 3 | #### **参考答案**: 4 | 5 | **数据库索引**,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。 6 | 7 | 在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。 8 | 9 | 为表设置索引要付出代价的:一是增加了数据库的存储空间,二是在插入和修改数据时要花费较多的时间(因为索引也要随之变动)。 10 | 11 | 12 | 13 | 图展示了一种可能的索引方式。左边是数据表,一共有两列七条记录,最左边的是数据记录的物理地址(注意逻辑上相邻的记录在磁盘上也并不是一定物理相邻的)。为了加快Col2的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就可以运用二叉查找在O(log2n)的复杂度内获取到相应数据。 14 | 15 | 创建索引可以大大提高系统的性能。 16 | 17 | 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 18 | 19 | 第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。 20 | 21 | 第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 22 | 23 | 第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 24 | 25 | 第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。 26 | 27 | 也许会有人要问:增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢?因为,增加索引也有许多不利的方面。 28 | 29 | 第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。 30 | 31 | 第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。 32 | 33 | 第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。 34 | 35 | 索引是建立在数据库表中的某些列的上面。在创建索引的时候,应该考虑在哪些列上可以创建索引,在哪些列上不能创建索引。一般来说,应该在这些列上创建索引:在经常需要搜索的列上,可以加快搜索的速度;在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。 36 | 37 | 同样,对于有些列不应该创建索引。一般来说,不应该创建索引的的这些列具有下列特点: 38 | 39 | 第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。 40 | 41 | 第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。 42 | 43 | 第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。 44 | 45 | 第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。 46 | 47 | 根据数据库的功能,可以在数据库设计器中创建三种索引:唯一索引、主键索引和聚集索引。 48 | 49 | 唯一索引 50 | 51 | 唯一索引是不允许其中任何两行具有相同索引值的索引。 52 | 53 | 当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在employee表中职员的姓(lname)上创建了唯一索引,则任何两个员工都不能同姓。 主键索引 数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。 在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。 聚集索引 在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。 54 | 55 | 如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。 56 | 57 | 局部性原理与磁盘预读 58 | 由于存储介质的特性,磁盘本身存取就比主存慢很多,再加上机械运动耗费,磁盘的存取速度往往是主存的几百分分之一,因此为了提高效率,要尽量减少磁盘I/O。为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。这样做的理论依据是计算机科学中著名的局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用。程序运行期间所需要的数据通常比较集中。 59 | 60 | 由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率。 61 | 62 | 预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多操作系统中,页得大小通常为4k),主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行。 63 | 64 | B-/+Tree索引的性能分析 65 | 到这里终于可以分析B-/+Tree索引的性能了。 66 | 67 | 上文说过一般使用磁盘I/O次数评价索引结构的优劣。先从B-Tree分析,根据B-Tree的定义,可知检索一次最多需要访问h个节点。数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧: 68 | 69 | 每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。 70 | 71 | B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)=O(logdN)。一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3)。 72 | 73 | 而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。 74 | 75 | 综上所述,用B-Tree作为索引结构效率是非常高的。 -------------------------------------------------------------------------------- /09.MySQL篇/9.1.5 连接的种类.md: -------------------------------------------------------------------------------- 1 | #### **题目**:连接的种类 2 | 3 | #### **参考答案**: 4 | 5 | 查询分析器中执行: 6 | ``` 7 | --建表table1,table2: 8 | create table table1(id int,name varchar(10)) 9 | create table table2(id int,score int) 10 | insert into table1 select 1,'lee' 11 | insert into table1 select 2,'zhang' 12 | insert into table1 select 4,'wang' 13 | insert into table2 select 1,90 14 | insert into table2 select 2,100 15 | insert into table2 select 3,70 16 | 17 | ``` 18 | 如表: 19 | ``` 20 | ------------------------------------------------- 21 | table1 | table2 | 22 | ------------------------------------------------- 23 | id name |id score | 24 | 1 lee |1 90| 25 | 2 zhang| 2 100| 26 | 4 wang| 3 70| 27 | ------------------------------------------------- 28 | ``` 29 | 以下均在查询分析器中执行 30 | 一、外连接 31 | 1.概念:包括左向外联接、右向外联接或完整外部联接 32 | 33 | 2.左连接:left join 或 left outer join 34 | (1)左向外联接的结果集包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值(null)。 35 | (2)sql 语句 36 | ``` 37 | select * from table1 left join table2 on table1.id=table2.id 38 | -------------结果------------- 39 | idnameidscore 40 | ------------------------------ 41 | 1lee190 42 | 2zhang2100 43 | 4wangNULLNULL 44 | ------------------------------ 45 | ``` 46 | 注释:包含table1的所有子句,根据指定条件返回table2相应的字段,不符合的以null显示 47 | 48 | 3.右连接:right join 或 right outer join 49 | (1)右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。 50 | (2)sql 语句 51 | ``` 52 | select * from table1 right join table2 on table1.id=table2.id 53 | -------------结果------------- 54 | idnameidscore 55 | ------------------------------ 56 | 1lee190 57 | 2zhang2100 58 | NULLNULL370 59 | ------------------------------ 60 | ``` 61 | 注释:包含table2的所有子句,根据指定条件返回table1相应的字段,不符合的以null显示 62 | 63 | 4.完整外部联接:full join 或 full outer join 64 | (1)完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。 65 | (2)sql 语句 66 | ``` 67 | select * from table1 full join table2 on table1.id=table2.id 68 | -------------结果------------- 69 | idnameidscore 70 | ------------------------------ 71 | 1lee190 72 | 2zhang2100 73 | 4wangNULLNULL 74 | NULLNULL370 75 | ------------------------------ 76 | ``` 77 | 注释:返回左右连接的和(见上左、右连接) 78 | 79 | 二、内连接 80 | 1.概念:内联接是用比较运算符比较要联接列的值的联接 81 | 82 | 2.内连接:join 或 inner join 83 | 84 | 3.sql 语句 85 | ``` 86 | select * from table1 join table2 on table1.id=table2.id 87 | -------------结果------------- 88 | idnameidscore 89 | ------------------------------ 90 | 1lee190 91 | 2zhang2100 92 | ------------------------------ 93 | ``` 94 | 注释:只返回符合条件的table1和table2的列 95 | 96 | 4.等价(与下列执行效果相同) 97 | ``` 98 | A:select a.*,b.* from table1 a,table2 b where a.id=b.id 99 | B:select * from table1 cross join table2 where table1.id=table2.id (注:cross join后加条件只能用where,不能用on) 100 | ``` 101 | 三、交叉连接(完全) 102 | 103 | 1.概念:没有 WHERE 子句的交叉联接将产生联接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。(table1和table2交叉连接产生3*3=9条记录) 104 | 105 | 2.交叉连接:cross join (不带条件where...) 106 | 107 | 3.sql语句 108 | ``` 109 | select * from table1 cross join table2 110 | -------------结果------------- 111 | idnameidscore 112 | ------------------------------ 113 | 1lee190 114 | 2zhang190 115 | 4wang190 116 | 1lee2100 117 | 2zhang2100 118 | 4wang2100 119 | 1lee370 120 | 2zhang370 121 | 4wang370 122 | ------------------------------ 123 | ``` 124 | 注释:返回3*3=9条记录,即笛卡尔积 125 | 126 | 4.等价(与下列执行效果相同) 127 | ``` 128 | A:select * from table1,table2 129 | ``` -------------------------------------------------------------------------------- /09.MySQL篇/9.1.6 数据库范式.md: -------------------------------------------------------------------------------- 1 | #### **题目**:数据库范式 2 | 3 | #### **参考答案**: 4 | 5 | 1 第一范式(1NF) 6 | 7 | 在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。 8 | 所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。简而言之,第一范式就是无重复的列。 9 | 10 | 2 第二范式(2NF) 11 | 12 | 第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键、主码。 13 | 第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是非主属性非部分依赖于主关键字。 14 | 15 | 3 第三范式(3NF) 16 | 17 | 满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性。(我的理解是消除冗余) -------------------------------------------------------------------------------- /09.MySQL篇/9.1.7 数据库优化的思路.md: -------------------------------------------------------------------------------- 1 | #### **题目**:数据库优化的思路 2 | 3 | #### **参考答案**: 4 | 5 | 这个我借鉴了慕课上关于数据库优化的课程。 6 | 7 | 1.SQL语句优化 8 | 9 | - 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。 10 | 11 | - 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: 12 | 13 | ```sql 14 | select id from t where num is null 15 | ``` 16 | 17 | 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: 18 | 19 | ```sql 20 | select id from t where num=0 21 | ``` 22 | *liueleven* 的评论: 23 | 24 | ``` 25 | 不是非我杠精,关于null,isNull,isNotNull其实是要看成本的,是否回表等因素总和考虑,才会决定是要走索引还是走全表扫描。 26 | ``` 27 | 28 | 也给大家找了一个作者的博文([MySQL中IS NULL、IS NOT NULL、!=不能用索引?胡扯!](https://mp.weixin.qq.com/s/CEJFsDBizdl0SvugGX7UmQ)),仅供参考!!! 29 | 30 | [zhiyong0804d的意见] 31 | 32 | 之所以未把第二条删除还是考虑可能很多人都被误导了。那这样的组织能让大家兼听则明。 33 | 34 | - 很多时候用 exists 代替 in 是一个好的选择。 35 | 36 | - 用Where子句替换HAVING 子句 因为HAVING 只会在检索出所有记录之后才对结果集进行过滤。 37 | 38 | 2.索引优化 39 | 40 | 看上文索引 41 | 42 | 3.数据库结构优化 43 | 44 | - 范式优化: 比如消除冗余(节省空间。。) 45 | 46 | - 反范式优化:比如适当加冗余等(减少join) 47 | 48 | - 拆分表:分区将数据在物理上分隔开,不同分区的数据可以制定保存在处于不同磁盘上的数据文件里。这样,当对这个表进行查询时,只需要在表分区中进行扫描,而不必进行全表扫描,明显缩短了查询时间,另外处于不同磁盘的分区也将对这个表的数据传输分散在不同的磁盘I/O,一个精心设置的分区可以将数据传输对磁盘I/O竞争均匀地分散开。对数据量大的时时表可采取此方法。可按月自动建表分区。 49 | 50 | - 拆分其实又分垂直拆分和水平拆分: 51 | 52 | 案例: 简单购物系统暂设涉及如下表: 53 | 54 | 1.产品表(数据量10w,稳定) 55 | 56 | 2.订单表(数据量200w,且有增长趋势) 57 | 58 | 3.用户表 (数据量100w,且有增长趋势) 59 | 60 | 以mysql为例讲述下水平拆分和垂直拆分,mysql能容忍的数量级在百万静态数据可以到千万 61 | 62 | **垂直拆分:** 63 | 64 | 解决问题:表与表之间的io竞争 65 | 66 | 不解决问题:单表中数据量增长出现的压力 67 | 68 | 方案: 把产品表和用户表放到一个server上 订单表单独放到一个server上 69 | 70 | **水平拆分:** 71 | 72 | 解决问题:单表中数据量增长出现的压力 73 | 74 | 不解决问题:表与表之间的io争夺 75 | 76 | 方案:**用户表** 通过性别拆分为男用户表和女用户表,**订单表** 通过已完成和完成中拆分为已完成订单和未完成订单,**产品表** 未完成订单放一个server上,已完成订单表盒男用户表放一个server上,女用户表放一个server上(女的爱购物 哈哈)。 77 | 78 | 4.服务器硬件优化 79 | 80 | 这个么多花钱咯! -------------------------------------------------------------------------------- /09.MySQL篇/9.1.8 存储过程与触发器的区别.md: -------------------------------------------------------------------------------- 1 | #### **题目**:存储过程与触发器的区别 2 | 3 | #### **参考答案**: 4 | 5 | 触发器与存储过程非常相似,触发器也是SQL语句集,两者唯一的区别是触发器不能用EXECUTE语句调用,而是在用户执行Transact-SQL语句时自动触发(激活)执行。 6 | 7 | 触发器是在一个修改了指定表中的数据时执行的存储过程。 8 | 9 | 通常通过创建触发器来强制实现不同表中的逻辑相关数据的引用完整性和一致性。由于用户不能绕过触发器,所以可以用它来强制实施复杂的业务规则,以确保数据的完整性。 10 | 11 | 触发器不同于存储过程,触发器主要是通过事件执行触发而被执行的,而存储过程可以通过存储过程名称名字而直接调用。当对某一表进行诸如UPDATE、INSERT、DELETE这些操作时,SQLSERVER就会自动执行触发器所定义的SQL语句,从而确保对数据的处理必须符合这些SQL语句所定义的规则。 -------------------------------------------------------------------------------- /09.MySQL篇/9.1.9 解释 SQL 的 left join 和 right join.md: -------------------------------------------------------------------------------- 1 | #### **题目**:解释 SQL 的 left join 和 right join 2 | 3 | #### 出题人:阿里巴巴新零售技术质量部 4 | 5 | #### **参考答案**: 6 | 7 | left join 和 right join 都是两个表进行 merge 的操作,left join 是将右边的表 merge 到左边,right join 是将左边的表 merge 到右边,通常我们会指定按照哪几列进行 merge 8 | 9 | 举个例子: 10 | 11 | **left table** 12 | 13 | | 姓名 | 学号 | 14 | | ---- | --------- | 15 | | 小红 | SZ1716029 | 16 | | 小明 | SZ1716030 | 17 | | 小王 | SZ1716031 | 18 | 19 | **right table** 20 | 21 | | 学号 | 排名 | 22 | | --------- | ---- | 23 | | SZ1716029 | 1 | 24 | | SZ1716030 | 2 | 25 | 26 | **left table** left join **right table** on 学号 27 | 28 | | 学号 | 姓名 | 排名 | 29 | | --------- | ---- | ---- | 30 | | SZ1716029 | 小红 | 1 | 31 | | SZ1716030 | 小明 | 2 | 32 | | SZ1716031 | 小王 | NULL | 33 | 34 | **left table** right join **right table** on 学号 35 | 36 | | 学号 | 姓名 | 排名 | 37 | | --------- | ---- | ---- | 38 | | SZ1716029 | 小红 | 1 | 39 | | SZ1716030 | 小明 | 2 | 40 | 41 | -------------------------------------------------------------------------------- /10.Redis篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/10.Redis篇/.gitkeep -------------------------------------------------------------------------------- /10.Redis篇/10.1.0 使用Redis有哪些好处?.md: -------------------------------------------------------------------------------- 1 | #### **题目**: 2 | 3 | #### **参考答案**: 4 | 5 | (1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) 6 | 7 | (2) 支持丰富数据类型,支持string,list,set,sorted set,hash 8 | 9 | (3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行 10 | 11 | (4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除 -------------------------------------------------------------------------------- /10.Redis篇/10.1.1 redis相比memcached有哪些优势?.md: -------------------------------------------------------------------------------- 1 | #### **redis相比memcached有哪些优势?**: 2 | 3 | #### **参考答案**: 4 | 5 | (1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型 6 | 7 | (2) redis的速度比memcached快很多 8 | 9 | (3) redis可以持久化其数据 -------------------------------------------------------------------------------- /10.Redis篇/10.1.2 redis常见性能问题和解决方案.md: -------------------------------------------------------------------------------- 1 | #### **题目**:redis常见性能问题和解决方案 2 | 3 | #### **参考答案**: 4 | 5 | (1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件 6 | 7 | (2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次 8 | 9 | (3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内 10 | 11 | (4) 尽量避免在压力很大的主库上增加从库 12 | 13 | (5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3... 14 | 15 | 这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。 16 | -------------------------------------------------------------------------------- /10.Redis篇/10.1.3 MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据.md: -------------------------------------------------------------------------------- 1 | #### **题目**:MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据 2 | 3 | #### **参考答案**: 4 | 5 | 相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略: 6 | 7 | voltile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰 8 | 9 | volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰 10 | 11 | volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰 12 | 13 | allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰 14 | 15 | allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰 16 | 17 | no-enviction(驱逐):禁止驱逐数据 18 | 19 | -------------------------------------------------------------------------------- /10.Redis篇/10.1.3 zookeeper的四种类型的znode.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zookeeper的四种类型的znode 2 | 3 | #### **参考答案**: 4 | 5 | 1、PERSISTENT-持久化目录节点 6 | 客户端与zookeeper断开连接后,该节点依旧存在 7 | 2、PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点 8 | 客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号 9 | 3、EPHEMERAL-临时目录节点 10 | 客户端与zookeeper断开连接后,该节点被删除 11 | 4、EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点 12 | 客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号 -------------------------------------------------------------------------------- /10.Redis篇/10.1.4 Memcache与Redis的区别都有哪些?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:Memcache与Redis的区别都有哪些? 2 | 3 | #### **参考答案**: 4 | 5 | 1)、存储方式 6 | 7 | Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。 8 | 9 | Redis有部份存在硬盘上,这样能保证数据的持久性。 10 | 11 | 2)、数据支持类型 12 | 13 | Memcache对数据类型支持相对简单。 14 | 15 | Redis有复杂的数据类型。 16 | 17 | 3)、使用底层模型不同 18 | 19 | 它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。 20 | 21 | Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。 22 | 23 | 4),value大小 24 | 25 | redis最大可以达到1GB,而memcache只有1MB -------------------------------------------------------------------------------- /10.Redis篇/10.1.5 Redis 常见的性能问题都有哪些?如何解决?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:Redis 常见的性能问题都有哪些?如何解决? 2 | 3 | #### **参考答案**: 4 | 5 | 1) Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。 6 | 7 | 2) Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。 8 | 9 | 3) Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。 10 | 11 | 4) Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内 -------------------------------------------------------------------------------- /10.Redis篇/10.1.6 redis最适合的场景.md: -------------------------------------------------------------------------------- 1 | #### **题目**:redis 最适合的场景 2 | 3 | #### **参考答案**: 4 | 5 | Redis最适合所有数据in-memory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用Memcached,何时使用Redis呢? 6 | 7 | 如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点: 8 | 9 | 1) Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。 10 | 2) Redis支持数据的备份,即master-slave模式的数据备份。 11 | 3) Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用 12 | -------------------------------------------------------------------------------- /10.Redis篇/10.1.7 Redis的同步机制了解么?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:Redis的同步机制了解么? 2 | 3 | #### **参考答案**: 4 | 5 | 主从同步。第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接受完成后将rdb镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。 6 | -------------------------------------------------------------------------------- /10.Redis篇/10.1.8 是否使用过Redis集群,集群的原理是什么?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:是否使用过Redis集群,集群的原理是什么? 2 | 3 | #### **参考答案**: 4 | 5 | Redis Sentinel着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。 6 | 7 | Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。 8 | -------------------------------------------------------------------------------- /11.MongoDB篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/.gitkeep -------------------------------------------------------------------------------- /11.MongoDB篇/11.1.0 什么是MongoDB?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:什么是MongoDB 2 | 3 | #### **参考答案**: 4 | 5 | MongoDB是一个文档数据库,提供好的性能,领先的非关系型数据库。采用BSON存储文档数据。2007年10月,MongoDB由10gen团队所发展。2009年2月首度推出。获得安装包和查看详细的API可以访问官网网址www.mongodb.com -------------------------------------------------------------------------------- /11.MongoDB篇/11.1.1 MongoDB是由哪种语言写的?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:MongoDB是由哪种语言写的 2 | 3 | #### **参考答案**: 4 | MongoDB用c++编写的,流行的开源数据库MySQL也是用C++开发的。C++1983年发行是一种使用广泛的计算机程序设计语言。它是一种通用程序设计语言,支持多重编程模式。 -------------------------------------------------------------------------------- /11.MongoDB篇/11.1.2 MongoDB的优势有哪些?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:MongoDB的优势有哪些 2 | 3 | #### **参考答案**: 4 | 5 | 面向文档的存储:文档存储以BSON格式(有大小限制,最大16M), 内置GridFS文件系统(一般存储大于16M的文件)。 6 | 7 | * 任何属性都可以建立索引。 8 | 9 | * 复制以及高可扩展性。 10 | 11 | * 自动分片。 12 | 13 | * 丰富的查询功能。 14 | 15 | * 快速的即时更新。 16 | 17 | * 来自 MongoDB 的专业支持。 18 | -------------------------------------------------------------------------------- /11.MongoDB篇/11.1.3 什么是数据库?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:什么是数据库 2 | 3 | #### **参考答案**: 4 | 5 | 数据库可以看成是一个电子化的文件柜,用户可以对文件中的数据运行新增、检索、更新、删除等操作。数据库是一个所有集合的容器,在文件系统中每一个数据库都有一个相关的物理文件。 -------------------------------------------------------------------------------- /11.MongoDB篇/11.1.4 什么是集合?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:什么是集合 2 | 3 | #### **参考答案**: 4 | 5 | 集合就是一组 MongoDB 文档。它相当于关系型数据库(RDBMS)中的表这种概念。集合位于单独的一个数据库中。一个集合内的多个文档可以有多个不同的字段。一般来说,集合中的文档都有着相同或相关的目的。 -------------------------------------------------------------------------------- /11.MongoDB篇/11.1.5 什么是文档?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:什么是文档 2 | 3 | #### **参考答案**: 4 | 5 | 文档由一组key value组成。文档是动态模式,这意味着同一集合里的文档不需要有相同的字段和结构。在关系型数据库中table中的每一条记录相当于MongoDB中的一个文档。 6 | -------------------------------------------------------------------------------- /11.MongoDB篇/11.1.6 MongoDB和关系型数据库术语对比图.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.1.6 MongoDB和关系型数据库术语对比图.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.1.7 什么是“mongod”?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:什么是”mongod“ 2 | 3 | #### **参考答案**: 4 | 5 | mongod是处理MongoDB系统的主要进程。它处理数据请求,管理数据存储,和执行后台管理操作。当我们运行mongod命令意味着正在启动MongoDB进程,并且在后台运行。 -------------------------------------------------------------------------------- /11.MongoDB篇/11.1.8 “mongod”参数有什么?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:"mongod"参数有什么 2 | 3 | #### **参考答案**: 4 | 5 | 传递数据库存储路径,默认是"/data/db" 6 | 端口号 默认是 "27017" -------------------------------------------------------------------------------- /11.MongoDB篇/11.1.9 什么是“mongo”?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:什么是"mongo" 2 | 3 | #### **参考答案**: 4 | 5 | 它是一个命令行工具用于连接一个特定的mongod实例。当我们没有带参数运行mongo命令它将使用默认的端口号和localhost连接。 6 | 7 | -------------------------------------------------------------------------------- /11.MongoDB篇/11.2.0 MongoDB哪个命令可以切换数据库?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:MongoDB哪个命令可以切换数据库 2 | 3 | #### **参考答案**: 4 | 5 | MongoDB 用use+数据库名称的方式来创建数据库。use会创建一个新的数据库,如果该数据库存在,则返回这个数据库。 6 | 7 | >use database_name -------------------------------------------------------------------------------- /11.MongoDB篇/11.2.1 什么是非关系型数据库?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:什么是非关系型数据库 2 | 3 | #### **参考答案**: 4 | 5 | 非关系型数据库是对不同于传统关系型数据库的统称。非关系型数据库的显著特点是不使用SQL作为查询语言,数据存储不需要特定的表格模式。由于简单的设计和非常好的性能所以被用于大数据和Web Apps等 -------------------------------------------------------------------------------- /11.MongoDB篇/11.2.2 非关系型数据库有哪些类型?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:非关系型数据库有哪些类型 2 | 3 | #### **参考答案**: 4 | 5 | * Key-Value 存储 Eg:Amazon S3 6 | 7 | * 图表 Eg:Neo4J 8 | 9 | * 文档存储 Eg:MongoDB 10 | 11 | * 基于列存储 Eg:Cassandra -------------------------------------------------------------------------------- /11.MongoDB篇/11.2.3 为什么用MOngoDB?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:为什么用MOngoDB? 2 | 3 | #### **参考答案**: 4 | 5 | * 架构简单 6 | 7 | * 没有复杂的连接 8 | 9 | * 深度查询能力,MongoDB支持动态查询。 10 | 11 | * 容易调试 12 | 13 | * 容易扩展 14 | 15 | * 不需要转化/映射应用对象到数据库对象 16 | 17 | * 使用内部内存作为存储工作区,以便更快的存取数据。 18 | -------------------------------------------------------------------------------- /11.MongoDB篇/11.2.4 在哪些场景使用MongoDB?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:在哪些场景使用MongoDB 2 | 3 | #### **参考答案**: 4 | 5 | * 大数据 6 | 7 | * 内容管理系统 8 | 9 | * 移动端Apps 10 | 11 | * 数据管理 12 | -------------------------------------------------------------------------------- /11.MongoDB篇/11.2.5 MongoDB中的命名空间是什么意思.md: -------------------------------------------------------------------------------- 1 | #### **题目**:MongoDB中的命名空间是什么意思? 2 | 3 | #### **参考答案**: 4 | 5 | MongoDB内部有预分配空间的机制,每个预分配的文件都用0进行填充。 6 | 7 | 数据文件每新分配一次,它的大小都是上一个数据文件大小的2倍,每个数据文件最大2G。 8 | 9 | MongoDB每个集合和每个索引都对应一个命名空间,这些命名空间的元数据集中在16M的*.ns文件中,平均每个命名占用约 628 字节,也即整个数据库的命名空间的上限约为24000。 10 | 11 | 如果每个集合有一个索引(比如默认的_id索引),那么最多可以创建12000个集合。如果索引数更多,则可创建的集合数就更少了。同时,如果集合数太多,一些操作也会变慢。 12 | 13 | 要建立更多的集合的话,MongoDB 也是支持的,只需要在启动时加上“--nssize”参数,这样对应数据库的命名空间文件就可以变得更大以便保存更多的命名。这个命名空间文件(.ns文件)最大可以为 2G。 14 | 15 | 每个命名空间对应的盘区不一定是连续的。与数据文件增长相同,每个命名空间对应的盘区大小都是随分配次数不断增长的。目的是为了平衡命名空间浪费的空间与保持一个命名空间数据的连续性。 16 | 17 | 需要注意的一个命名空间$freelist,这个命名空间用于记录不再使用的盘区(被删除的Collection或索引)。每当命名空间需要分配新盘区时,会先查看$freelist是否有大小合适的盘区可以使用,如果有就回收空闲的磁盘空间。 -------------------------------------------------------------------------------- /11.MongoDB篇/11.2.6 哪些语言支持MongoDB.md: -------------------------------------------------------------------------------- 1 | #### **题目** : 哪些语言支持MongoDB? 2 | 3 | #### **参考答案**: 4 | 5 | * C 6 | 7 | * C++ 8 | 9 | * C# 10 | 11 | * Java 12 | 13 | * Node.js 14 | 15 | * Perl 16 | 17 | * Php 等 18 | -------------------------------------------------------------------------------- /11.MongoDB篇/11.2.7 在MongoDB中如何创建一个新的数据库?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:在MongoDB中如何创建一个新的数据库 2 | 3 | #### **参考答案**: 4 | 5 | MongoDB 用 use + 数据库名称 的方式来创建数据库。use 会创建一个新的数据库,如果该数据库存在,则返回这个数据库。 6 | 7 | >use mydb 8 | switched to db mydb 9 | 10 | -------------------------------------------------------------------------------- /11.MongoDB篇/11.2.8 在MongoDB中如何查看数据库列表?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:在MongoDB中如何查看数据库列表 2 | 3 | #### **参考答案**: 4 | 5 | 使用命令"show dbs" 6 | 7 | >show dbs -------------------------------------------------------------------------------- /11.MongoDB篇/11.2.9 MongoDB中的分片是什么意思?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:MongoDB中的分片是什么意思 2 | 3 | #### **参考答案**: 4 | 5 | 分片是将数据水平切分到不同的物理节点。当应用数据越来越大的时候,数据量也会越来越大。当数据量增长时,单台机器有可能无法存储数据或可接受的读取写入吞吐量。利用分片技术可以添加更多的机器来应对数据量增加以及读写操作的要求。 6 | 7 | 参考:[https://docs.mongodb.com/manual/sharding/](https://docs.mongodb.com/manual/sharding/) -------------------------------------------------------------------------------- /11.MongoDB篇/11.3.0 如何查看使用MongoDB的连接?.md: -------------------------------------------------------------------------------- 1 | 如何查看使用MongoDB的连接Sharding - MongoDB Manual21.如何查看使用MongoDB的连接 2 | 3 | 使用命令"db.adminCommand(“connPoolStats”)" 4 | 5 | >db.adminCommand(“connPoolStats”) -------------------------------------------------------------------------------- /11.MongoDB篇/11.3.1 什么是复制?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.3.1 什么是复制?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.3.2 在MongoDB中如何在集合中插入一个文档?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.3.2 在MongoDB中如何在集合中插入一个文档?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.3.3 在MongoDB中如何除去一个数据库?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.3.3 在MongoDB中如何除去一个数据库?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.3.4 在MongoDB中如何创建一个集合?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.3.4 在MongoDB中如何创建一个集合?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.3.5 在MongoDB中如何查看一个已经创建的集合?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.3.5 在MongoDB中如何查看一个已经创建的集合?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.3.6 在MongoDB中如何删除一个集合?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.3.6 在MongoDB中如何删除一个集合?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.3.7 为什么要在MongoDB中使用分析器?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.3.7 为什么要在MongoDB中使用分析器?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.3.8 MongoDB支持主键外键关系吗?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.3.8 MongoDB支持主键外键关系吗?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.3.9 MongoDB支持哪些数据类型?.md: -------------------------------------------------------------------------------- 1 | + String 2 | + Integer 3 | + Double 4 | + Boolean 5 | + Object 6 | + Object ID 7 | + Arrays 8 | + Min/Max Keys 9 | + Datetime 10 | + Code 11 | + Regular Expression等 12 | -------------------------------------------------------------------------------- /11.MongoDB篇/11.4.0 为什么要在MongoDB中用Code数据类型?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.4.0 为什么要在MongoDB中用Code数据类型?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.4.1 为什么要在MongoDB中用Regular Expression数据类型?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.4.1 为什么要在MongoDB中用Regular Expression数据类型?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.4.2 为什么在MongoDB中使用Object ID数据类型?.md: -------------------------------------------------------------------------------- 1 | 不使用自增是分布式维护起来非常困难。使用ObjectId可以保证不同机器都能用全局唯一的同种方法生成它并且确保不重复 -------------------------------------------------------------------------------- /11.MongoDB篇/11.4.3 如何在集合中插入一个文档?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.4.3 如何在集合中插入一个文档?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.4.4 “ObjectID”有哪些部分组成?.md: -------------------------------------------------------------------------------- 1 | 一共有四部分组成:时间戳、客户端ID、客户进程ID、三个字节的增量计数器 2 | -------------------------------------------------------------------------------- /11.MongoDB篇/11.4.5 在MongoDb中什么是索引?.md: -------------------------------------------------------------------------------- 1 | 索引是为了解决数据搜索效率低下引入的一种特殊的数据结构。索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。简单的说,索引就是将`文档`按照某个(或某些)字段顺序组织起来,以便能根据该字段高效的查询。 2 | 3 | -------------------------------------------------------------------------------- /11.MongoDB篇/11.4.6 如何添加索引?.md: -------------------------------------------------------------------------------- 1 | MongoDB支持多种类型的索引,包括单字段索引、复合索引、多key索引、文本索引等,每种类型的索引有不同的使用场合。 2 | 3 | 按照类型可分为: 4 | 5 | 1. 单字段索引 6 | 7 | ```db.person.createIndex( {age: 1} ) ``` 8 | 9 | 对`person`集合建立对`age`的索引。 10 | 11 | `{age: 1}` 代表升序索引,也可以通过`{age: -1}`来指定降序索引,对于单字段索引,升序/降序效果是一样的。 12 | 13 | 2. 复合索引 14 | 15 | ``` db.person.createIndex( {age: 1, name: 1} ) ``` 16 | 17 | 他是单字段索引的升级,可以对多个字段进行索引。按第一个字段排序,第一个字段相同的文档按第二个字段排序。 18 | 19 | 3. 多key索引 20 | 21 | ``` 22 | {"name" : "jack", "age" : 19, habbit: ["football, runnning"]} 23 | db.person.createIndex( {habbit: 1} ) // 自动创建多key索引 24 | db.person.find( {habbit: "football"} ) 25 | ``` 26 | 27 | 当索引的字段为数组时,创建出的索引称为多key索引,多key索引会为数组的每个元素建立一条索引,比如person表加入一个`habbit`字段(数组)用于描述兴趣爱好,需要查询有相同兴趣爱好的人就可以利用`habbit`字段的多key索引。 28 | 29 | 4. 其他索引 30 | 31 | -------------------------------------------------------------------------------- /11.MongoDB篇/11.4.7 MongoDB有哪些可替代产品?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.4.7 MongoDB有哪些可替代产品?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.4.8 如何查询集合中的文档?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.4.8 如何查询集合中的文档?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.4.9 用什么方法可以格式化输出结果?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.4.9 用什么方法可以格式化输出结果?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.5.0 如何使用AND或OR条件循环查询集合中的文档?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.5.0 如何使用AND或OR条件循环查询集合中的文档?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.5.1 在MongoDB中如何更新数据?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.5.1 在MongoDB中如何更新数据?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.5.2 如何删除文档?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.5.2 如何删除文档?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.5.3 在MongoDB中如何排序?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.5.3 在MongoDB中如何排序?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.5.4 什么是聚合?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.5.4 什么是聚合?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.5.5 在MongoDB中什么是副本集?.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.5.5 在MongoDB中什么是副本集?.md -------------------------------------------------------------------------------- /11.MongoDB篇/11.5.6 Mongodb存储特性与内部原理.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/11.MongoDB篇/11.5.6 Mongodb存储特性与内部原理.md -------------------------------------------------------------------------------- /12.Zookeeper篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/12.Zookeeper篇/.gitkeep -------------------------------------------------------------------------------- /12.Zookeeper篇/12.1.0 zookeeper是什么?.md: -------------------------------------------------------------------------------- 1 | #### **参考答案**: 2 | 3 | > A high-performance coordination service for distributed applications 4 | 5 | Zookeeper是基于Google Chubby论文的开源实现,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、配置管理 等等。 6 | 由于Hadoop生态系统中很多项目都依赖于zookeeper,如Pig,Hive等, 似乎很像一个动物园管理员,于是取名为Zookeeper。 7 | -------------------------------------------------------------------------------- /12.Zookeeper篇/12.1.1 zookeeper提供了什么?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zookeeper提供了什么? 2 | 3 | #### **参考答案**: 4 | 5 | 1、文件系统 6 | 2、通知机制 7 | -------------------------------------------------------------------------------- /12.Zookeeper篇/12.1.2 zookeeper文件系统.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zookeeper文件系统 2 | 3 | #### **参考答案**: 4 | 5 | zookeeper提供一个类似unix文件系统目录的多层级节点命名空间(节点称为znode)。与文件系统不同的是,这些节点都可以设置关联的数据,而文件系统中只有文件节点可以存放数据而目录节点不行。zookeeper为了保证高吞吐和低延迟,在内存中维护了这个树状的目录结构,这种特性使得zookeeper不能用于存放大量的数据,每个节点的存放数据上限为1M。 -------------------------------------------------------------------------------- /12.Zookeeper篇/12.1.3 zookeeper的四种类型的znode.md: -------------------------------------------------------------------------------- 1 | #### 题目:zookeeper的四种类型的znode 2 | 3 | #### 参考答案: 4 | 5 | PERSISTENT 持久化节点 6 | 7 | PERSISTENT_SEQUENTIAL 顺序自动编号持久化节点,这种节点会根据当前已存在的节点数自动加 1 8 | 9 | EPHEMERAL 临时节点, 客户端session超时这类节点就会被自动删除 10 | 11 | EPHEMERAL_SEQUENTIAL 临时自动编号节点 -------------------------------------------------------------------------------- /12.Zookeeper篇/12.1.4 zookeeper通知机制.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zookeeper通知机制 2 | 3 | #### **参考答案**: 4 | 5 | client端会对某个znode建立一个watcher事件,当该znode发生变化时,zk会主动通知watch这个znode的client,然后client根据znode的变化来做出业务上的改变等。 6 | 7 | #### watcher的特点: 8 | - 轻量级:一个callback函数。 9 | - 异步性:不会block正常的读写请求。 10 | - 主动推送:Watch被触发时,由Zookeeper服务端主动将更新推送给客户端。 11 | - 一次性:数据变化时,Watch只会被触发一次。如果客户端想得到后续更新的通知,必须要在 Watch 被触发后重新注册一个 Watch。 12 | - 仅通知:仅通知变更类型,不附带变更后的结果。 13 | - 顺序性:如果多个更新触发了多个Watch,那 Watch 被触发的顺序与更新顺序一致。 14 | 15 | #### 使用watch的注意事项: 16 | - 由于watcher是一次性的,所以需要自己去实现永久watch 17 | - 如果被watch的节点频繁更新,会出现“丢数据”的情况 18 | - watcher数量过多会导致性能下降 19 | -------------------------------------------------------------------------------- /12.Zookeeper篇/12.1.5 zookeeper有哪些应用场景?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zookeeper有哪些应用场景 2 | 3 | #### **参考答案**: 4 | 5 | 1、名字服务 6 | 7 | 2、配置管理 8 | 9 | 3、集群管理 10 | 11 | 4、分布式锁 12 | 13 | 5、队列管理 14 | 15 | 6、消息订阅 16 | -------------------------------------------------------------------------------- /12.Zookeeper篇/12.1.6 zk的命名服务.md: -------------------------------------------------------------------------------- 1 | #### **题目**: zk的命名服务 2 | 3 | #### **参考答案**: 4 | 5 | 命名服务是指通过指定的名字来获取资源或者服务的地址,利用zk创建一个全局的路径,即是唯一的路径,这个路径就可以作为一个名字,指向集群中的集群,提供的服务的地址,或者一个远程的对象等等。 -------------------------------------------------------------------------------- /12.Zookeeper篇/12.1.7 zk的配置管理服务.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zk的配置管理 2 | 3 | #### **参考答案**: 4 | 5 | 程序分布式的部署在不同的机器上,将程序的配置信息放在zk的znode下,当有配置发生改变时,也就是znode发生变化时,可以通过改变zk中某个目录节点的内容,利用watcher通知给各个客户端,从而更改配置。 -------------------------------------------------------------------------------- /12.Zookeeper篇/12.1.8 zk的集群管理.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zookeeper集群管理 2 | 3 | #### **参考答案**: 4 | 5 | 所谓集群管理无在乎两点:是否有机器退出和加入、选举master。 6 | 对于第一点,所有机器约定在父目录下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道:它上船了。 7 | 新机器加入也是类似,所有机器收到通知:新兄弟目录加入,highcount又有了,对于第二点,我们稍微改变一下,所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好。 -------------------------------------------------------------------------------- /12.Zookeeper篇/12.1.9 zk的分布式锁.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zookeeper分布式锁 2 | 3 | #### **参考答案**: 4 | 5 | 有了zookeeper的一致性文件系统,锁的问题变得容易。锁服务可以分为两类,一个是保持独占,另一个是控制时序。 6 | 对于第一类,我们将zookeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建的distribute_lock 节点就释放出锁。 7 | 对于第二类, /distribute_lock 已经预先存在,所有客户端在它下面创建临时顺序编号目录节点,和选master一样,编号最小的获得锁,用完删除,依次方便。 8 | 9 | **获取分布式锁的流程** 10 | 11 | 12 | 13 | 在获取分布式锁的时候在locker节点下创建临时顺序节点,释放锁的时候删除该临时节点。客户端调用createNode方法在locker下创建临时顺序节点, 14 | 然后调用getChildren(“locker”)来获取locker下面的所有子节点,注意此时不用设置任何Watcher。客户端获取到所有的子节点path之后,如果发现自己创建的节点在所有创建的子节点序号最小,那么就认为该客户端获取到了锁。如果发现自己创建的节点并非locker所有子节点中最小的,说明自己还没有获取到锁,此时客户端需要找到比自己小的那个节点,然后对其调用exist()方法,同时对其注册事件监听器。之后,让这个被关注的节点删除,则客户端的Watcher会收到相应通知,此时再次判断自己创建的节点是否是locker子节点中序号最小的,如果是则获取到了锁,如果不是则重复以上步骤继续获取到比自己小的一个节点并注册监听。当前这个过程中还需要许多的逻辑判断。 15 | 16 | 17 | 18 | 代码的实现主要是基于互斥锁,获取分布式锁的重点逻辑在于BaseDistributedLock,实现了基于Zookeeper实现分布式锁的细节。 19 | -------------------------------------------------------------------------------- /12.Zookeeper篇/12.2.0 zk队列管理.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zk队列管理 2 | 3 | #### **参考答案**: 4 | 5 | 两种类型的队列: 6 | 1、同步队列,当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。 7 | 2、队列按照 FIFO 方式进行入队和出队操作。 8 | 第一类,在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。 9 | 第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。在特定的目录下创建PERSISTENT_SEQUENTIAL节点,创建成功时Watcher通知等待的队列,队列删除序列号最小的节点用以消费。此场景下Zookeeper的znode用于消息存储,znode存储的数据就是消息队列中的消息内容,SEQUENTIAL序列号就是消息的编号,按序取出即可。由于创建的节点是持久化的,所以不必担心队列消息的丢失问题。 -------------------------------------------------------------------------------- /12.Zookeeper篇/12.2.1 zk数据复制.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zk数据复制 2 | 3 | #### **参考答案**: 4 | 5 | Zookeeper作为一个集群提供一致的数据服务,自然,它要在所有机器间做数据复制。 6 |
7 | 数据复制的好处: 8 |
9 | 1、容错:一个节点出错,不致于让整个系统停止工作,别的节点可以接管它的工作; 10 |
11 | 2、提高系统的扩展能力 :把负载分布到多个节点上,或者增加节点来提高系统的负载能力; 12 |
13 | 3、提高性能:让客户端本地访问就近的节点,提高用户访问速度。 14 |
15 |
16 | 17 | 从客户端读写访问的透明度来看,数据复制集群系统分下面两种: 18 |
19 | 1、写主(WriteMaster) :对数据的修改提交给指定的节点。读无此限制,可以读取任何一个节点。这种情况下客户端需要对读与写进行区别,俗称读写分离; 20 |
21 | 2、写任意(Write Any):对数据的修改可提交给任意的节点,跟读一样。这种情况下,客户端对集群节点的角色与变化透明。 22 |
23 | 24 | 对zookeeper来说,它采用的方式是写任意。通过增加机器,它的读吞吐能力和响应能力扩展性非常好,而写,随着机器的增多吞吐能力肯定下降(这也是它建立observer的原因),而响应能力则取决于具体实现方式,是延迟复制保持最终一致性,还是立即复制快速响应。 25 | -------------------------------------------------------------------------------- /12.Zookeeper篇/12.2.2 zk中zab的工作原理.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zk中zab的工作原理 2 | 3 | #### **参考答案**: 4 | 5 | ZAB 是 ZooKeeper Atomic Broadcast (ZooKeeper 原子广播协议)的缩写,它是特别为 ZooKeeper 设计的崩溃可恢复的原子消息广播算法。ZooKeeper 使用 Leader来接收并处理所有事务请求,并采用 ZAB 协议,将服务器数据的状态变更以事务 Proposal 的形式广播到所有的 Follower 服务器上去。这种主备模型架构保证了同一时刻集群中只有一个服务器广播服务器的状态变更,因此能够很好的保证事物的完整性和顺序性。 6 | 7 | Zab协议有两种模式,它们分别是恢复模式(recovery)和广播模式(broadcast)。当服务启动或者在leader崩溃后,Zab就进入了恢复模式,当leader被选举出来,且大多数follower完成了和leader的状态同步以后, 恢复模式就结束了,ZAB开始进入广播模式。 8 | -------------------------------------------------------------------------------- /12.Zookeeper篇/12.2.3 zk是如何保证事务的顺序一致性.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zookeeper是如何保证事务的顺序一致性的? 2 | 3 | #### **参考答案**: 4 | 5 | zookeeper采用了递增的事务Id来标识,所有的proposal(提议)都在被提出的时候加上了zxid,zxid实际上是一个64位的数字,高32位是epoch(时期; 纪元; 世; 新时代)用来标识leader是否发生改变,如果有新的leader产生出来,epoch会自增,低32位用来递增计数。当新产生proposal的时候,会依据数据库的两阶段过程,首先会向其他的server发出事务执行请求,如果超过半数的机器都能执行并且能够成功,那么就会开始执行。 6 | -------------------------------------------------------------------------------- /12.Zookeeper篇/12.2.4 zk集群下server工作状态.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zk集群下server工作状态 2 | 3 | #### **参考答案**: 4 | 5 | 每个Server在工作过程中有四种状态: 6 | 7 | LOOKING:当前Server不知道leader是谁,正在搜寻 8 | 9 | LEADING:当前server角色为leader 10 | 11 | FOLLOWING:当前server角色为follower 12 | 13 | OBSERVING:当前server角色为observer 14 | -------------------------------------------------------------------------------- /12.Zookeeper篇/12.2.5 zk是如何选举Leader的?.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zookeeper是如何选举Leader的? 2 | 3 | #### **参考答案**: 4 | 5 | 当leader崩溃或者leader失去大多数的follower,这时zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的Server都恢复到一个正确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos。 6 | 7 | 1、Zookeeper选主流程(basic paxos) 8 | (1)选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server; 9 | (2)选举线程首先向所有Server发起一次询问(包括自己); 10 | (3)选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中; 11 | (4)收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server; 12 | (5)线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数,设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。 通过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于n+1. 每个Server启动后都会重复以上流程。在恢复模式下,如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信息,zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复。 13 | 14 | 15 | 16 | 2、Zookeeper选主流程(fast paxos) 17 | fast paxos流程是在选举过程中,某Server首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和 zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。 18 | 19 | 20 | -------------------------------------------------------------------------------- /12.Zookeeper篇/12.2.6 zk同步流程.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zookeeper同步流程 2 | 3 | #### **参考答案**: 4 | 5 | 选完Leader以后,zk就进入状态同步过程。 6 | 7 | 1. Leader等待Follower和Observer连接; 8 | 9 | 2. Follower连接leader,将最大的zxid发送给leader; 10 | 11 | 3. Leader根据follower的zxid确定同步点; 12 | 13 | 4. 完成同步后通知follower 已经成为uptodate状态; 14 | 15 | 5. Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。 16 | 17 | 18 | 19 | 20 | 数据同步的4种方式: 21 | 22 | 1、SNAP-全量同步 23 | - 条件:peerLastZxidmaxCommittedLog 32 | - 说明:证明follower上有些提议proposal并未在leader上提交,follower需要回滚到zxid为maxCommittedLog对应的事务操作 33 | 34 | 4、TRUNC+DIFF-回滚+增量同步 35 | - 条件:minCommittedLog<=peerLastZxid<=maxCommittedLog 36 | - 说明:leader a已经将事务truncA提交到本地事务日志中,但没有成功发起proposal协议进行投票就宕机了;然后集群中剔除原leader a重新选举出新leader b,又提交了若干新的提议proposal,然后原leader a重新服务又加入到集群中说明:此时a,b都有一些对方未提交的事务,若b是leader, a需要先回滚truncA然后增量同步新leader b上的数据。 37 | -------------------------------------------------------------------------------- /12.Zookeeper篇/12.2.7 分布式通知和协调.md: -------------------------------------------------------------------------------- 1 | #### **题目**:分布式通知和协调 2 | 3 | #### **参考答案**: 4 | 5 | 对于系统调度来说:操作人员发送通知实际是通过控制台改变某个节点的状态,然后zk将这些变化发送给注册了这个节点的watcher的所有客户端。 6 | 7 | 对于执行情况汇报:每个工作进程都在某个目录下创建一个临时节点。并携带工作的进度数据,这样汇总的进程可以监控目录子节点的变化获得工作进度的实时的全局情况。 -------------------------------------------------------------------------------- /12.Zookeeper篇/12.2.8 zk的session机制.md: -------------------------------------------------------------------------------- 1 | #### **题目**:zk的session机制 2 | 3 | #### **参考答案**: 4 | 5 | zookeeper会为每个客户端分配一个session,类似于web服务器一样,用来标识客户端的身份。 6 | 7 | session的作用: 8 | 9 | 10 | - 客户端标识 11 | - 超时检查 12 | - 请求的顺序执行 13 | - 维护临时节点的生命周期 14 | - watcher通知 15 | 16 | session的状态: 17 | 18 | - CONNECTING 19 | - CONNECTED 20 | - RECONNECTING 21 | - RECONNECTED 22 | - CLOSED 23 | 24 | session的属性: 25 | 26 | - SessionID:会话ID,全局唯一 27 | - TimeOut:会话超时时间 28 | - TickTime:下次会话超时时间点 29 | - isClosing:会话是否已经被关闭 30 | 31 | sessionID的构成: 32 | 33 | - 高8位代表创建Session时所在的zk节点的id 34 | - 中间40位代表zk节点当前角色在创建的时候的时间戳 35 | - 低16位是一个计数器,初始值为0 36 | -------------------------------------------------------------------------------- /12.Zookeeper篇/zk_distributed_locker1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/12.Zookeeper篇/zk_distributed_locker1.png -------------------------------------------------------------------------------- /12.Zookeeper篇/zk_distributed_locker2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/12.Zookeeper篇/zk_distributed_locker2.png -------------------------------------------------------------------------------- /12.Zookeeper篇/zk_sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/12.Zookeeper篇/zk_sync.png -------------------------------------------------------------------------------- /12.Zookeeper篇/zk_zab_basic_paxos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/12.Zookeeper篇/zk_zab_basic_paxos.png -------------------------------------------------------------------------------- /12.Zookeeper篇/zk_zab_fast_paxos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/12.Zookeeper篇/zk_zab_fast_paxos.png -------------------------------------------------------------------------------- /13.Nginx篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/13.Nginx篇/.gitkeep -------------------------------------------------------------------------------- /14.算法篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/14.算法篇/.gitkeep -------------------------------------------------------------------------------- /15.内存篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/15.内存篇/.gitkeep -------------------------------------------------------------------------------- /16.CPU篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/16.CPU篇/.gitkeep -------------------------------------------------------------------------------- /17.磁盘篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/17.磁盘篇/.gitkeep -------------------------------------------------------------------------------- /18.网络通信篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/18.网络通信篇/.gitkeep -------------------------------------------------------------------------------- /19.安全篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/19.安全篇/.gitkeep -------------------------------------------------------------------------------- /20.并发篇/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/20.并发篇/.gitkeep -------------------------------------------------------------------------------- /21.面经/2020秋招面经总结.md: -------------------------------------------------------------------------------- 1 | 2 | @[LiuYongQiang6](https://github.com/LiuYongQiang6) 3 | 4 | # 目标岗位 5 | 本硕均为机电专业相关,比赛和项目也是软硬件结合,个人软开背景中学已经学过pascal和数据结构与算法,大学本科除了C语言和微机原理基本没学过CS相关课程,研究生才把操作系统、组原以及计算机网络补上,顺便补了个c++,抽空玩linux,秋招前3个月开始刷题(牛客300,力扣350)。 6 | **第一目标岗位:嵌入式软件。** 7 |
8 | **第二目标岗位:C++后台开发。** 9 |
10 | **第三目标岗位:游戏相关岗位以及硬件。** 11 |
12 | 13 | 投递公司:大疆深圳(嵌入式软件,offer),华为杭州(操作系统内核开发,offer,签约),小米武汉(物联网嵌入式软件,offer),远景智能(C++后台,offer),网易雷火游戏服务器提前批(笔试挂),网易雷火游戏测试开发(offer),中兴南京(软件开发,offer),网易互娱游戏策划(一面挂),腾讯(c++后台,笔试挂),oppo(c/c++软件开发,笔试通过拒绝面试),小马智行/图森未来(简历石沉大海),株洲中车时代电气(大数据智能部门?,offer),。 14 | 15 | ## 前期准备 16 | 17 | 今年秋招前期体验十分艰难,十分庆幸当时没有轻信师兄做深度学习,学完吴恩达的机器学习课程及时刹车选择了做自己喜欢的嵌入式linux开发方向,顺便利用学习下来的东西一个人参加了下中兴算法大赛,摸了个名次,并且找了个学校附近的物联网公司做嵌入式linux的实习,下班复习基础与刷题: 18 |
19 | **1. 笔试刷题** ,非常重要,不然面试机会都没有,leetcode感觉是普通应用题,实际笔试可能是综合应用题,我采取的是专题速刷,半个月回顾一次; 20 |
21 | **2. 专业面试准备** ,重点复习数据结构、操作系统与计算机网络,我采取的方式先看别人的面经总结,并结合笔记,最后结合书籍构建系统,有时间可以看看源码,个人除了后台相关重点关注了嵌入式相关的总结以及linux源码分析,深入理解linux内核,linux驱动开发。 22 |
23 | **3. 综合面试准备**,个人项目精炼,个人职责,亮点总结,个人项目介绍从结构、硬件、软件角度分析,完成的工作,可采用第一点、第二点等方法表示,个人项目逐点介绍采用为什么?怎么做?取得的效果?流程介绍,并准备一两个超级亮点和超级难点(你并未解决)。 24 | 25 | 26 | ## 面经 27 | **1.大疆**: 28 |
29 | **一面**,仔细询问笔试细节,并且挖深,被仔细询问了在笔试中用的bitmap算法,为何要用,有什么特点,怎么做的,然后抓住linux驱动开发项目追问细节,并引申,open/read/write等函数具体是怎么工作的,从用户态的系统调用闻到内核态的数据结构,基数树等,内存管理相关问到了linux系统中页缓存、缓存命中以及mmap相关的问题,比如两个大文件需要进行交互如何做,中断的上半部以及下半部等,为何要设置上半部和下半部,怎么做的,自旋锁和互斥锁的区别以及应用场景,如何实现一把自旋锁。 30 |
31 | **二面**,基本就是问项目,RM比赛中学到了什么,比赛看了没有,觉得有什么问题,哪些可以改进,如果让你重新设计一个机器人,你希望设计出什么新功能可以在比赛中取到突出的效果。项目中涉及到硬件电路设计,被问到了信号链如何分析以及电源管理如何设计,开关电源与线性稳压器的对比,能接受提前实习么? 32 |
33 | **三面**,应该是个pm,项目介绍,你觉得你做的最好的是哪块,最差的是哪块,个人优缺点,合作中出现问题应该怎么做,然后就是介绍公司业务和发展。 34 |
35 | 36 | **2.华为:** 37 |
38 | **一面**,笔试回顾,个人情况特殊,笔试40分钟A了两个题便出去做oppo笔试,第三题没看,面试官看提交情况很好,只有3次提交,便放我一马,没问第三题,然后询问项目,细节记不大清,都是基本操作,最后做算法题,leetcode原题,打家劫舍,简单动态规划,分析一下算法复杂度。 39 |
40 | **二面**,说一面面试官评价不错,直接跳过了项目介绍与询问,问中学时候参加信息学竞赛的经历以及中兴算法大赛,最后环节是算法题,消灭进程树,hash表加队列。 41 |
42 | **三面**,项目介绍,什么是一份好的代码,了解操作系统么,做过哪些相关的工作,看过哪些相关的书籍。 43 |
44 | 45 | **3.小米**: 46 |
47 | **一面**,询问项目细节,RTOS与linux的区别,如果让你写一个RTOS你应该写哪些功能,哪些是必须的,会用到哪些重要的数据结构,指针熟悉么,和C++中的引用的区别,什么时候用二级指针,C++中动态数组vector是怎么实现的,C语言中的设计模式了解么,最后做了一个简单的题,找出区间内乘积最大的两个素数。 48 |
49 | **二面**,基本是项目,没啥印象了,然后问拿了哪些offer。 50 |
51 | 52 | **4.远景**: 53 |
54 | **一面**,项目细节,三次握手以及四次挥手,超时重传算法,如何给一个超大文件进行排序,hash分桶; 55 |
56 | **二面**,跟大疆三面差不多; 57 |
58 | **三面**,跟hr聊天; 59 |
60 | **终面**,会什么,能做什么,然后就是岗位介绍画饼。 61 |
62 | 63 | ## 总结 64 | 时间过了太久,只有大疆印象深刻,其他基本忘得差不多,网易雷火游戏测试那部分虽然5面,刷人较多,但是看完牛客上的面经应该问题不大,唯一有点难度的是总监面时的算法题,当时做的一个dfs,比较复杂,分4种情况。中兴和中车感觉只要是个985应该问题不大,中兴一面讲了一下epoll的实现面试官眼睛都亮了,强行给我加上了南京的软件岗,中车同上,背景相关即可。 65 | 66 | 后台面试虽然准备了很多,但是由于基本找的都是C相关的底层岗位,基本没怎么问,redis和ngix基本没问,数据库相关的问题基本没碰到,可能第一目标岗位面试比较顺利便没怎么投C++后台相关的岗位开发,简历上基本没写C++后台相关的项目。 67 |
68 | 69 | **以上**,重点还是代码基础,也就是数据结构和算法,和项目结合的代码的逻辑实现,CS基础知识个人认为自己用的少的把面经看完即可,把自己做的项目细节融汇贯通,能抗住连环5问即可,答不上来避免强答,然后整理思路理清条理,平时多思考为什么怎么做有什么效果,然后干净一点吐词清晰即可,给自己一个好的面试体验以及给面试官一个好的面试体验,回答的时候尽量看着面试官(虽然有时候面试官在敲代码),最后,网易的小姐姐很漂亮。 70 | 71 | 72 | -------------------------------------------------------------------------------- /arch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/arch.jpg -------------------------------------------------------------------------------- /contact.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0voice/interview_internal_reference/9fe6c758e98c03c40c8908c39e78ab98a7ab53d6/contact.jpg -------------------------------------------------------------------------------- /sync_link: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Author: ileler@qq.com 4 | import re 5 | from shutil import move 6 | from urllib import parse 7 | from pathlib import Path 8 | 9 | class REMatcher(object): 10 | def __init__(self, matchstring): 11 | self.matchstring = matchstring 12 | 13 | def match(self,regexp): 14 | self.rematch = re.match(regexp, self.matchstring) 15 | return bool(self.rematch) 16 | 17 | def group(self,i): 18 | return self.rematch.group(i) 19 | 20 | def get_path(name): 21 | try: 22 | files = Path('./').glob('**/%s.md' % name) 23 | for file in files: 24 | return str(file) 25 | except: 26 | pass 27 | return None 28 | 29 | prefix = '##### ' 30 | filepath = './README.md' 31 | temppath = filepath + '.tmp' 32 | with open(filepath, 'r') as lines: 33 | with open(temppath, 'w') as file: 34 | for line in lines: 35 | m1 = REMatcher(line) 36 | if not m1.match(r'%s(.*)' % prefix): 37 | file.write(line) 38 | continue 39 | name = m1.group(1) 40 | m2 = REMatcher(name) 41 | if m2.match(r'\[(.*)\]\((.*)\)'): 42 | name = m2.group(1) 43 | path = get_path(name) 44 | file.write(('%s[%s](%s)\n' % (prefix, name, parse.quote(path))) if path else line) 45 | move(temppath, filepath) 46 | --------------------------------------------------------------------------------