Repository: woniu201/interview-reference Branch: main Commit: be356dcbc2d6 Files: 148 Total size: 116.2 KB Directory structure: gitextract_tmzb99tl/ ├── 01.阿里篇/ │ ├── 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.华为篇/ │ ├── 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.百度篇/ │ ├── 3.4.8 找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数。.md │ └── 3.4.9 找出被修改过的数字.md ├── 04.腾讯篇/ │ ├── 4.1.0 JAVA中的几种基本数据类型是什么,各自占用多少字节.md │ ├── 4.1.1 String类能被继承吗,为什么.md │ ├── 4.1.2 String,Stringbuffer,StringBuilder的区别.md │ ├── 4.1.3 ArrayList和LinkedList有什么区别.md │ ├── 4.1.4 讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,当new的时候,他们的执行顺序.md │ ├── 4.1.5 用过哪些Map类,都有什么区别,HashMap是线程安全的吗,并发下使用的Map是什么,他们内部原理分别是什么,比如存储方式,hashcode,扩容,默认容量等.md │ ├── 4.1.6 JAVA8的ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何设计.md │ ├── 4.1.7有没有有顺序的Map实现类,如果有,他们是怎么保证有序的.md │ ├── 4.1.8抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口么.md │ ├── 4.1.9继承和聚合的区别在哪.md │ ├── 4.2.0IO模型有哪些,讲讲你理解的nio,他和bio,aio的区别是啥,谈谈reactor模型.md │ ├── 4.2.1反射的原理,反射创建类实例的三种方式是什么.md │ ├── 4.2.2反射中,Class.forName和ClassLoader区别.md │ └── 4.2.3描述动态代理的几种实现方式,分别说出相应的优缺点.md ├── 05.美团篇/ │ └── 5.2.0 浅复制和深复制?怎样实现深复制?.md ├── 06.字节跳动篇/ │ └── 一棵二叉树,求最大通路长度(即最大左右子树高度之和).md ├── 08.京东篇/ │ └── 简单说一下hadoop和spark的shuffle过程.md ├── 09.MySQL篇/ │ ├── 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篇/ │ ├── 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篇/ │ ├── 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篇/ │ ├── 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 ├── 21.面经/ │ └── 2020秋招面经总结.md └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: 01.阿里篇/1.1.1 如何实现一个高效的单向链表逆序输出?.md ================================================ ##### **问题**:如何实现一个高效的单向链表逆序输出? ##### **出题人**:阿里巴巴出题专家:昀龙/阿里云弹性人工智能负责人 ##### **参考答案**:下面是其中一种写法,也可以有不同的写法,比如递归等。供参考。 ``` typedef struct node{ int data; struct node* next; node(int d):data(d), next(NULL){} }node; void reverse(node* head) { if(head == NULL){ return; } node* pleft = NULL; node* pcurrent = head; node* pright = head->next; while(pright){ pcurrent->next = pleft; node *ptemp = pright->next; pright->next = pcurrent; pleft = pcurrent; pcurrent = pright; pright = ptemp; } while(pcurrent != NULL){ cout<< pcurrent->data << "\t"; pcurrent = pcurrent->next; } } ``` ``` java class Solution { public void reverse(ListNode head) { if (head == null || head.next == null) { return ; } ListNode currentNode = head; Stack> stack = new Stack<>(); while (currentNode != null) { stack.push(currentNode); ListNode tempNode = currentNode.next; currentNode.next = null; // 断开连接 currentNode = tempNode; } head = stack.pop(); currentNode = head; while (!stack.isEmpty()) { currentNode.next = stack.pop(); currentNode = currentNode.next; } } } class ListNode{ T val; public ListNode(T val) { this.val = val; } ListNode next; } ``` ================================================ FILE: 01.阿里篇/1.1.2 已知sqrt(2)约等于1.414,要求不用数学库,求sqrt(2)精确到小数点后10位.md ================================================ #### **题目**:已知 sqrt (2)约等于 1.414,要求不用数学库,求 sqrt (2)精确到小数点后 10 位。 #### **出题人**:——阿里巴巴出题专家:文景/阿里云 CDN 资深技术专家 #### **参考答案**: #### * 考察点 1. 基础算法的灵活应用能力(二分法学过数据结构的同学都知道,但不一定往这个方向考虑;如果学过数值计算的同学,应该还要能想到牛顿迭代法并解释清楚) 2. 退出条件设计 #### 二分法 ##### 1. 已知 sqrt(2)约等于 1.414,那么就可以在(1.4, 1.5)区间做二分 查找,如: a) high=>1.5 b) low=>1.4 c) mid => (high+low)/2=1.45 d) 1.45*1.45>2 ? high=>1.45 : low => 1.45 e) 循环到 c) ##### 2. 退出条件 a) 前后两次的差值的绝对值<=0.0000000001, 则可退出 ``` const double EPSILON = 0.0000000001; double sqrt2() { double low = 1.4, high = 1.5; double mid = (low + high) / 2; while (high - low > EPSILON) { if (mid * mid > 2) { high = mid; } else { low = mid; } mid = (high + low) / 2; } return mid; } ``` #### 牛顿迭代法 ##### 1.牛顿迭代法的公式为: xn+1 = xn-f(xn)/f'(xn) 对于本题,需要求解的问题为:f(x)=x2-2 的零点 ``` EPSILON = 0.1 ** 10 def newton(x): if abs(x ** 2 - 2) > EPSILON: return newton(x - (x ** 2 - 2) / (2 * x)) else: return x ``` ================================================ FILE: 01.阿里篇/1.1.3 给定一个二叉搜索树(BST),找到树中第 K 小的节点.md ================================================ #### **题目**:给定一个二叉搜索树(BST),找到树中第 K 小的节点。 #### **出题人**:阿里巴巴出题专家:文景/阿里云 CDN 资深技术专家 #### **参考答案**: ##### * 考察点 1. 基础数据结构的理解和编码能力 2. 递归使用 ##### * 示例 ``` 5 / \ 3 6 / \ 2 4 / 1 ``` 说明:保证输入的 K 满足 1<=K<=(节点数目) 解法1:树相关的题目,第一眼就想到递归求解,左右子树分别遍历。联想到二叉搜索树的性质,root 大于左子树,小于右子树,如果左子树的节点数目等于 K-1,那么 root 就是结果,否则如果左子树节点数目小于 K-1,那么结果必然在右子树,否则就在左子树。因此在搜索的时候同时返回节点数目,跟 K 做对比,就能得出结果了。 ``` /** * Definition for a binary tree node. **/ public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } class Solution { private class ResultType { boolean found; // 是否找到 int val; // 节点数目 ResultType(boolean found, int val) { this.found = found; this.val = val; } } public int kthSmallest(TreeNode root, int k) { return kthSmallestHelper(root, k).val; } private ResultType kthSmallestHelper(TreeNode root, int k) { if (root == null) { return new ResultType(false, 0); } ResultType left = kthSmallestHelper(root.left, k); // 左子树找到,直接返回 if (left.found) { return new ResultType(true, left.val); } // 左子树的节点数目 = K-1,结果为 root 的值 if (k - left.val == 1) { return new ResultType(true, root.val); } // 右子树寻找 ResultType right = kthSmallestHelper(root.right, k - left.val - 1); if (right.found) { return new ResultType(true, right.val); } // 没找到,返回节点总数 return new ResultType(false, left.val + 1 + right.val); } } ``` 解法2:基于二叉搜索树的特性,在中序遍历的结果中,第k个元素就是本题的解。 最差的情况是k节点是bst的最右叶子节点,不过`每个节点的遍历次数最多是1次`。 遍历并不是需要全部做完,使用计数的方式,找到第k个元素就可以退出。 下面是go的一个简单实现。 ``` // BST is binary search tree type BST struct { key, value int left, right *BST } func (bst *BST) setLeft(b *BST) { bst.left = b } func (bst *BST) setRight(b *BST) { bst.right = b } // count 查找bst第k个节点的值,未找到就返回0 func count(bst *BST, k int) int { if k < 1 { return 0 } c := 0 ok, value := countRecursive(bst, &c, k) if ok { return value } return 0 } // countRecurisive 对bst使用中序遍历 // 用计数方式控制退出遍历,参数c就是已遍历节点数 func countRecursive(bst *BST, c *int, k int) (bool, int) { if bst.left != nil { ok, value := countRecursive(bst.left, c, k) if ok { return ok, value } } if *c == k-1 { return true, bst.value } *c++ if bst.right != nil { ok, value := countRecursive(bst.right, c, k) if ok { return ok, value } } return false, 0 } // 下面是测试代码,覆盖了退化的情况和普通bst func createBST1() *BST { b1 := &BST{key: 1, value: 10} b2 := &BST{key: 2, value: 20} b3 := &BST{key: 3, value: 30} b4 := &BST{key: 4, value: 40} b5 := &BST{key: 5, value: 50} b6 := &BST{key: 6, value: 60} b7 := &BST{key: 7, value: 70} b8 := &BST{key: 8, value: 80} b9 := &BST{key: 9, value: 90} b9.setLeft(b8) b8.setLeft(b7) b7.setLeft(b6) b6.setLeft(b5) b5.setLeft(b4) b4.setLeft(b3) b3.setLeft(b2) b2.setLeft(b1) return b9 } func createBST2() *BST { b1 := &BST{key: 1, value: 10} b2 := &BST{key: 2, value: 20} b3 := &BST{key: 3, value: 30} b4 := &BST{key: 4, value: 40} b5 := &BST{key: 5, value: 50} b6 := &BST{key: 6, value: 60} b7 := &BST{key: 7, value: 70} b8 := &BST{key: 8, value: 80} b9 := &BST{key: 9, value: 90} b1.setRight(b2) b2.setRight(b3) b3.setRight(b4) b4.setRight(b5) b5.setRight(b6) b6.setRight(b7) b7.setRight(b8) b8.setRight(b9) return b1 } func createBST3() *BST { b1 := &BST{key: 1, value: 10} b2 := &BST{key: 2, value: 20} b3 := &BST{key: 3, value: 30} b4 := &BST{key: 4, value: 40} b5 := &BST{key: 5, value: 50} b6 := &BST{key: 6, value: 60} b7 := &BST{key: 7, value: 70} b8 := &BST{key: 8, value: 80} b9 := &BST{key: 9, value: 90} b5.setLeft(b3) b5.setRight(b7) b3.setLeft(b2) b3.setRight(b4) b2.setLeft(b1) b7.setLeft(b6) b7.setRight(b8) b8.setRight(b9) return b5 } func createBST4() *BST { b := &BST{key: 1, value: 10} last := b for i := 2; i < 100000; i++ { n := &BST{key: i, value: i * 10} last.setRight(n) last = n } return b } func createBST5() *BST { b := &BST{key: 99999, value: 999990} last := b for i := 99998; i > 0; i-- { n := &BST{key: i, value: i * 10} last.setLeft(n) last = n } return b } func createBST6() *BST { b := &BST{key: 50000, value: 500000} last := b for i := 49999; i > 0; i-- { n := &BST{key: i, value: i * 10} last.setLeft(n) last = n } last = b for i := 50001; i < 100000; i++ { n := &BST{key: i, value: i * 10} last.setRight(n) last = n } return b } func TestK(t *testing.T) { bst1 := createBST1() bst2 := createBST2() bst3 := createBST3() bst4 := createBST4() check(t, bst1, 1, 10) check(t, bst1, 2, 20) check(t, bst1, 3, 30) check(t, bst1, 4, 40) check(t, bst1, 5, 50) check(t, bst1, 6, 60) check(t, bst1, 7, 70) check(t, bst1, 8, 80) check(t, bst1, 9, 90) check(t, bst2, 1, 10) check(t, bst2, 2, 20) check(t, bst2, 3, 30) check(t, bst2, 4, 40) check(t, bst2, 5, 50) check(t, bst2, 6, 60) check(t, bst2, 7, 70) check(t, bst2, 8, 80) check(t, bst2, 9, 90) check(t, bst3, 1, 10) check(t, bst3, 2, 20) check(t, bst3, 3, 30) check(t, bst3, 4, 40) check(t, bst3, 5, 50) check(t, bst3, 6, 60) check(t, bst3, 7, 70) check(t, bst3, 8, 80) check(t, bst3, 9, 90) check(t, bst4, 1, 10) check(t, bst4, 2, 20) check(t, bst4, 3, 30) check(t, bst4, 4, 40) check(t, bst4, 5, 50) check(t, bst4, 6, 60) check(t, bst4, 7, 70) check(t, bst4, 8, 80) check(t, bst4, 9, 90) check(t, bst4, 99991, 999910) check(t, bst4, 99992, 999920) check(t, bst4, 99993, 999930) check(t, bst4, 99994, 999940) check(t, bst4, 99995, 999950) check(t, bst4, 99996, 999960) check(t, bst4, 99997, 999970) check(t, bst4, 99998, 999980) check(t, bst4, 99999, 999990) } func check(t *testing.T, b *BST, k, value int) { t.Helper() checkCall(t, b, k, value, count) // 此处可添加其他解法的实现 } func checkCall(t *testing.T, b *BST, k, value int, find func(bst *BST, kth int) int) { t.Helper() got := find(b, k) if got != value { t.Fatalf("want:%d, got:%d", value, got) } } ``` ================================================ FILE: 01.阿里篇/1.1.4 LRU缓存机制.md ================================================ **题目**:LRU 缓存机制 设计和实现一个 LRU(最近最少使用)缓存数据结构,使它应该支持一下操作:get 和 put。 get(key) - 如果 key 存在于缓存中,则获取 key 的 value(总是正数),否则返回 -1。 put(key,value) - 如果 key 不存在,请设置或插入 value。当缓存达到其容量时,它应该在插入新项目之前使最近最少使用的项目作废。 **出题人**:文景/阿里云 CDN 资深技术专家 **参考答案**: python版本的: ``` class LRUCache(object): def __init__(self, capacity): """ :type capacity: int """ self.cache = {} self.keys = [] self.capacity = capacity def visit_key(self, key): if key in self.keys: self.keys.remove(key) self.keys.append(key) def elim_key(self): key = self.keys[0] self.keys = self.keys[1:] del self.cache[key] def get(self, key): """ :type key: int :rtype: int """ if not key in self.cache: return -1 self.visit_key(key) return self.cache[key] def put(self, key, value): """ :type key: int :type value: int :rtype: void """ if not key in self.cache: if len(self.keys) == self.capacity: self.elim_key() self.cache[key] = value self.visit_key(key) def main(): s = [["put","put","get","put","get","put","get","get","get"],[[1,1],[2,2],[1],[3,3],[2],[ 4,4],[1],[3],[4]]] obj = LRUCache(2) l=[] for i,c in enumerate(s[0]): if(c == "get"): l.append(obj.get(s[1][i][0])) else: obj.put(s[1][i][0], s[1][i][1]) print(l) if __name__ == "__main__": main() ``` c++版本的: ``` class LRUCache{ public: LRUCache(int capacity) { cap = capacity; } int get(int key) { auto it = m.find(key); if (it == m.end()) return -1; l.splice(l.begin(), l, it->second); return it->second->second; } void set(int key, int value) { auto it = m.find(key); if (it != m.end()) l.erase(it->second); l.push_front(make_pair(key, value)); m[key] = l.begin(); if (m.size() > cap) { int k = l.rbegin()->first; l.pop_back(); m.erase(k); } } } ``` ================================================ FILE: 01.阿里篇/1.1.5 关于epoll和select的区别,以下哪些说法是正确的.md ================================================ ##### **问题**:关于 epoll 和 select 的区别,哪些说法是正确的?(多选) A. epoll 和 select 都是 I/O 多路复用的技术,都可以实现同时监听多个 I/O 事件的状态。 B. epoll 相比 select 效率更高,主要是基于其操作系统支持的I/O事件通知机制,而 select 是基于轮询机制。 C. epoll 支持水平触发和边沿触发两种模式。 D. select 能并行支持 I/O 比较小,且无法修改。 ##### **出题人**:阿里巴巴出题专家:寈峰/阿里技术专家 ##### **参考答案**:A,B,C **【延伸】那在高并发的访问下,epoll使用那一种触发方式要高效些?当使用边缘触发的时候要注意些什么东西?** ================================================ FILE: 01.阿里篇/1.1.6 从innodb的索引结构分析,为什么索引的 key 长度不能太长.md ================================================ #### **题目**:从 innodb 的索引结构分析,为什么索引的 key 长度不能太长? #### **出题人**:阿里巴巴出题专家:近秋/阿里云数据库产品技术部技术专家 #### **参考答案**:key 太长会导致一个页当中能够存放的 key 的数目变少,间接导致索引树的页数目变多,索引层次增加,从而影响整体查询变更的效率。 ================================================ FILE: 01.阿里篇/1.1.7 MySQL的数据如何恢复到任意时间点?.md ================================================ #### **题目**:MySQL 的数据如何恢复到任意时间点? #### **出题人**:阿里巴巴出题专家:近秋/阿里云数据库产品技术部技术专家参考答案 #### **参考答案**:恢复到任意时间点以定时的做全量备份,以及备份增量的 binlog 日志为前提。恢复到任意时间点首先将全量备份恢复之后,再此基础上回放增加的 binlog 直至指定的时间点。 ================================================ FILE: 01.阿里篇/1.1.8 NFS与SMB的区别?.md ================================================ #### **题目**:NFS 和 SMB 是最常见的两种 NAS(Network Attached Storage)协议,当把一个文件系统同时通过 NFS 和 SMB 协议共享给多个主机访问时,以下哪些说法是错误的:(多选) A. 不可能有这样的操作,即把一个文件系统同时通过 NFS 和 SMB协议共享给多个主机访问。 B. 主机 a 的用户通过NFS 协议创建的文件或者目录,另一个主机 b的用户不能通过 SMB 协议将其删除。 C. 在同一个目录下,主机 a 通过 NFS 协议看到文件 file.txt,主机b 通过 SMB 协议也看到文件 file.txt,那么它们是同一个文件。 D. 主机 a 通过 NFS 协议,以及主机 b 通过 SMB 协议,都可以通过主机端的数据缓存,提升文件访问性能。 #### **出题人**:阿里巴巴出题专家:起影/阿里云文件存储高级技术专家 #### **参考答案**:A,B,C ================================================ FILE: 01.阿里篇/1.1.9 输入 ping IP 后敲回车,发包前会发生什么?.md ================================================ #### **题目**:输入 ping IP 后敲回车,发包前会发生什么? #### **出题人**:阿里巴巴出题专家:怀虎/阿里云云效平台负责人 #### **参考答案**: ping目标ip时,先查路由表,确定出接口 - 如果落在直连接口子网内,此时若为以太网等 _多路访问网络_ 则先查询arp缓存,命中则直接发出,否则在该接口上发arp询问目标ip的mac地址,取得后发出,若为ppp等 _点对点网络_ ,则直接可以发出; - 如果查表落在缺省路由上,此时若为以太网等 _多路访问网络_ 则先查询网关arp缓存,命中则直接发出,否则在该接口上发arp询问网关的mac地址,取得后发出,若为ppp等 _点对点网络_ ,则直接可以发出; - 若查表未命中,则返回不可达。 ================================================ FILE: 01.阿里篇/1.2.0 请解释下为什么鹿晗发布恋情的时候,微博系统会崩溃,如何解决?.md ================================================ #### **题目**:请解释下为什么鹿晗发布恋情的时候,微博系统会崩溃,如何解决? #### **出题人**:阿里巴巴出题专家:江岚/阿里巴巴数据技术高级技术专家 #### **参考答案**: A. 获取微博通过 pull 方式还是 push 方式 B. 发布微博的频率要远小于阅读微博 C. 流量明星的发微博,和普通博主要区分对待,比如在 sharding的时候,也要考虑这个因素 ================================================ FILE: 01.阿里篇/1.2.1 现有一批邮件需要发送给订阅顾客,且有一个集群(集群的节点数不定,会动态扩容缩容)来负责具体的邮件发送任务,如何让系统尽快地完成发送?.md ================================================ #### **题目**:现有一批邮件需要发送给订阅顾客,且有一个集群(集群的节点数不定,会动态扩容缩容)来负责具体的邮件发送任务,如何让系统尽快地完成发送?请详述技术方案! #### **出题人**:阿里巴巴出题专家:江岚/阿里巴巴数据技术高级技术专家 ### **参考答案**: A. 借助消息中间件,通过发布者订阅者模式来进行任务分配 B. master-slave 部署,由 master 来分配任务 C. 不借助任何中间件,且所有节点均等。通过数据库的 update-returning,从而实现节点之间任务的互斥 ================================================ FILE: 01.阿里篇/1.2.2 有一批气象观测站,现需要获取这些站点的观测数据,并存储到 Hive 中。但是气象局只提供了 api 查询,每次只能查询单个观测点。那么如果能够方便快速地获取到所有的观测点的数据?.md ================================================ #### **题目**:有一批气象观测站,现需要获取这些站点的观测数据,并存储到 Hive 中。但是气象局只提供了 api 查询,每次只能查询单个观测点。那么如果能够方便快速地获取到所有的观测点的数据? #### **出题人**:阿里巴巴出题专家:江岚/阿里巴巴数据技术高级技术专家 #### **参考答案**: A. 通过 shell 或 python 等调用 api,结果先暂存本地,最后将本地文件上传到 Hive 中。 B. 通过 datax 的 httpReader 和 hdfsWriter 插件,从而获取所需的数据。 C. 比较理想的回答,是在计算引擎的 UDF 中调用查询 api,执行UDF 的查询结果存储到对应的表中。一方面,不需要同步任务的导出导入;另一方面,计算引擎的分布式框架天生提供了分布式、容错、并发等特性。 ================================================ FILE: 01.阿里篇/1.2.3 如何实现两金额数据相加(最多小数点两位).md ================================================ #### **题目**:如何实现两金额数据相加(最多小数点两位)? #### **出题人**:阿里巴巴出题专家:御术/蚂蚁金服数据可视化高级技术专家 #### **参考答案**: 其实问题并不难,就是考察候选人对 JavaScript 数据运算上的认知以及考虑问题的缜密程度,有很多坑,可以用在笔试题,如果用在面试,回答过程中还可以随机加入有很多计算机基础的延伸。 回到这个问题,由于直接浮点相与加会失精,所以要转整数;(可以插入问遇到过吗?是否可以举个例子?)。 转整数是第一个坑,虽然只有两位可以通过乘以100转整数,但由于乘以一百和除以一百都会出现浮点数的运算,所以也会失精,还是要通过字符串来转;(可以插入问字符串转整数有几种方式?)字符串转整是第二个坑,因为最后要对齐计算,如果没考虑周全先toFixed(2),对于只有一位小数点数据进入计算就会错误;转整数后的计算是个加分点,很多同学往往就是直接算了,如果可以考虑大数计算的场景,恭喜同学进入隐藏关卡,这就会涉及如何有效循环、遍历、算法复杂度的问题。 ================================================ FILE: 01.阿里篇/1.2.4 关于并行计算的一些基础开放问题.md ================================================ #### **题目**: 关于并行计算的一些基础开放问题。 ◼ 如何定义并计算,请分别阐述分布式内存到共享内存模式行编程的区别和实现(例子代码)? ◼ 请使用 MPI 和 OpenMP 分别实现 N 个处理器对 M 个变量的求和? ◼ 请说明 SIMD 指令在循环中使用的权限?向量化优化有哪些手段? ◼ 请用 Amdahl 定律说明什么是并行效率以及并行算法的扩展性?并说明扩展性的性能指标和限制因素,最后请说明在共享内存计算机中,共享内存的限制?OpenMP 是怎样实现共享内存编程环境的?MPI 阻塞和非阻塞读写的区别? #### **出题人**:阿里巴巴出题专家:何万青/阿里云高性能计算资深技术专家 #### **参考答案**: (简要答案,但必须触及,可以展开) ◼ 同时执行多个/算法/逻辑操作/内存访问/IO,相互独立同时运行,分三个层次:进程级,多个节点分布式内存通过MPI通信并行;线程级,共享内存的多路机器,通过OpenMP实现多线程并行;指令集:通过SIM指令实现单指令多数据。。。。举例吧啦吧啦。 ◼ MPI代码,,,OpenMP代码,分别写出来 M个元素,N个处理器的累加,后者注意private 参数。 ◼ SIMD在循环中的应用,限制在于 SIMD指令处理的每一个数组的长度,cache line利用,内部循环间的依赖和条件调用等。 ◼ 向量化,主要看SSE和AVX指令占比率,通过编译器优化...... 在loop代码中使用。 ◼ 性能和计算规模随处理器增加的变化曲线,实测HPL和峰值HPL比率,能用用Amdahl定律表达Tpar(N) = (an + (1-a)n/N )t + C (n,N), 能够讲明白串行部分对整个并行的天花板效应,扩展性能够解释清楚算法的扩展性=并行效率随处理器数目的变化关系,画出来。 ◼ 共享内存计算机OpenMP对变量的限制描述,EREW,CREW,ERCW,CRCW等区别,NUMA概念,如何保持coherent等。 ◼ 写出OpenMP和MPI的核心函数,回答问题即可。 ================================================ FILE: 01.阿里篇/1.2.5 请计算XILINX公司VU9P芯片的算力相当于多少TOPS,给出计算过程与公式.md ================================================ #### **题目**:请计算XILINX公司VU9P芯片的算力相当于多少TOPS,给出计算过程与公式。 #### **出题人**: 阿里巴巴出题专家:隐达/阿里云异构计算资深专家 #### **参考答案**:基于不同的算法,这个值在十几到几百之间。但是,如果只是单纯比算力,FPGA和ASIC、GPU相比并无太大优势,甚至大多时候有较大劣势。FPGA的优势在于高度的灵活性和算法的针对性。 ================================================ FILE: 01.阿里篇/1.2.6 一颗现代处理器,每秒大概可以执行多少条简单的MOV指令,有哪些主要的影响因素.md ================================================ #### **题目**:一颗现代处理器,每秒大概可以执行多少条简单的MOV指令,有哪些主要的影响因素? #### **出题人**:阿里巴巴出题专家:子团/创新产品虚拟化&稳定性资深技术专家 #### **参考答案**: **及格:** 每执行一条mov指令需要消耗1个时钟周期,所以每秒执行的mov指令和CPU主频相关。 **加分:** 在CPU微架构上,要考虑数据预取,乱序执行,多发射,内存stall(前端stall和后端stall)等诸多因素,因此除了cpu主频外,还和流水线上的效率(IPC)强相关,比较复杂的一个问题。 ================================================ FILE: 01.阿里篇/1.2.7 请分析 MaxCompute 产品与分布式技术的关系、当前大数据计算平台类产品的市场现状和发展趋势.md ================================================ #### **题目**:请分析 MaxCompute 产品与分布式技术的关系、当前大数据计算平台类产品的市场现状和发展趋势。 #### **出题人**:阿里巴巴出题专家:云郎/阿里 MaxCompute 高级产品专家 #### **参考答案**: 开放性问题,无标准答案。 ================================================ FILE: 01.阿里篇/1.2.8 对大数据平台中的元数据管理是怎么理解的,元数据收集管理体系是怎么样的,会对大数据应用有什么样的影响.md ================================================ #### **题目**: 对大数据平台中的元数据管理是怎么理解的,元数据收集管理体系是怎么样的,会对大数据应用有什么样的影响。 #### **出题人**: 阿里巴巴出题专家:映泉/阿里巴巴高级技术专家 #### **参考答案**:开放性问题,无标准答案。 ================================================ FILE: 01.阿里篇/1.2.9 你理解常见如阿里,和友商大数据平台的技术体系差异以及发展趋势和技术瓶颈,在存储和计算两个方面进行概述.md ================================================ #### **题目**: 你理解常见如阿里,和友商大数据平台的技术体系差异以及发展趋势和技术瓶颈,在存储和计算两个方面进行概述。 #### **出题人**: 阿里巴巴出题专家:映泉/阿里巴巴高级技术专家 #### **参考答案**:开放性问题,无标准答案。 ================================================ FILE: 01.阿里篇/1.3.0 在云计算大数据处理场景中,每天运行着成千上万的任务,每个任务都要进行 IO 读写.md ================================================ #### **题目**:在云计算大数据处理场景中,每天运行着成千上万的任务,每个任务都要进行 IO 读写。存储系统为了更好的服务,经常会保证高优先级的任务优先执行。当多个作业或用户访问存储系统时,如何保证优先级和公平性。 #### **出题人**:阿里巴巴出题专家:田磊磊/阿里云文件存储高级技术专家 #### **参考答案**:开放性问题,无标准答案。 ================================================ FILE: 01.阿里篇/1.3.1 最大频率栈.md ================================================ #### **题目**:最大频率栈。 实现 FreqStack,模拟类似栈的数据结构的操作的一个类。FreqStack 有两个函数:
push(int x),将整数 x 推入栈中。pop(),它移除并返回栈中出现最频繁的元素。如果最频繁的元素不只一个,则移除并返回最接近栈顶的元素。 ◼ 示例: push [5,7,5,7,4,5] pop() -> 返回 5,因为 5 是出现频率最高的。
栈变成 [5,7,5,7,4]。 pop() -> 返回 7,因为 5 和 7 都是频率最高的,但 7 最接近栈 顶。
栈变成 [5,7,5,4]。 pop() -> 返回 5 。
栈变成 [5,7,4]。 pop() -> 返回 4 。
栈变成 [5,7]。 #### **出题人**:阿里巴巴出题专家:屹平/阿里云视频云边缘计算高级技术专家 #### **参考答案**: 令 freq 作为 x 的出现次数的映射 Map。 此外 maxfreq,即栈中任意元素的当前最大频率,因为我们必须弹出频率最高的元素。 当前主要的问题就变成了:在具有相同的(最大)频率的元素中,怎么判断那个元素是最新的?我们可以使用栈来查询这一信息:靠近栈顶的元素总是相对更新一些。 为此,我们令 group 作为从频率到具有该频率的元素的映射。到目前,我们已经实现了 FreqStack 的所有必要的组件。 算法: 实际上,作为实现层面上的一点细节,如果 x 的频率为 f,那么我们将获取在所有 group[i] (i <= f) 中的 x,而不仅仅是栈顶的那个。这是因为每个 group[i] 都会存储与第 i 个 x 副本相关的信息。 最后,我们仅仅需要如上所述维持 freq,group,以及 maxfreq。 **参考代码***: ``` class FreqStack { Map freq; Map> group; int maxfreq; public FreqStack() { freq = new HashMap(); group = new HashMap(); maxfreq = 0; } public void push(int x) { int f = freq.getOrDefault(x, 0) + 1; freq.put(x, f); if (f > maxfreq) maxfreq = f; group.computeIfAbsent(f, z-> new Stack()).push(x); } public int pop() { int x = group.get(maxfreq).pop(); freq.put(x, freq.get(x) - 1); if (group.get(maxfreq).size() == 0) maxfreq--; return x; } } ``` ================================================ FILE: 01.阿里篇/1.3.2 给定一个链表,删除链表的倒数第N个节点,并且返回链表的头结点.md ================================================ #### **题目**:给定一个链表,删除链表的倒数第 N 个节点,并且返回链表的头结点。 ◼ 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5. 说明: 给定的 n 保证是有效的。 要求: 只允许对链表进行一次遍历。 #### **出题人**:阿里巴巴出题专家:屹平/阿里云视频云边缘计算高级技术专家 #### **参考答案**: 我们可以使用两个指针而不是一个指针。第一个指针从列表的开头向前移动 n+1 步,而第二个指针将从列表的开头出发。现在,这两个指针被 n 个结点分开。我们通过同时移动两个指针向前来保持这个恒定的间隔,直到第一个指针到达最后一个结点。此时第二个指针将指向从最后一个结点数起的第 n 个结点。我们重新链接第二个指针所引用的结点的 next 指针指向该结点的下下个结点。 **参考代码**: ``` public ListNode removeNthFromEnd(ListNode head, int n) { ListNode dummy = new ListNode(0); dummy.next = head; ListNode first = dummy; ListNode second = dummy; // Advances first pointer so that the gap between first and second is n nodes apart for (int i = 1; i <= n + 1; i++) { first = first.next; } // Move first to the end, maintaining the gap while (first != null) { first = first.next; second = second.next; } second.next = second.next.next; return dummy.next; } ``` **复杂度分析:** * 时间复杂度:O(L),该算法对含有 L 个结点的列表进行了一次遍历。因此时间复杂度为 O(L)。 * 空间复杂度:O(1),我们只用了常量级的额外空间。 ================================================ FILE: 01.阿里篇/1.3.3 如果让你设计一个通用的、支持各种数据库秒级备份和恢复的系统,你会如何设计.md ================================================ #### **题目**:如果让你设计一个通用的、支持各种数据库秒级备份和恢复的系统,你会如何设计? #### **出题人**:阿里巴巴出题专家:千震/阿里云数据库高级技术专家 #### **参考答案**:开放性问题,无标准答案。 ================================================ FILE: 01.阿里篇/1.3.4 如果让你来设计一个支持数据库、NOSQL 和大数据之间数据实时流动的数据流及处理的系统,你会考虑哪些问题?如何设计?.md ================================================ #### **题目**:如果让你来设计一个支持数据库、NOSQL 和大数据之间数据实时流动的数据流及处理的系统,你会考虑哪些问题?如何设计? #### **出题人**:阿里巴巴出题专家:千震/阿里云数据库高级技术专家 #### **参考答案**:开放性问题,无标准答案。 ================================================ FILE: 01.阿里篇/1.3.5 给定一个整数数组和一个整数,返回两个数组的索引,这两个索引指向的数字的加和等于指定的整数。需要最优的算法,分析算法的空间和时间复杂度.md ================================================ 题目:给定一个整数数组和一个整数,返回两个数组的索引,这两个索引指向的数字的加和等于指定的整数。需要最优的算法,分析算法的空间和时间复杂度 参考答案: ```Java public int[] twoSum(int[] nums, int target) { if(nums==null || nums.length<2) return new int[]{0,0}; HashMap map = new HashMap(); for(int i=0; i queue = new SynchronousQueue<>(); System. out .print(queue.offer(1) + " "); System. out .print(queue.offer(2) + " "); System. out .print(queue.offer(3) + " "); System. out .print(queue.take() + " "); System. out .println(queue.size()); } } ``` A. true true true 1 3 B. true true true (阻塞) C. false false false null 0 D. false false false (阻塞) #### **出题人**:阿里巴巴出题专家:桃谷/阿里云中间件技术专家 #### **参考答案**:D ================================================ FILE: 01.阿里篇/1.3.8 如何测试一辆自行车.md ================================================ #### **题目**:如何测试一辆自行车 #### **出题人**:阿里巴巴新零售技术质量部 #### **参考答案**: 开放性问题,如果联系到测试角度上看的话,可以这么作答: 1. 骑车试一试,看有没有问题,对应测试能不能跑通 2. 看看车的核心部件,例如车闸,车把等,对应软件的核心功能 3. 看看车是否安全,配锁质量如何,对应软件是否有安全问题 ================================================ FILE: 01.阿里篇/1.3.9 如何判断两个链表是否相交.md ================================================ #### **题目**:如何判断两个链表是否相交 #### **出题人**:阿里巴巴新零售技术质量部 #### **参考答案**: $O(n^2)$: 两层遍历,总能发现是否相交 $O(n)$: 一层遍历,遍历完两个链表,如果两个链表的最后一个结点指针相同,则相交,否则不相交 ================================================ FILE: 02.华为篇/2.1.1 static有什么用途?(请至少说明两种).md ================================================ #### **题目**: static有什么用途?(请至少说明两种) #### **参考答案**: 1) 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。 2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。 3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用 ================================================ FILE: 02.华为篇/2.1.2 引用与指针有什么区别?.md ================================================ #### **题目**:引用与指针有什么区别? #### **参考答案**: 1) 引用必须被初始化,指针不必。 2) 引用初始化以后不能被改变,指针可以改变所指的对象。 3) 不存在指向空值的引用,但是存在指向空值的指针。 ================================================ FILE: 02.华为篇/2.1.3 描述实时系统的基本特性.md ================================================ #### **题目**:描述实时系统的基本特性 #### **参考答案**: 在特定时间内完成特定的任务,实时性与可靠性。 ================================================ FILE: 02.华为篇/2.1.4 全局变量和局部变量在内存中是否有区别?如果有,是什么区别?.md ================================================ #### **题目**:全局变量和局部变量在内存中是否有区别?如果有,是什么区别? #### **参考答案**: 全局变量储存在静态数据库,局部变量在堆栈。 ================================================ FILE: 02.华为篇/2.1.5 什么是平衡二叉树?.md ================================================ #### **题目**:什么是平衡二叉树? #### **参考答案**: 左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1。 ================================================ FILE: 02.华为篇/2.1.6 堆栈溢出一般是由什么原因导致的?.md ================================================ #### **题目**:堆栈溢出一般是由什么原因导致的? #### **参考答案**: 没有回收垃圾资源。 ================================================ FILE: 02.华为篇/2.1.7 什么函数不能声明为虚函数?.md ================================================ #### **题目**:什么函数不能声明为虚函数? #### **参考答案**: constructor函数不能声明为虚函数。 ================================================ FILE: 02.华为篇/2.1.8 冒泡排序算法的时间复杂度是什么?.md ================================================ #### **题目**: 冒泡排序算法的时间复杂度是什么? #### **参考答案**: 时间复杂度是O(n^2)。 ================================================ FILE: 02.华为篇/2.1.9. Internet采用哪种网络协议?该协议的主要层次结构?.md ================================================ #### **题目**:Internet采用哪种网络协议?该协议的主要层次结构? #### **参考答案**: Tcp/Ip协议 主要层次结构为: 应用层/传输层/网络层/数据链路层/物理层。 ================================================ FILE: 02.华为篇/2.2.0 IP地址的编码分为哪俩部分?.md ================================================ #### **题目**:IP地址的编码分为哪俩部分? #### **参考答案**: IP地址由两部分组成,网络号和主机号。不过是要和“子网掩码”按位与上之后才能区分哪些是网络位哪些是主机位。 ================================================ FILE: 02.华为篇/2.2.1 用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序.md ================================================ #### **题目**:用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。 #### **参考答案**: 循环链表,用取余操作做 ================================================ FILE: 02.华为篇/2.2.2 某32位系统下, C++程序,请计算sizeof 的值.md ================================================ #### **题目**:某32位系统下, C++程序,请计算sizeof 的值. #### **参考答案**: ``` char str[] = “http://www.ibegroup.com/” char *p = str ; int n = 10; 请计算 sizeof (str ) = ?(1) sizeof ( p ) = ?(2) sizeof ( n ) = ?(3) void Foo ( char str[100]){ 请计算 sizeof( str ) = ?(4) } void *p = malloc( 100 ); 请计算 sizeof ( p ) = ?(5) (1)17 (2)4 (3) 4 (4)4 (5)4 ``` ================================================ FILE: 03.百度篇/3.4.8 找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数。.md ================================================ #### **题目**:找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数。 #### **出题人**:阿里巴巴新零售技术质量部 #### **参考答案**: 遍历数组的同时用Object来储存每个元素出现的个数,每次遍历都跟max比较 #### **参考代码**: ``` const arr =[1,2,3,4,5,6,7,8,89,9,9,9,9,99]; const maxNumObj =(arr)=>{ return arr.reduce((obj,cur)=>{ if(!obj['max']){ obj['max']=arr[0]; } obj[cur] = ++obj[cur]||1; if(obj[cur]>obj['max']){ obj['max'] = obj[cur] } return obj; },{})['max']; } ``` ================================================ FILE: 03.百度篇/3.4.9 找出被修改过的数字.md ================================================ #### **题目**: 找出被修改过的数字 #### **出题人**:阿里巴巴新零售技术质量部 #### **参考答案**: emmm假设背景是寻找数组中被修改的数字或者元素,我使用代理的方式来监听数组中元素的变化,并将变化的最后数值和次数储存在额外空间中 #### **参考代码**: ``` const arr =[1,2,3,4,5,6,7,8,89,9,9,9,9,99]; const saveModifyNum={ } const watchNumChangeProxy=new Proxy(arr,{ set:function(target,key,value){ let {count} = Reflect.get(saveModifyNum,target[key])||{count:0,value}; ++count; return Reflect.set(saveModifyNum,target[key],{ count, value }); } }) watchNumChangeProxy[0]=2; watchNumChangeProxy[0]=3; watchNumChangeProxy[0]=4; //{ '1': { count: 3, value: 4 } } ``` ================================================ FILE: 04.腾讯篇/4.1.0 JAVA中的几种基本数据类型是什么,各自占用多少字节.md ================================================ #### 题目: JAVA中的几种基本数据类型是什么,各自占用多少字节。 #### 参考答案: Java中一共有八种基本数据类型: 1. byte 1字节 2. char 2字节 3. short 2字节 4. int 4字节 5. float 4字节 6. long 8字节 7. double 8字节 8. boolean 只有两个值:true、false,可以使用 1 bit 来存储,但是具体大小没有明确规定。JVM 会在编译时期将boolean 类型的数据转换为 int,使用 1 来表示 true,0 表示 false。 ================================================ FILE: 04.腾讯篇/4.1.1 String类能被继承吗,为什么.md ================================================ #### 题目:String类能被继承吗,为什么 #### 参考答案: ``` // Java8 string 类 public final class String implements java.io.Serializable, Comparable, CharSequence { private final char value[]; } ``` ``` // Java 9 变为字节数组,同时提供了编码类型属性 public final class String implements java.io.Serializable, Comparable, CharSequence { private final byte[] value; private final byte coder; } ``` 由string类的源码可知,string类被设计为final类型,因此它不可被继承。 此外我们发现它内部维护的字符数组也被修饰为 final 类型,这使得 value 数组初始化之后就不能再改变其值。并且 String 内部没有改变 value 数组引用的方法,因此String具有不可变的特性。 ================================================ FILE: 04.腾讯篇/4.1.2 String,Stringbuffer,StringBuilder的区别.md ================================================ #### 问题:String,Stringbuffer,StringBuilder的区别 #### 参考答案: ##### 1 可变性 - String 不可变 - StringBuffer 和 StringBuilder可变 ##### 2 线程安全性 - String 不可变,意味着它是线程安全的,我们可以再多线程中放心使用String。 - StringBuffer ``` @Override public synchronized int length() { return count; } @Override public synchronized int capacity() { return value.length; } …… ``` 源码中的获取长度和扩容等方法均被 synchronized 关键字修饰进行同步操作,因此是线程安全的。 - StringBuilder ``` // StringBuilder 的父类 AbstractStringBuilder @Override public int length() { return count; } /** * Returns the current capacity. The capacity is the amount of storage * available for newly inserted characters, beyond which an allocation * will occur. * * @return the current capacity */ public int capacity() { return value.length; } …… ``` 因此,StringBuilder 是线程不安全的,由于没有锁的操作,StringBuilder执行更快。 ​ ================================================ FILE: 04.腾讯篇/4.1.3 ArrayList和LinkedList有什么区别.md ================================================ #### 问题描述:ArrayList和LinkedList有什么区别。 #### 参考答案: - 数据结构 ``` public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable { /** * Default initial capacity. */ private static final int DEFAULT_CAPACITY = 10; transient Object[] elementData; // non-private to simplify nested class access …… } ``` ArrayList 基于Object数组实现,可以利用 index 的特性进行快速查找,RandomAccess 接口表明它支持快速随机访问。 ------ ``` public class LinkedList extends AbstractSequentialList implements List, Deque, Cloneable, java.io.Serializable { transient int size = 0; /** * Pointer to first node. * Invariant: (first == null && last == null) || (first.prev == null && first.item != null) */ transient Node first; /** * Pointer to last node. * Invariant: (first == null && last == null) || (last.next == null && last.item != null) */ transient Node last; …… } ``` LinkedList使用了双向链表实现,使用静态内部类 Node 来存储元素(原理如图示)。 - 查询 ``` // ArrayList public E get(int index) { rangeCheck(index); return elementData(index); } E elementData(int index) { return (E) elementData[index]; } ``` ArrayList 数组的数据结构使得它可以使用索引下标进行随机快速访问元素数据。 ------ ``` // LinkedList public E get(int index) { checkElementIndex(index); return node(index).item; } Node node(int index) { // assert isElementIndex(index); if (index < (size >> 1)) { Node x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { Node x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } } ``` LinkedList 双向链表的数据结构使得它只能进行顺序查找访问,因此就查询来说ArrayList 的效率要高于LinkedList(源码可知,它提供的 get(int index)方法实际上也是走的链表顺序查询,而不是真正的索引快速查找)。 - 删除 ``` // ArrayList public E remove(int index) { rangeCheck(index); modCount++; E oldValue = elementData(index); int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue; } /** System.arraycopy(Object src,int srcPos,Object dest, int destPos,int length); */ ``` image-20210221101023286 ArrayList 在删除元素的时候,要将去除删除元素的剩余元素重新拷贝到一个新的数组,并重新索引删除元素后的元素,可见 ArrayList 在删除元素时的效率比较低。 ------ ``` // LinkedList public E remove(int index) { checkElementIndex(index); return unlink(node(index)); } E unlink(Node x) { // assert x != null; final E element = x.item; final Node next = x.next; final Node prev = x.prev; if (prev == null) { first = next; } else { prev.next = next; x.prev = null; } if (next == null) { last = prev; } else { next.prev = prev; x.next = null; } x.item = null; size--; modCount++; return element; } ``` LinkedList 的删除操作就相对高效,直接改变删除元素首位的node 引用,然后将当前要删除的元素的引用置位null即可,没有额外的复制操作。 ================================================ FILE: 04.腾讯篇/4.1.4 讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,当new的时候,他们的执行顺序.md ================================================ #### 题目:讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,当new的时候,他们的执行顺序。 #### 参考答案: 1. 父类静态成员和静态初始化块 ,按在代码中出现的顺序依次执行。 2. 子类静态成员和静态初始化块 ,按在代码中出现的顺序依次执行。 3. 父类实例成员和实例初始化块 ,按在代码中出现的顺序依次执行。 4. 父类构造方法。 5. 子类实例成员和实例初始化块 ,按在代码中出现的顺序依次执行。 6. 子类构造方法。 **当创建类对象时,先初始化静态变量和静态块,然后是非静态变量和非静态代码块,然后是构造器。由于静态成员只会被初始化一次,所以如果静态成员已经被初始化,将不会被再次初始化。** ================================================ FILE: 04.腾讯篇/4.1.5 用过哪些Map类,都有什么区别,HashMap是线程安全的吗,并发下使用的Map是什么,他们内部原理分别是什么,比如存储方式,hashcode,扩容,默认容量等.md ================================================ #### 题目:用过哪些Map类,都有什么区别,HashMap是线程安全的吗,并发下使用的Map是什么,他们内部原理分别是什么,比如存储方式,hashcode,扩容,默认容量等。 #### 参考答案: **map实现类**: - HashMap:基于哈希表实现(从 JDK 1.8 开始,一个桶存储的链表长度大于 8 时会将链表转换为红黑树。以便于查找,而不是链表的顺序查找)。 - HashTable:和 HashMap 类似,但它是线程安全的。 ``` // HashTable 的使用全部被设计为线程安全的方式,使用synchronized修饰 …… public synchronized V put(K key, V value) …… ``` - LinkedHashMap:使用双向链表来维护元素的顺序(顺序可以是 插入顺序或者最近最少使用(LRU))。 - TreeMap:基于红黑树实现。 ------ HashMap是线程不安全的,线程安全的map 有 HashTable 和 ConcurrentHashMap,但是如果要保证线程安全我们推荐使用 ConcurrentHashMap,尤其是在并发的情况下,因为 HashTable 由 synchronized 来确保线程安全,因此同一时刻只能有一个线程操作,会阻碍并发的效率。 **ConcurrentHashMap** : ConcurrentHashMap 和 HashMap 实现上非常类似,最主要的差别是 ConcurrentHashMap 采用了分段锁(Segment),每个分段锁维护着几个桶(HashEntry),多个线程可以同时访问不同分段锁上的桶,从而实现真正的并发,并保证线程安全(并发度就是 Segment 的个数)。 JDK1.8 使用了 CAS 操作来支持更高的并发度,在 CAS 操作失败时使用内置锁 synchronized。 ``` // put 操作 public V put(K key, V value) { return putVal(key, value, false); } /**#############################################*/ private static final int DEFAULT_CAPACITY = 16; static final boolean casTabAt(Node[] tab, int i, Node c, Node v) { return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v); } /**#############################################*/ /**onlyIfAbsent 只有不存在的时候再添加 put方法不设置默认为false(putVal(key, value, false)) */ final V putVal(K key, V value, boolean onlyIfAbsent) { if (key == null || value == null) throw new NullPointerException(); int hash = spread(key.hashCode()); int binCount = 0; for (Node[] tab = table;;) { Node f; int n, i, fh; if (tab == null || (n = tab.length) == 0) /** 当Node 数组容器为空是,初始化一个默认长度的Node 数组,长度为16 */ tab = initTable(); else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) { /** 使用cas操作,如果成功则结束循环,返回 */ if (casTabAt(tab, i, null, new Node(hash, key, value, null))) break; // no lock when adding to empty bin } else if ((fh = f.hash) == MOVED) tab = helpTransfer(tab, f); else { V oldVal = null; /** CAS 操作失败,进入 synchronized 操作。 */ synchronized (f) { ………… } ………… } } addCount(1L, binCount); return null; } ``` **HashMap :** - 数据结构 HashMap的主干是一个Entry数组。Entry是HashMap的基本组成单元,每一个Entry包含一个key-value键值对。(JDK1.8换为Node implements Map.Entry) ``` transient Entry[] table; /**实际存储的key-value键值对的个数*/ transient int size; /**阈值,当table == {}时,该值为初始容量(初始容量默认为16);当table被填充了,也就是为table分配内存空间后,threshold一般 capacity*loadFactory。HashMap在进行扩容时需要参考threshold,后面会详细谈到*/ int threshold; /**负载因子,代表了table的填充度有多少,默认是0.75加载因子存在的原因,还是因为减缓哈希冲突,如果初始桶为16,等到满16个元素才扩容, 某些桶里可能就有不止一个元素了。所以加载因子默认为0.75,也就是说大小为16的HashMap,到了第13个元素,就会扩容成32。*/ final float loadFactor; /**HashMap被改变的次数,由于HashMap非线程安全,在对HashMap进行迭代时,如果期间其他线程的参与导致HashMap的结构发生变化了 (比如put,remove等操作),需要抛出异常ConcurrentModificationException */ transient int modCount; static class Entry implements Map.Entry { final K key; V value; Entry next;//存储指向下一个Entry的引用,单链表结构 int hash;//对key的hashcode值进行hash运算后得到的值,存储在Entry,避免重复计算 Entry(int h, K k, V v, Entry n) { value = v; next = n; key = k; hash = h; } } ``` **HashMap由数组+链表组成的**,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,如果定位到的数组位置不含链表那么查找,添加等操作很快,仅需一次寻址即可;如果定位到的数组包含链表,对于添加操作,其时间复杂度为O(n),首先遍历链表,存在即覆盖,否则新增;对于查找操作来讲,仍需遍历链表,然后通过key对象的equals方法逐一比对查找。 - hash函数 ``` final int hash(Object k) { int h = hashSeed; if (0 != h && k instanceof String) { return sun.misc.Hashing.stringHash32((String) k); } h ^= k.hashCode(); h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); } ``` 以上hash函数计算出的值,通过indexFor进一步处理来获取实际的存储位置 ``` /** * 返回数组下标 */ static int indexFor(int h, int length) { return h & (length-1); } ``` ================================================ FILE: 04.腾讯篇/4.1.6 JAVA8的ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何设计.md ================================================ #### 题目: JAVA8的ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何设计。 #### 参考答案: 关于ConcurrentHashMap的实现参考前面介绍,不在详细赘述。 关于分段锁 Segment继承了重入锁ReentrantLock,有了锁的功能,每个锁控制的是一段,当每个Segment越来越大时,锁的粒度就变得有些大了。 - 分段锁的优势在于保证在操作不同段 map 的时候可以并发执行,操作同段 map 的时候,进行锁的竞争和等待。这相对于直接对整个map同步synchronized是有优势的。 - 缺点在于分成很多段时会比较浪费内存空间(不连续,碎片化); 操作map时竞争同一个分段锁的概率非常小时,分段锁反而会造成更新等操作的长时间等待; 当某个段很大时,分段锁的性能会下降。 再来回顾一下源码 ``` final V putVal(K key, V value, boolean onlyIfAbsent) { if (key == null || value == null) throw new NullPointerException(); int hash = spread(key.hashCode()); int binCount = 0; for (Node[] tab = table;;) { Node f; int n, i, fh; if (tab == null || (n = tab.length) == 0) // 如果没有设置初始化容量,则使用默认大小初始化桶 tab = initTable(); else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) { // 这里否则就可以初始化元素了,这里可以看到使用了cas的操作 if (casTabAt(tab, i, null, new Node(hash, key, value, null))) break; // no lock when adding to empty bin } else if ((fh = f.hash) == MOVED) // 桶正在进行迁移操作 MOVED = -1 tab = helpTransfer(tab, f); else { V oldVal = null; // synchronized锁 同步头操作 synchronized (f) { if (tabAt(tab, i) == f) { if (fh >= 0) { binCount = 1; for (Node e = f;; ++binCount) { K ek; if (e.hash == hash && ((ek = e.key) == key || (ek != null && key.equals(ek)))) { oldVal = e.val; if (!onlyIfAbsent) e.val = value; break; } Node pred = e; if ((e = e.next) == null) { pred.next = new Node(hash, key, value, null); break; } } } else if (f instanceof TreeBin) { Node p; binCount = 2; if ((p = ((TreeBin)f).putTreeVal(hash, key, value)) != null) { oldVal = p.val; if (!onlyIfAbsent) p.val = value; } } } } if (binCount != 0) { if (binCount >= TREEIFY_THRESHOLD) treeifyBin(tab, i); if (oldVal != null) return oldVal; break; } } } addCount(1L, binCount); return null; } ``` 把数组中的每个元素看成一个桶。可以看到大部分都是CAS操作,加锁的部分是对桶的头节点进行加锁,锁粒度很小。 #### ReentrantLock VS synchronized ? - 减少内存开销:如果使用ReentrantLock则需要节点继承AQS来获得同步支持,增加内存开销,而1.8中只有头节点需要进行同步。 - 内部优化:synchronized是JVM直接支持的,1.8之后进行了许多优化,能够在运行期间调整锁的粒度:锁粗化、锁消除、锁自旋等等,而不是再开始就使用重量级锁操作。 #### 总结: 通过源码可以看出 使用 CAS + synchronized 方式时加锁的对象是每个链条的头结点,也就是锁定的是冲突的链表,所以再次提高了并发度,并发度等于链表的条数或者说桶的数量。那为什么sement 不把段的大小设置为一个桶呢,因为在粒度比较小的情况下,如果使用ReentrantLock则需要节点继承AQS来获得同步支持,增加内存开销,而1.8中只有头节点需要进行同步,粒度表较小,相对来说内存开销就比较大。所以不把segment的大小设置为一个桶。 ================================================ FILE: 04.腾讯篇/4.1.7有没有有顺序的Map实现类,如果有,他们是怎么保证有序的.md ================================================ #### 问题描述:有没有有顺序的Map实现类,如果有,他们是怎么保证有序的。 #### 参考答案: map的实现类常见的有TreeMap,HashMap,LinkedHashMap。 其中HashMap 是没有顺序的,它也是我们最常用的Map,它根据key的HashCode 值来存储数据,根据key可以直接获取它的Value,同时它具有很快的访问速度。HashMap最多只允许一条记录的key值为Null(多条会覆盖);允许多条记录的Value为 Null,非同步的。 ``` public V put(K key, V value) { return putVal(hash(key), key, value, false, true); } ``` 有顺序的两个Map:TreeMap , LinkedHashMap ##### TreeMap: 它能够根据元素的key进行排序,默认升序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。 实现自定义的排序我们需要设置我们自定义的Comparator。 Comparator可以对集合对象或者数组进行排序的比较器接口,实现该接口的public compare`(T o1,To2)`方法即可实现排序。 > 该方法主要是根据第一个参数o1,小于、等于或者大于o2分别返回负整数、0或者正整数。这里的Comparator属于典型的策略设计模式。 ``` TreeMap treeMap = new TreeMap<>(); treeMap.put("maliya","玛利亚"); treeMap.put("leiliya","蕾莉亚"); treeMap.put("charlote","夏洛特"); treeMap.forEach((k,v) -> { System.out.println(k+v); }); /** *默认排序 * charlote夏洛特 * leiliya蕾莉亚 * maliya玛利亚 */ // 倒序排序 TreeMap treeMap = new TreeMap<>((o1,o2) -> { return o2.compareTo(o1); }); // 倒序也可以直接使用Comparator现成的静态方法、 TreeMap treeMap = new TreeMap<>(Comparator.reverseOrder()); /** * maliya玛利亚 * leiliya蕾莉亚 * charlote夏洛特 */ ``` ##### LinkedHashMap: 继承自 HashMap,因此具有和 HashMap 一样的快速查找特性。它与TreeMap的顺序在意义上不一样,它是按照元素的更新来进行排序,可以说,它的排序是动态的。 结构内部维护双向链表保存更新顺序 ``` /** * 链表的头,存放最老的数据 */ transient LinkedHashMap.Entry head; /** * 链表的尾部,存放最新的数据 */ transient LinkedHashMap.Entry tail; ``` accessOrder 决定了顺序,默认为 false,此时维护的是插入顺序。 ``` final boolean accessOrder; ``` > 维护顺序的函数是LinkedHashMap 类的核心,它们会在 put、get 等方法中调用,以实现插入排序或LRU排序。 ``` // 当移除一个元素 void afterNodeRemoval(Node e) { } // 当添加一个元素 void afterNodeInsertion(boolean evict) {} // 当访问一个元素 void afterNodeAccess(Node e) { } ``` - afterNodeAccess 当一个节点被访问时,如果 accessOrder 为 true,则会将该节点移到链表尾部。也就是说指定为 LRU 顺序之后,在每次访问一个节点时,会将这个节点移到链表尾部,保证链表尾部是最近访问的节点,那么链表首部就是最近最久未使用的节点。 - afterNodeInsertion() 在 put 等操作之后执行,当 removeEldestEntry() 方法返回 true 时会移除最晚的节点,也就是链表首部节点 first。evict 只有在构建 Map 的时候才为 false,在这里为 true。 > 在开发中,我们可以直接使用LinkedHashMap 实现的LUR进行自己的业务开发,而不必造同样的车轮。 以上就是有序map实现的排序,当然这里我们只是说map本身是否支持排序,而不代表HashMap不能被排序,我们可以将其转换为list,然后自定义排序规则。 ================================================ FILE: 04.腾讯篇/4.1.8抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口么.md ================================================ #### 问题描述:抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口么 #### 参考答案: - ##### 抽象类 抽象类和抽象方法都使用 abstract 关键字进行声明。如果一个类中包含抽象方法,那么这个类必须声明为抽象类。 抽象类和普通类最大的区别是,抽象类不能被实例化,需要继承抽象类才能实例化其子类。 - ##### 接口 接口是抽象类的延伸,在 Java 8 之前,它可以看成是一个完全抽象的类,因为它不能有任何的方法实现。从 Java 8 开始,接口也可以拥有默认的方法实现,因为不支持默认方法的接口的维护成本太高了。在 Java 8 之前,如果一个接口想要添加新的方法,那么要修改所有实现了该接口的类。 接口的成员(字段 + 方法)默认都是 public 的,并且不允许定义为 private 或者 protected,因为从被设计的意义上来讲,它就是用来被实现的,如果它成员设置为private,自己又没有实现,那么它本身就没有意义了。 接口的字段默认都是 static 和 final 的。 - ##### 区别 1. 从设计层面看,抽象类规定了一种 IS-A 关系,必须满足里式替换原则:即子类对象必须能够替换掉所有父类对象。而接口更像是一种 LIKE-A 关系,它只是提供一种方法实现契约,并不要求接口和实现接口的类具有 IS-A 关系。 2. 从使用上来看,一个类可以实现多个接口,但是不能继承多个抽象类。 3. 接口的字段只能是 static 和 final 类型的,而抽象类的字段没有这种限制。 4. 接口的成员只能是 public 的,而抽象类的成员可以有多种访问权限。 Java中是单继承的,因此同一个类不能继承多个类,只能通过父类再继承,间接实现多继承。 接口可以extends 接口,并且没有数量限制,但是类不能extends 接口;类只能implement 接口,没有数量限制。 > 因此我们不能笼统地说:Java中的接口不能被继承。 ##### 接口和抽象类在使用上的选择: - 接口被用来定义共性方法,它的抽象度和适用范围广,即使8版本之后支持默认的方法实现,但是我们通常不在接口层面定义实现,因为接口的存在就是为了解耦,将具体的实现延迟到子类,获得更好的扩展性。实现同一个接口的类不需要有任何的关联性,它们实现同一个接口只是因为有相同的方法定义需求而已。 - 抽象类通常用来定义相关对象系列,凡是继承了同一个抽象类的对象,它们必定是有着很强的关联性,比如 JDK中的 AbstractMap,TreeMap和HashMap等都继承了AbstractMap,从设计上来说,它们都是从属map容器得我相关系列对象,此处没有选择接口,而是抽象类。 就共享重复代码来说,JDK8之后接口同样能够做到,但这其中的选择就是考虑一个开发者的代码设计能力了。 开发中,应该选择合适的类设计方法,而不是固定地使用其中一种。 ================================================ FILE: 04.腾讯篇/4.1.9继承和聚合的区别在哪.md ================================================ #### 问题:继承和聚合的区别在哪 #### 参考答案: 类与类之间的关系(即事物关系),有继承(泛化)关系、实现关系、组合关系、聚合关系、关联关系和依赖关系6种。继承和聚合属于这六种关系中的其中两种。 - #### 继承 在继承(Generalization,又叫作泛化)关系中,子类继承父类的所有功能,父类所具有的属性、方法,子类都应该有。除了与父类一致的信息,子类中还包括额外的信息。例如所有的类都默认继承了Object 类,因此所有的类都具有 hashCode 、equals 、clone 等方法,但是每个类又都有自己独特的属性和方法。 这种关系必须使用 extends 关键字来表示。 - #### 聚合 聚合(Aggregate)关系表示类之间整体与部分的关系,成员对象是整体对象的一部分,但是成员对象可以脱离整体对象独立存在。例如 TreeMap中的Comparator 和TreeMap就是一种聚合关系,同样的Comparator 可以用于不同的TreeMap,Comparator 的存在不依赖于TreeMap,即使脱离TreeMap,Comparator 本身是具有使用意义的一个类。 ``` public class TreeMap extends AbstractMap implements NavigableMap, Cloneable, java.io.Serializable { private final Comparator comparator; …… } ``` > 聚合强调多个类协调完成一个整体的功能,而继承强调子父类的成员重用和类型兼容。在设计模式中,我们经常回强调类之间的六种关系,这六种关系是完成设计模式的源头。 从关系强度和紧密度来说 继承的关系强度大于聚合。 ================================================ FILE: 04.腾讯篇/4.2.0IO模型有哪些,讲讲你理解的nio,他和bio,aio的区别是啥,谈谈reactor模型.md ================================================ #### 题目:IO模型有哪些,讲讲你理解的nio,他和bio,aio的区别是啥,谈谈reactor模型 #### 参考答案: 我们通常讨论的IO模型重点指的是网络IO,即socket。 一个输入操作通常包括两个阶段: ​ 1 等待数据准备好 ​ 2 从内核向进程复制数据 ##### 对于一个socket的输入操作,第一步通常涉及等待数据从网络中到达,当所等待数据到达时,它被复制到内核中的某个缓冲区。第二步就是把数据从内核缓冲区 ##### 复制到应用进程缓冲区。 > Unix 的五种 I/O 模型: > - 阻塞式 I/O > - 非阻塞式 I/O > - I/O 复用(select 和 poll) > - 信号驱动式 I/O(SIGIO) > - 异步 I/O(AIO) 注意区别同步/异步、阻塞/非阻塞的区别。 ##### 当我们说同步/异步的时候,我们指的是进程在IO的过程中会不会被阻塞,如果会阻塞那么就是同步,不会阻塞就是异步。 ##### 而当我们说阻塞/非阻塞的时候,我们指进程阻塞的阶段,I/O 复用和信号驱动式 I/O在第一阶段不会阻塞,阻塞IO直到IO完成之前一直处于阻塞进程阶段,而非阻塞IO,在第一阶段不会阻塞应用进程,而是轮训第一阶段的数据是否到达,在复制到应用进程缓冲区的过程中会阻塞进程。 ##### `NIO` NIO( New IO) 同步非阻塞IO,从JDK 1.4开始引入了NIO模型,用于丰富IO操作类型,同时变得更加高效。 **NIO在IO过程中,使用 select 或者 poll 等待数据,并且可以等待多个套接字中的任何一个变为可读。这一过程会被阻塞,当某一个套接字可读时返回,之后再使用 recvfrom 把数据从内核复制到进程中。它可以让单个进程具有处理多个 I/O 事件的能力。又被称为 Event Driven I/O,即事件驱动 I/O。** 如果一个 Web 服务器没有 I/O 复用,那么每一个 Socket 连接都需要创建一个线程去处理。如果同时有几万个连接,那么就需要创建相同数量的线程。相比于多进程和多线程技术,I/O 复用不需要进程线程创建和切换的开销,系统开销更小。 相对于BIO的流,NIO抽象出了新的通道(Channel)作为输入输出的通道,并且提供了缓存(Buffer)的支持,在进行读操作时,需要使用Buffer分配空间,然后将数据从Channel中读入Buffer中,对于Channel的写操作,也需要现将数据写入Buffer,然后将Buffer写入Channel中。 `BIO`: 阻塞IO,"最原始的"IO,在IO过程中会一直阻塞当前应用进程(注意其它无关应用进程是不会阻塞的,他并不是说阻塞整个操作系统)。 `AIO` (Asynchronous I/O) 异步非阻塞I/O: 应用进程执行 aio_read 系统调用会立即返回,应用进程可以继续执行,不会被阻塞,内核会在所有操作完成之后向应用进程发送信号。 异步 I/O 与信号驱动 I/O 的区别在于,异步 I/O 的信号是通知应用进程 I/O 完成,而信号驱动 I/O 的信号是通知应用进程可以开始 I/O,也就是说当异步 I/O 的信号发出时,表名已经完成IO,进程直接可以开始使用,因此,AIO不会阻塞应用进程。 ------ ##### reactor 前面了解到,java的NIO是属于同步非阻塞IO,关于IO多路复用,java没有相应的IO模型,但有相应的编程模式,Reactor 就是基于NIO中实现多路复用的一种模式。 reactor 的三种角色: - **Reactor** 将I/O事件分派给对应的Handler - **Acceptor** 处理客户端新连接,并分派请求到处理器链中 - **Handlers** 执行非阻塞读/写 任务 ##### 1 单Reactor单线程模型 ![](../images/image-20210308165404.png) 这是最基本的单Reactor单线程模型。其中Reactor线程,负责多路分离套接字,监听新连接触发connect 事件之后,交由Acceptor进行处理,有IO读写事件之后交给hanlder 处理。 Acceptor主要任务是构建handler ,在获取到和client相关的SocketChannel之后 ,绑定到相应的hanlder上,对应的SocketChannel有读写事件之后,基于racotor 分发,hanlder就可以处理了。 ##### 2 单Reactor多线程模型 ![](../images/image-20210308170213.png) 相对于第一种单线程的模式来说,在处理业务逻辑,也就是获取到IO的读写事件之后,交由线程池来处理,这样可以减小主reactor的性能开销,从而更专注的做事件分发工作了,从而提升整个应用的吞吐。 ##### 3 多Reactor多线程模型 ![](../images/image-20210308170505.png) 第三种模型比起第二种模型,是将Reactor分成两部分, 1. ##### mainReactor负责监听server socket,用来处理新连接的建立,将建立的socketChannel指定注册给subReactor。 2. ##### subReactor维护自己的selector, 基于mainReactor 注册的socketChannel多路分离IO读写事件,读写网 络数据,对业务处理的功能,另其扔给worker线程池来完成。 mainReactor 主要是用来处理网络IO 连接建立操作,通常一个线程就可以处理,而subReactor主要做和建立起来的socket做数据交互和事件业务处理操作,它的个数上一般是和CPU个数等同,每个subReactor一个线程来处理。 此种模型中,每个模块的工作更加专一,耦合度更低,性能和稳定性也大量的提升,支持的可并发客户端数量可达到上百万级别。 ================================================ FILE: 04.腾讯篇/4.2.1反射的原理,反射创建类实例的三种方式是什么.md ================================================ #### 问题:反射的原理,反射创建类实例的三种方式是什么 #### 参考答案: ##### 反射概述 Java中每个类都有一个 Class 对象,描述并包含了与类有关的信息。当编译一个新类时,会产生一个同名的 .class 文件,该文件内容保存着 Class 对象。类加载相当于 Class 对象的加载,类在第一次使用时才动态加载到 JVM 中。也可以使用Class.forName("类完整名") 这种方式来控制类的加载,该方法会返回一个 Class 对象。 也可以使用对象.getClass(),获取该对象的Class。 反射可以提供运行时的类信息,并且这个类可以在运行时才加载进来,甚至在编译时期该类的 .class 不存在也可以加载进来。 ------ **Class** 和 **java.lang.reflect** 一起对反射提供了支持,reflect 类库主要包含了以下三个类: - Field :可以使用 get() 和 set() 方法读取和修改 Field 对象关联的字段; - Method :可以使用 invoke() 方法调用与 Method 对象关联的方法; - Constructor :可以用 Constructor 创建新的对象。 > 示例代码 ``` Class mapClazz = Class.forName("java.util.HashMap"); Method putMethod = mapClazz.getDeclaredMethod("put", Object.class, Object.class); putMethod.setAccessible(true); Constructor constructor = mapClazz.getConstructor(); Object o = constructor.newInstance(); putMethod.invoke(o,"name","休比"); JSONConverter jsonConverter = new JSONConverter(); System.out.println(jsonConverter.convert(o, null).toStringPretty());、 /** * 输出: * { * "name": "休比" * } */ ``` ------ ##### 反射创建实例的三种方式: 1. 对象.class 实际上这表明所有的类都隐含一个class的静态变量。 ``` Class clazz = HashMap.class; ``` 2. 对象实例.getClass() 此为Object通用方法。 ``` Class aClass = new HashMap<>().getClass(); ``` 3. Class.forName("类完整名字") Class静态方法。 ``` Class mapClazz = Class.forName("java.util.HashMap"); ``` 最典型的代理模式经常回用到反射,用于动态创建适合的对象。 ================================================ FILE: 04.腾讯篇/4.2.2反射中,Class.forName和ClassLoader区别.md ================================================ #### 问题描述:反射中,Class.forName和ClassLoader区别 #### 参考答案: 首先,Class.forName() 和 ClassLoader 在功能上都可以对类进行加载。 ClassLoader遵循**双亲委派模型**,最终调用启动类加载器的类加载器,实现的功能是“通过一个类的全限定名来获取描述此类的二进制字节流”,获取到二进制流后放到JVM中。 Class.forName()方法实际上也是调用的ClassLoader来实现的。 Class.forName(String className) 源码示例: ``` private static native Class forName0(String name, boolean initialize, ClassLoader loader, Class caller) throws ClassNotFoundException; /** * Returns the {@code Class} object associated with the class or * interface with the given string name. Invoking this method is * equivalent to: * *
* {@code Class.forName(className, true, currentLoader)} *
*/ @CallerSensitive public static Class forName(String className) throws ClassNotFoundException { Class caller = Reflection.getCallerClass(); return forName0(className, true, ClassLoader.getClassLoader(caller), caller); } ``` 最后调用的方法是forName0这个方法,在这个forName0方法中的第二个参数被默认设置为了true,这个参数代表是否对加载的类进行初始化,设置为true时会类进行初始化,代表会执行类中的静态代码块,以及对静态变量的赋值等操作。 源码注释说明 forName(String className) 此方法等效于调用 Class.forName(className, true, currentLoader) 方法,源码示例: ``` //The class is initialized only if the {@code initialize} parameter is {@code true} and if it has //not been initialized earlier. @CallerSensitive public static Class forName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException { Class caller = null; SecurityManager sm = System.getSecurityManager(); if (sm != null) { // 仅当存在安全管理器时,才需要进行反射性调用以获取调用方类,否则,避免进行此调用的开销。 caller = Reflection.getCallerClass(); if (sun.misc.VM.isSystemDomainLoader(loader)) { ClassLoader ccl = ClassLoader.getClassLoader(caller); if (!sun.misc.VM.isSystemDomainLoader(ccl)) { sm.checkPermission( SecurityConstants.GET_CLASSLOADER_PERMISSION); } } } return forName0(name, initialize, loader, caller); } ``` 源码注释表名 当code initialize参数为true,且先前尚未初始化时,则初始化该类。 ------ 我们代码实际进行测试: ``` public class Shop { static { log.info("##############静态代码块执行"); } private static String name = setName(); private static String setName() { log.info("###########进行了赋值"); return "小林家"; } } ``` 测试: ``` Class loadClass = ClassLoader.getSystemClassLoader().loadClass("pojo.Shop"); /** * */ Class aClass = Class.forName("pojo.Shop"); /** * [main] INFO pojo.Shop - ##############静态代码块执行 * [main] INFO pojo.Shop - ###########进行了赋值 */ ``` 通过测试输出我们发现,ClassLoader#loadClass 并不会对类进行初始化,只是把类加载到了虚拟机中。而Class.forName 加载了类,并对其进行了初始化操作。 ================================================ FILE: 04.腾讯篇/4.2.3描述动态代理的几种实现方式,分别说出相应的优缺点.md ================================================ #### 问题描述:描述动态代理的几种实现方式,分别说出相应的优缺点 #### 参考答案: 首先我们要区分两个含义上的静态代理和动态代理。 从设计模式上来讲:静态代理和动态代理都属于代理模式。 静态代理模式下,代码本身的适用性受到局限,我们可以说是一种"硬编码"的方式:代理类通过构造函数引用**`特定的被代理的类`**,并在执行被代理类的方法时执行一些代理逻辑,达到扩展的目的,因此静态代理的扩展成本较高,不够具有通用性,而且一定程度的通用必须依赖接口。 ------ 为了解决静态代理的通用性问题,产生了动态代理模式,动态代理的实现底层我们不会自己去写,通常是使用已有的动态代理技术,在Java生态中,目前普遍使用的是JDK自带的代理和CGLib提供的类库。 ##### JDK代理 代码示例 ``` public class JDKProxy implements InvocationHandler { private IPerson target; public IPerson getInstance(IPerson person) { this.target = person; Class targetClass = target.getClass(); return (IPerson) Proxy.newProxyInstance(targetClass.getClassLoader(),targetClass.getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { this.before(); Object invoke = method.invoke(this.target, args); this.after(); return invoke; } private void before() { log.info("洗手"); } private void after() { log.info("收拾"); } } ``` ``` public class LiSiBaby implements IPerson{ @Override public void eat() { log.info("大口吃饭"); } } ``` 测试 ``` JDKProxy jdkProxy = new JDKProxy(); IPerson instance = jdkProxy.getInstance(new LiSiBaby()); instance.eat(); /** * design_model.proxy_model.JDKProxy - 洗手 * design_model.proxy_model.LiSiBaby - 大口吃饭 * design_model.proxy_model.JDKProxy - 收拾 */ ``` 可见JDK动态代理的强大之处在于只要规范了接口定义,就可以动态扩展所有实现类,而不需要每个去单独编码。 ##### CGlib代理 代码示例 ``` public class CGlibProxy implements MethodInterceptor { public Object getInstance(Class clazz) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { this.before(); Object invokeSuper = methodProxy.invokeSuper(o, objects); this.after(); return invokeSuper; } private void before() { log.info("洗手"); } private void after() { log.info("收拾"); } } ``` 测试 ``` CGlibProxy cGlibProxy = new CGlibProxy(); LiSiBaby instance = (LiSiBaby) cGlibProxy.getInstance(LiSiBaby.class); instance.eat(); /** * design_model.proxy_model.CGlibProxy.CGlibProxy - 洗手 * design_model.proxy_model.LiSiBaby - 大口吃饭 * design_model.proxy_model.CGlibProxy.CGlibProxy - 收拾 */ ``` 当然了,CGlib并不依赖接口,你可以传入任意对象,并对其进行扩展。 ##### 对比: (1)JDK动态代理实现了被代理对象的接口,CGLib动态代理继承了被代理对象。 (2)JDK动态代理和CGLib动态代理都在运行期生成字节码,JDK动态代理直接写Class字节码,CGLib动态代理使用ASM框架写Class字节码。CGLib动态代理实现更复杂,生成代理类比JDK动态代理效率低。 (3)JDK动态代理调用代理方法是通过反射机制调用的,CGLib动态代理是通过FastClass机制(索引分配直接调用)直接调用方法的,因此CGLib动态代理的执行效率更高。 开发中,我们不必太过纠结性能问题,可以根据自己的实际需求灵活选择。 ================================================ FILE: 05.美团篇/5.2.0 浅复制和深复制?怎样实现深复制?.md ================================================ #### **题目**:浅复制和深复制?怎样实现深复制? #### **出题人**:阿里巴巴新零售技术质量部 #### **参考答案**: #### **参考代码**; ``` const isObject = (item)=>{ return Object.prototype.toString.call(item) === '[object Object]'; } const isArray = (item)=>{ return Object.prototype.toString.call(item) === '[object Array]'; } const deepClone=(obj)=>{ const cloneObj=isArray(obj)?[]:isObject(obj)?{}:''; for(let key in obj){ if(isObject(obj[key])||isArray(obj[key])){ Object.assign(cloneObj,{ [key]: deepClone(Reflect.get(obj,key)) }); } else{ cloneObj[key] = obj[key]; } } return cloneObj; } ``` PS:可以处理这样的格式,仅处理了对象类型和数组类型 ``` const obj111 ={ a:1, b:{ c:2, d:{ e:3 }, f:[1,{a:1,b:2},3] } } ``` ================================================ FILE: 06.字节跳动篇/一棵二叉树,求最大通路长度(即最大左右子树高度之和).md ================================================ #### **题目**:一棵二叉树,求最大通路长度(即最大左右子树高度之和) #### **参考答案**: 该题与leetcode第104题同题型,定义TreeNode结构如下: ```java class TreeNode { int val; TreeNode left; TreeNode right; public TreeNode(int val) { this.val = val; } } ``` 解法一(递归求解) ```java class Solution { public int maxHeight(TreeNode root) { if (root == null) { return 0; } return maxChildHeight(root.left) + maxChildHeight(root.right); } public int maxChildHeight(TreeNode root) { if (root == null) { return 0; } int leftHeight = maxChildHeight(root.left); int rightHeight = maxChildHeight(root.right); return Math.max(leftHeight, rightHeight) + 1; } } ``` 解法二(迭代求解) ```java public class Solution { public int maxHeight(TreeNode root) { if (root == null) { return 0; } return maxChildHeight(root.left) + maxChildHeight(root.right); } public int maxChildHeight(TreeNode root) { int height = 0; Queue queue = new LinkedList<>(); queue.add(root); while (!queue.isEmpty()) { int size = queue.size(); for (int i = 0; i < size; i++) { TreeNode node = queue.poll(); height++; if (node.left != null) { queue.add(node.left); } if (node.right != null) { queue.add(node.right); } } } return height; } } ``` ================================================ FILE: 08.京东篇/简单说一下hadoop和spark的shuffle过程.md ================================================ ##### 问题:**简单说一下hadoop和spark的shuffle过程** ##### 出题人:京东出题专家:阿昀/京东数据中台 ##### 参考答案: Hadoop:map端保存分片数据,通过网络收集到reduce端。 Spark:spark的shuffle实在DAGSchedular划分Stage的时候产生的,TaskSchedular要分发Stage到各个worker的executor。减少shuffle可以提高性能。 ================================================ FILE: 09.MySQL篇/9.1.0 主键 超键 候选键 外键.md ================================================ #### **题目**:主键 超键 候选键 外键是什么 #### 定义 **超键(super key)**: 在关系中能唯一标识元组的属性集称为关系模式的超键 **候选键(candidate key)**: 不含有多余属性的超键称为候选键。也就是在候选键中,若再删除属性,就不是键了! **主键(primary key)**: 用户选作元组标识的一个候选键程序主键 **外键(foreign key)**:如果关系模式R中属性K是其它模式的主键,那么k在模式R中称为外键。 #### 举例 比如有如下数据: | 学号 | 姓名 | 性别 | 年龄 | 系别 | 专业 |:---:|:---:|:---:|:---:|:---:|:---: |20020612 |李辉 |男 |20 |计算机 |软件开发 |20060613| 张明| 男 |18 |计算机 |软件开发 |20060614| 王小玉| 女 |19 |物理 |力学 |20060615| 李淑华| 女 |17 |生物 |动物学 |20060616| 赵静| 男 |21 |化学 |食品化学 |20060617| 赵静| 女 |20 |生物 |植物学 1. 超键 在关系中能唯一标识元组的属性集称为关系模式的超键。 于是我们从例子中可以发现 学号是标识学生实体的唯一标识。那么该元组的超键就为学号。 除此之外我们还可以把它跟其他属性组合起来,比如: (`学号`,`性别`) (`学号`,`年龄`) 这样也是超键. 2. 候选键 不含多余属性的超键为候选键。 根据例子可知,学号是一个可以唯一标识元组的唯一标识,因此学号是一个候选键,实际上,候选键是超键的子集,比如 (学号,年龄)是超键,但是它不是候选键。因为它还有了额外的属性。 3. 主键 用户选择的候选键作为该元组的唯一标识,那么它就为主键。 简单的说,例子中的元组的候选键为学号,但是我们选定他作为该元组的唯一标识,那么学号就为主键。 4. 外键 外键是相对于主键的,比如在学生记录里,主键为学号,在成绩单表中也有学号字段,因此学号为成绩单表的外键,为学生表的主键。 #### 总结 **主键为候选键的子集,候选键为超键的子集,而外键的确定是相对于主键的。** ================================================ FILE: 09.MySQL篇/9.1.1 数据库事务的四个特性及含义.md ================================================ #### **题目**:数据库事务的四个特性及含义 #### **参考答案**: 数据库事务transanction正确执行的四个基本要素。ACID,原子性(Atomicity)、一致性(Correspondence)、隔离性(Isolation)、持久性(Durability)。 * 原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。 * 一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。 * 隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行 相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请 求,使得在同一时间仅有一个请求用于同一数据。 * 持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。 ================================================ FILE: 09.MySQL篇/9.1.2 视图的作用,视图可以更改么?.md ================================================ #### **题目**:视图的作用,视图可以更改么? #### **参考答案**: 视图是虚拟的表,与包含数据的表不一样,视图只包含使用时动态检索数据的查询;不包含任何列或数据。使用视图可以简化复杂的sql操作,隐藏具体的细节,保护数据;视图创建后,可以使用与表相同的方式利用它们。 视图不能被索引,也不能有关联的触发器或默认值,如果视图本身内有order by 则对视图再次order by将被覆盖。 创建视图:create view XXX as XXXXXXXXXXXXXX; 对于某些视图比如未使用联结子查询分组聚集函数Distinct Union等,是可以对其更新的,对视图的更新将对基表进行更新;但是视图主要用于简化检索,保护数据,并不用于更新,而且大部分视图都不可以更新。 ================================================ FILE: 09.MySQL篇/9.1.3 drop,delete与truncate的区别.md ================================================ #### **题目**:drop,delete与truncate的区别 #### **参考答案**: drop直接删掉表 truncate删除表中数据,再插入时自增长id又从1开始 delete删除表中数据,可以加where字句。 (1) DELETE语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作。TRUNCATE TABLE 则一次性地从表中删除所有的数据并不把单独的删除操作记录记入日志保存,删除行是不能恢复的。并且在删除的过程中不会激活与表有关的删除触发器。执行速度快。 (2) 表和索引所占空间。当表被TRUNCATE 后,这个表和索引所占用的空间会恢复到初始大小,而DELETE操作不会减少表或索引所占用的空间。drop语句将表所占用的空间全释放掉。 (3) 一般而言,drop > truncate > delete (4) 应用范围。TRUNCATE 只能对TABLE;DELETE可以是table和view (5) TRUNCATE 和DELETE只删除数据,而DROP则删除整个表(结构和数据)。 (6) truncate与不带where的delete :只删除数据,而不删除表的结构(定义)drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger)索引(index);依赖于该表的存储过程/函数将被保留,但其状态会变为:invalid。 (7) delete语句为DML(Data Manipulation Language),这个操作会被放到 rollback segment中,事务提交后才生效。如果有相应的 tigger,执行的时候将被触发。 (8) truncate、drop是DDL(Data Define Language),操作立即生效,原数据不放到 rollback segment中,不能回滚 (9) 在没有备份情况下,谨慎使用 drop 与 truncate。要删除部分数据行采用delete且注意结合where来约束影响范围。回滚段要足够大。要删除表用drop;若想保留表而将表中数据删除,如果于事务无关,用truncate即可实现。如果和事务有关,或老是想触发trigger,还是用delete。 (10) Truncate table 表名 速度快,而且效率高,因为: truncate table 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少。DELETE 语句每次删除一行,并在事务日志中为所删除的每行记录一项。TRUNCATE TABLE 通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。 (11) TRUNCATE TABLE 删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用 DELETE。如果要删除表定义及其数据,请使用 DROP TABLE 语句。 (12) 对于由 FOREIGN KEY 约束引用的表,不能使用 TRUNCATE TABLE,而应使用不带 WHERE 子句的 DELETE 语句。由于 TRUNCATE TABLE 不记录在日志中,所以它不能激活触发器。 ================================================ FILE: 09.MySQL篇/9.1.4 索引的工作原理及其种类.md ================================================ #### **题目**:索引的工作原理及其种类 #### **参考答案**: **数据库索引**,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。 在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。 为表设置索引要付出代价的:一是增加了数据库的存储空间,二是在插入和修改数据时要花费较多的时间(因为索引也要随之变动)。 图展示了一种可能的索引方式。左边是数据表,一共有两列七条记录,最左边的是数据记录的物理地址(注意逻辑上相邻的记录在磁盘上也并不是一定物理相邻的)。为了加快Col2的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就可以运用二叉查找在O(log2n)的复杂度内获取到相应数据。 创建索引可以大大提高系统的性能。 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。 第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。 也许会有人要问:增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢?因为,增加索引也有许多不利的方面。 第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。 第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。 第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。 索引是建立在数据库表中的某些列的上面。在创建索引的时候,应该考虑在哪些列上可以创建索引,在哪些列上不能创建索引。一般来说,应该在这些列上创建索引:在经常需要搜索的列上,可以加快搜索的速度;在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。 同样,对于有些列不应该创建索引。一般来说,不应该创建索引的的这些列具有下列特点: 第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。 第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。 第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。 第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。 根据数据库的功能,可以在数据库设计器中创建三种索引:唯一索引、主键索引和聚集索引。 唯一索引 唯一索引是不允许其中任何两行具有相同索引值的索引。 当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在employee表中职员的姓(lname)上创建了唯一索引,则任何两个员工都不能同姓。 主键索引 数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。 在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。 聚集索引 在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。 如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。 局部性原理与磁盘预读 由于存储介质的特性,磁盘本身存取就比主存慢很多,再加上机械运动耗费,磁盘的存取速度往往是主存的几百分分之一,因此为了提高效率,要尽量减少磁盘I/O。为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。这样做的理论依据是计算机科学中著名的局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用。程序运行期间所需要的数据通常比较集中。 由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率。 预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多操作系统中,页得大小通常为4k),主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行。 B-/+Tree索引的性能分析 到这里终于可以分析B-/+Tree索引的性能了。 上文说过一般使用磁盘I/O次数评价索引结构的优劣。先从B-Tree分析,根据B-Tree的定义,可知检索一次最多需要访问h个节点。数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧: 每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。 B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)=O(logdN)。一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3)。 而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。 综上所述,用B-Tree作为索引结构效率是非常高的。 ================================================ FILE: 09.MySQL篇/9.1.5 连接的种类.md ================================================ #### **题目**:连接的种类 #### **参考答案**: 查询分析器中执行: ``` --建表table1,table2: create table table1(id int,name varchar(10)) create table table2(id int,score int) insert into table1 select 1,'lee' insert into table1 select 2,'zhang' insert into table1 select 4,'wang' insert into table2 select 1,90 insert into table2 select 2,100 insert into table2 select 3,70 ``` 如表: ``` ------------------------------------------------- table1 | table2 | ------------------------------------------------- id name |id score | 1 lee |1 90| 2 zhang| 2 100| 4 wang| 3 70| ------------------------------------------------- ``` 以下均在查询分析器中执行 一、外连接 1.概念:包括左向外联接、右向外联接或完整外部联接 2.左连接:left join 或 left outer join (1)左向外联接的结果集包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值(null)。 (2)sql 语句 ``` select * from table1 left join table2 on table1.id=table2.id -------------结果------------- idnameidscore ------------------------------ 1lee190 2zhang2100 4wangNULLNULL ------------------------------ ``` 注释:包含table1的所有子句,根据指定条件返回table2相应的字段,不符合的以null显示 3.右连接:right join 或 right outer join (1)右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。 (2)sql 语句 ``` select * from table1 right join table2 on table1.id=table2.id -------------结果------------- idnameidscore ------------------------------ 1lee190 2zhang2100 NULLNULL370 ------------------------------ ``` 注释:包含table2的所有子句,根据指定条件返回table1相应的字段,不符合的以null显示 4.完整外部联接:full join 或 full outer join (1)完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。 (2)sql 语句 ``` select * from table1 full join table2 on table1.id=table2.id -------------结果------------- idnameidscore ------------------------------ 1lee190 2zhang2100 4wangNULLNULL NULLNULL370 ------------------------------ ``` 注释:返回左右连接的和(见上左、右连接) 二、内连接 1.概念:内联接是用比较运算符比较要联接列的值的联接 2.内连接:join 或 inner join 3.sql 语句 ``` select * from table1 join table2 on table1.id=table2.id -------------结果------------- idnameidscore ------------------------------ 1lee190 2zhang2100 ------------------------------ ``` 注释:只返回符合条件的table1和table2的列 4.等价(与下列执行效果相同) ``` A:select a.*,b.* from table1 a,table2 b where a.id=b.id B:select * from table1 cross join table2 where table1.id=table2.id (注:cross join后加条件只能用where,不能用on) ``` 三、交叉连接(完全) 1.概念:没有 WHERE 子句的交叉联接将产生联接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。(table1和table2交叉连接产生3*3=9条记录) 2.交叉连接:cross join (不带条件where...) 3.sql语句 ``` select * from table1 cross join table2 -------------结果------------- idnameidscore ------------------------------ 1lee190 2zhang190 4wang190 1lee2100 2zhang2100 4wang2100 1lee370 2zhang370 4wang370 ------------------------------ ``` 注释:返回3*3=9条记录,即笛卡尔积 4.等价(与下列执行效果相同) ``` A:select * from table1,table2 ``` ================================================ FILE: 09.MySQL篇/9.1.6 数据库范式.md ================================================ #### **题目**:数据库范式 #### **参考答案**: 1 第一范式(1NF) 在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。 所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。简而言之,第一范式就是无重复的列。 2 第二范式(2NF) 第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键、主码。 第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是非主属性非部分依赖于主关键字。 3 第三范式(3NF) 满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性。(我的理解是消除冗余) ================================================ FILE: 09.MySQL篇/9.1.7 数据库优化的思路.md ================================================ #### **题目**:数据库优化的思路 #### **参考答案**: 这个我借鉴了慕课上关于数据库优化的课程。 1.SQL语句优化 - 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。 - 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: ```sql select id from t where num is null ``` 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: ```sql select id from t where num=0 ``` *liueleven* 的评论: ``` 不是非我杠精,关于null,isNull,isNotNull其实是要看成本的,是否回表等因素总和考虑,才会决定是要走索引还是走全表扫描。 ``` 也给大家找了一个作者的博文([MySQL中IS NULL、IS NOT NULL、!=不能用索引?胡扯!](https://mp.weixin.qq.com/s/CEJFsDBizdl0SvugGX7UmQ)),仅供参考!!! [zhiyong0804d的意见] 之所以未把第二条删除还是考虑可能很多人都被误导了。那这样的组织能让大家兼听则明。 - 很多时候用 exists 代替 in 是一个好的选择。 - 用Where子句替换HAVING 子句 因为HAVING 只会在检索出所有记录之后才对结果集进行过滤。 2.索引优化 看上文索引 3.数据库结构优化 - 范式优化: 比如消除冗余(节省空间。。) - 反范式优化:比如适当加冗余等(减少join) - 拆分表:分区将数据在物理上分隔开,不同分区的数据可以制定保存在处于不同磁盘上的数据文件里。这样,当对这个表进行查询时,只需要在表分区中进行扫描,而不必进行全表扫描,明显缩短了查询时间,另外处于不同磁盘的分区也将对这个表的数据传输分散在不同的磁盘I/O,一个精心设置的分区可以将数据传输对磁盘I/O竞争均匀地分散开。对数据量大的时时表可采取此方法。可按月自动建表分区。 - 拆分其实又分垂直拆分和水平拆分: 案例: 简单购物系统暂设涉及如下表: 1.产品表(数据量10w,稳定) 2.订单表(数据量200w,且有增长趋势) 3.用户表 (数据量100w,且有增长趋势) 以mysql为例讲述下水平拆分和垂直拆分,mysql能容忍的数量级在百万静态数据可以到千万 **垂直拆分:** 解决问题:表与表之间的io竞争 不解决问题:单表中数据量增长出现的压力 方案: 把产品表和用户表放到一个server上 订单表单独放到一个server上 **水平拆分:** 解决问题:单表中数据量增长出现的压力 不解决问题:表与表之间的io争夺 方案:**用户表** 通过性别拆分为男用户表和女用户表,**订单表** 通过已完成和完成中拆分为已完成订单和未完成订单,**产品表** 未完成订单放一个server上,已完成订单表盒男用户表放一个server上,女用户表放一个server上(女的爱购物 哈哈)。 4.服务器硬件优化 这个么多花钱咯! ================================================ FILE: 09.MySQL篇/9.1.8 存储过程与触发器的区别.md ================================================ #### **题目**:存储过程与触发器的区别 #### **参考答案**: 触发器与存储过程非常相似,触发器也是SQL语句集,两者唯一的区别是触发器不能用EXECUTE语句调用,而是在用户执行Transact-SQL语句时自动触发(激活)执行。 触发器是在一个修改了指定表中的数据时执行的存储过程。 通常通过创建触发器来强制实现不同表中的逻辑相关数据的引用完整性和一致性。由于用户不能绕过触发器,所以可以用它来强制实施复杂的业务规则,以确保数据的完整性。 触发器不同于存储过程,触发器主要是通过事件执行触发而被执行的,而存储过程可以通过存储过程名称名字而直接调用。当对某一表进行诸如UPDATE、INSERT、DELETE这些操作时,SQLSERVER就会自动执行触发器所定义的SQL语句,从而确保对数据的处理必须符合这些SQL语句所定义的规则。 ================================================ FILE: 09.MySQL篇/9.1.9 解释 SQL 的 left join 和 right join.md ================================================ #### **题目**:解释 SQL 的 left join 和 right join #### 出题人:阿里巴巴新零售技术质量部 #### **参考答案**: left join 和 right join 都是两个表进行 merge 的操作,left join 是将右边的表 merge 到左边,right join 是将左边的表 merge 到右边,通常我们会指定按照哪几列进行 merge 举个例子: **left table** | 姓名 | 学号 | | ---- | --------- | | 小红 | SZ1716029 | | 小明 | SZ1716030 | | 小王 | SZ1716031 | **right table** | 学号 | 排名 | | --------- | ---- | | SZ1716029 | 1 | | SZ1716030 | 2 | **left table** left join **right table** on 学号 | 学号 | 姓名 | 排名 | | --------- | ---- | ---- | | SZ1716029 | 小红 | 1 | | SZ1716030 | 小明 | 2 | | SZ1716031 | 小王 | NULL | **left table** right join **right table** on 学号 | 学号 | 姓名 | 排名 | | --------- | ---- | ---- | | SZ1716029 | 小红 | 1 | | SZ1716030 | 小明 | 2 | ================================================ FILE: 10.Redis篇/10.1.0 使用Redis有哪些好处?.md ================================================ #### **题目**: #### **参考答案**: (1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) (2) 支持丰富数据类型,支持string,list,set,sorted set,hash (3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行 (4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除 ================================================ FILE: 10.Redis篇/10.1.1 redis相比memcached有哪些优势?.md ================================================ #### **redis相比memcached有哪些优势?**: #### **参考答案**: (1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型 (2) redis的速度比memcached快很多 (3) redis可以持久化其数据 ================================================ FILE: 10.Redis篇/10.1.2 redis常见性能问题和解决方案.md ================================================ #### **题目**:redis常见性能问题和解决方案 #### **参考答案**: (1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件 (2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次 (3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内 (4) 尽量避免在压力很大的主库上增加从库 (5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3... 这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。 ================================================ FILE: 10.Redis篇/10.1.3 MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据.md ================================================ #### **题目**:MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据 #### **参考答案**: 相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略: voltile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰 volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰 volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰 allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰 allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰 no-enviction(驱逐):禁止驱逐数据 ================================================ FILE: 10.Redis篇/10.1.3 zookeeper的四种类型的znode.md ================================================ #### **题目**:zookeeper的四种类型的znode #### **参考答案**: 1、PERSISTENT-持久化目录节点 客户端与zookeeper断开连接后,该节点依旧存在 2、PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点 客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号 3、EPHEMERAL-临时目录节点 客户端与zookeeper断开连接后,该节点被删除 4、EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点 客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号 ================================================ FILE: 10.Redis篇/10.1.4 Memcache与Redis的区别都有哪些?.md ================================================ #### **题目**:Memcache与Redis的区别都有哪些? #### **参考答案**: 1)、存储方式 Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。 Redis有部份存在硬盘上,这样能保证数据的持久性。 2)、数据支持类型 Memcache对数据类型支持相对简单。 Redis有复杂的数据类型。 3)、使用底层模型不同 它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。 Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。 4),value大小 redis最大可以达到1GB,而memcache只有1MB ================================================ FILE: 10.Redis篇/10.1.5 Redis 常见的性能问题都有哪些?如何解决?.md ================================================ #### **题目**:Redis 常见的性能问题都有哪些?如何解决? #### **参考答案**: 1) Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。 2) Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。 3) Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。 4) Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内 ================================================ FILE: 10.Redis篇/10.1.6 redis最适合的场景.md ================================================ #### **题目**:redis 最适合的场景 #### **参考答案**: Redis最适合所有数据in-memory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用Memcached,何时使用Redis呢? 如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点: 1) Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。 2) Redis支持数据的备份,即master-slave模式的数据备份。 3) Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用 ================================================ FILE: 10.Redis篇/10.1.7 Redis的同步机制了解么?.md ================================================ #### **题目**:Redis的同步机制了解么? #### **参考答案**: 主从同步。第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接受完成后将rdb镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。 ================================================ FILE: 10.Redis篇/10.1.8 是否使用过Redis集群,集群的原理是什么?.md ================================================ #### **题目**:是否使用过Redis集群,集群的原理是什么? #### **参考答案**: Redis Sentinel着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。 Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。 ================================================ FILE: 11.MongoDB篇/11.1.0 什么是MongoDB?.md ================================================ #### **题目**:什么是MongoDB #### **参考答案**: MongoDB是一个文档数据库,提供好的性能,领先的非关系型数据库。采用BSON存储文档数据。2007年10月,MongoDB由10gen团队所发展。2009年2月首度推出。获得安装包和查看详细的API可以访问官网网址www.mongodb.com ================================================ FILE: 11.MongoDB篇/11.1.1 MongoDB是由哪种语言写的?.md ================================================ #### **题目**:MongoDB是由哪种语言写的 #### **参考答案**: MongoDB用c++编写的,流行的开源数据库MySQL也是用C++开发的。C++1983年发行是一种使用广泛的计算机程序设计语言。它是一种通用程序设计语言,支持多重编程模式。 ================================================ FILE: 11.MongoDB篇/11.1.2 MongoDB的优势有哪些?.md ================================================ #### **题目**:MongoDB的优势有哪些 #### **参考答案**: 面向文档的存储:文档存储以BSON格式(有大小限制,最大16M), 内置GridFS文件系统(一般存储大于16M的文件)。 * 任何属性都可以建立索引。 * 复制以及高可扩展性。 * 自动分片。 * 丰富的查询功能。 * 快速的即时更新。 * 来自 MongoDB 的专业支持。 ================================================ FILE: 11.MongoDB篇/11.1.3 什么是数据库?.md ================================================ #### **题目**:什么是数据库 #### **参考答案**: 数据库可以看成是一个电子化的文件柜,用户可以对文件中的数据运行新增、检索、更新、删除等操作。数据库是一个所有集合的容器,在文件系统中每一个数据库都有一个相关的物理文件。 ================================================ FILE: 11.MongoDB篇/11.1.4 什么是集合?.md ================================================ #### **题目**:什么是集合 #### **参考答案**: 集合就是一组 MongoDB 文档。它相当于关系型数据库(RDBMS)中的表这种概念。集合位于单独的一个数据库中。一个集合内的多个文档可以有多个不同的字段。一般来说,集合中的文档都有着相同或相关的目的。 ================================================ FILE: 11.MongoDB篇/11.1.5 什么是文档?.md ================================================ #### **题目**:什么是文档 #### **参考答案**: 文档由一组key value组成。文档是动态模式,这意味着同一集合里的文档不需要有相同的字段和结构。在关系型数据库中table中的每一条记录相当于MongoDB中的一个文档。 ================================================ FILE: 11.MongoDB篇/11.1.6 MongoDB和关系型数据库术语对比图.md ================================================ ================================================ FILE: 11.MongoDB篇/11.1.7 什么是“mongod”?.md ================================================ #### **题目**:什么是”mongod“ #### **参考答案**: mongod是处理MongoDB系统的主要进程。它处理数据请求,管理数据存储,和执行后台管理操作。当我们运行mongod命令意味着正在启动MongoDB进程,并且在后台运行。 ================================================ FILE: 11.MongoDB篇/11.1.8 “mongod”参数有什么?.md ================================================ #### **题目**:"mongod"参数有什么 #### **参考答案**: 传递数据库存储路径,默认是"/data/db" 端口号 默认是 "27017" ================================================ FILE: 11.MongoDB篇/11.1.9 什么是“mongo”?.md ================================================ #### **题目**:什么是"mongo" #### **参考答案**: 它是一个命令行工具用于连接一个特定的mongod实例。当我们没有带参数运行mongo命令它将使用默认的端口号和localhost连接。 ================================================ FILE: 11.MongoDB篇/11.2.0 MongoDB哪个命令可以切换数据库?.md ================================================ #### **题目**:MongoDB哪个命令可以切换数据库 #### **参考答案**: MongoDB 用use+数据库名称的方式来创建数据库。use会创建一个新的数据库,如果该数据库存在,则返回这个数据库。 >use database_name ================================================ FILE: 11.MongoDB篇/11.2.1 什么是非关系型数据库?.md ================================================ #### **题目**:什么是非关系型数据库 #### **参考答案**: 非关系型数据库是对不同于传统关系型数据库的统称。非关系型数据库的显著特点是不使用SQL作为查询语言,数据存储不需要特定的表格模式。由于简单的设计和非常好的性能所以被用于大数据和Web Apps等 ================================================ FILE: 11.MongoDB篇/11.2.2 非关系型数据库有哪些类型?.md ================================================ #### **题目**:非关系型数据库有哪些类型 #### **参考答案**: * Key-Value 存储 Eg:Amazon S3 * 图表 Eg:Neo4J * 文档存储 Eg:MongoDB * 基于列存储 Eg:Cassandra ================================================ FILE: 11.MongoDB篇/11.2.3 为什么用MOngoDB?.md ================================================ #### **题目**:为什么用MOngoDB? #### **参考答案**: * 架构简单 * 没有复杂的连接 * 深度查询能力,MongoDB支持动态查询。 * 容易调试 * 容易扩展 * 不需要转化/映射应用对象到数据库对象 * 使用内部内存作为存储工作区,以便更快的存取数据。 ================================================ FILE: 11.MongoDB篇/11.2.4 在哪些场景使用MongoDB?.md ================================================ #### **题目**:在哪些场景使用MongoDB #### **参考答案**: * 大数据 * 内容管理系统 * 移动端Apps * 数据管理 ================================================ FILE: 11.MongoDB篇/11.2.5 MongoDB中的命名空间是什么意思.md ================================================ #### **题目**:MongoDB中的命名空间是什么意思? #### **参考答案**: MongoDB内部有预分配空间的机制,每个预分配的文件都用0进行填充。 数据文件每新分配一次,它的大小都是上一个数据文件大小的2倍,每个数据文件最大2G。 MongoDB每个集合和每个索引都对应一个命名空间,这些命名空间的元数据集中在16M的*.ns文件中,平均每个命名占用约 628 字节,也即整个数据库的命名空间的上限约为24000。 如果每个集合有一个索引(比如默认的_id索引),那么最多可以创建12000个集合。如果索引数更多,则可创建的集合数就更少了。同时,如果集合数太多,一些操作也会变慢。 要建立更多的集合的话,MongoDB 也是支持的,只需要在启动时加上“--nssize”参数,这样对应数据库的命名空间文件就可以变得更大以便保存更多的命名。这个命名空间文件(.ns文件)最大可以为 2G。 每个命名空间对应的盘区不一定是连续的。与数据文件增长相同,每个命名空间对应的盘区大小都是随分配次数不断增长的。目的是为了平衡命名空间浪费的空间与保持一个命名空间数据的连续性。 需要注意的一个命名空间$freelist,这个命名空间用于记录不再使用的盘区(被删除的Collection或索引)。每当命名空间需要分配新盘区时,会先查看$freelist是否有大小合适的盘区可以使用,如果有就回收空闲的磁盘空间。 ================================================ FILE: 11.MongoDB篇/11.2.6 哪些语言支持MongoDB.md ================================================ #### **题目** : 哪些语言支持MongoDB? #### **参考答案**: * C * C++ * C# * Java * Node.js * Perl * Php 等 ================================================ FILE: 11.MongoDB篇/11.2.7 在MongoDB中如何创建一个新的数据库?.md ================================================ #### **题目**:在MongoDB中如何创建一个新的数据库 #### **参考答案**: MongoDB 用 use + 数据库名称 的方式来创建数据库。use 会创建一个新的数据库,如果该数据库存在,则返回这个数据库。 >use mydb switched to db mydb ================================================ FILE: 11.MongoDB篇/11.2.8 在MongoDB中如何查看数据库列表?.md ================================================ #### **题目**:在MongoDB中如何查看数据库列表 #### **参考答案**: 使用命令"show dbs" >show dbs ================================================ FILE: 11.MongoDB篇/11.2.9 MongoDB中的分片是什么意思?.md ================================================ #### **题目**:MongoDB中的分片是什么意思 #### **参考答案**: 分片是将数据水平切分到不同的物理节点。当应用数据越来越大的时候,数据量也会越来越大。当数据量增长时,单台机器有可能无法存储数据或可接受的读取写入吞吐量。利用分片技术可以添加更多的机器来应对数据量增加以及读写操作的要求。 参考:[https://docs.mongodb.com/manual/sharding/](https://docs.mongodb.com/manual/sharding/) ================================================ FILE: 11.MongoDB篇/11.3.0 如何查看使用MongoDB的连接?.md ================================================ 如何查看使用MongoDB的连接Sharding - MongoDB Manual21.如何查看使用MongoDB的连接 使用命令"db.adminCommand(“connPoolStats”)" >db.adminCommand(“connPoolStats”) ================================================ FILE: 11.MongoDB篇/11.3.1 什么是复制?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.3.2 在MongoDB中如何在集合中插入一个文档?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.3.3 在MongoDB中如何除去一个数据库?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.3.4 在MongoDB中如何创建一个集合?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.3.5 在MongoDB中如何查看一个已经创建的集合?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.3.6 在MongoDB中如何删除一个集合?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.3.7 为什么要在MongoDB中使用分析器?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.3.8 MongoDB支持主键外键关系吗?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.3.9 MongoDB支持哪些数据类型?.md ================================================ + String + Integer + Double + Boolean + Object + Object ID + Arrays + Min/Max Keys + Datetime + Code + Regular Expression等 ================================================ FILE: 11.MongoDB篇/11.4.0 为什么要在MongoDB中用Code数据类型?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.4.1 为什么要在MongoDB中用Regular Expression数据类型?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.4.2 为什么在MongoDB中使用Object ID数据类型?.md ================================================ 不使用自增是分布式维护起来非常困难。使用ObjectId可以保证不同机器都能用全局唯一的同种方法生成它并且确保不重复 ================================================ FILE: 11.MongoDB篇/11.4.3 如何在集合中插入一个文档?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.4.4 “ObjectID”有哪些部分组成?.md ================================================ 一共有四部分组成:时间戳、客户端ID、客户进程ID、三个字节的增量计数器 ================================================ FILE: 11.MongoDB篇/11.4.5 在MongoDb中什么是索引?.md ================================================ 索引是为了解决数据搜索效率低下引入的一种特殊的数据结构。索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。简单的说,索引就是将`文档`按照某个(或某些)字段顺序组织起来,以便能根据该字段高效的查询。 ================================================ FILE: 11.MongoDB篇/11.4.6 如何添加索引?.md ================================================ MongoDB支持多种类型的索引,包括单字段索引、复合索引、多key索引、文本索引等,每种类型的索引有不同的使用场合。 按照类型可分为: 1. 单字段索引 ```db.person.createIndex( {age: 1} ) ``` 对`person`集合建立对`age`的索引。 `{age: 1}` 代表升序索引,也可以通过`{age: -1}`来指定降序索引,对于单字段索引,升序/降序效果是一样的。 2. 复合索引 ``` db.person.createIndex( {age: 1, name: 1} ) ``` 他是单字段索引的升级,可以对多个字段进行索引。按第一个字段排序,第一个字段相同的文档按第二个字段排序。 3. 多key索引 ``` {"name" : "jack", "age" : 19, habbit: ["football, runnning"]} db.person.createIndex( {habbit: 1} ) // 自动创建多key索引 db.person.find( {habbit: "football"} ) ``` 当索引的字段为数组时,创建出的索引称为多key索引,多key索引会为数组的每个元素建立一条索引,比如person表加入一个`habbit`字段(数组)用于描述兴趣爱好,需要查询有相同兴趣爱好的人就可以利用`habbit`字段的多key索引。 4. 其他索引 ================================================ FILE: 11.MongoDB篇/11.4.7 MongoDB有哪些可替代产品?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.4.8 如何查询集合中的文档?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.4.9 用什么方法可以格式化输出结果?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.5.0 如何使用AND或OR条件循环查询集合中的文档?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.5.1 在MongoDB中如何更新数据?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.5.2 如何删除文档?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.5.3 在MongoDB中如何排序?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.5.4 什么是聚合?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.5.5 在MongoDB中什么是副本集?.md ================================================ ================================================ FILE: 11.MongoDB篇/11.5.6 Mongodb存储特性与内部原理.md ================================================ ================================================ FILE: 12.Zookeeper篇/12.1.0 zookeeper是什么?.md ================================================ #### **参考答案**: > A high-performance coordination service for distributed applications Zookeeper是基于Google Chubby论文的开源实现,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、配置管理 等等。 由于Hadoop生态系统中很多项目都依赖于zookeeper,如Pig,Hive等, 似乎很像一个动物园管理员,于是取名为Zookeeper。 ================================================ FILE: 12.Zookeeper篇/12.1.1 zookeeper提供了什么?.md ================================================ #### **题目**:zookeeper提供了什么? #### **参考答案**: 1、文件系统 2、通知机制 ================================================ FILE: 12.Zookeeper篇/12.1.2 zookeeper文件系统.md ================================================ #### **题目**:zookeeper文件系统 #### **参考答案**: zookeeper提供一个类似unix文件系统目录的多层级节点命名空间(节点称为znode)。与文件系统不同的是,这些节点都可以设置关联的数据,而文件系统中只有文件节点可以存放数据而目录节点不行。zookeeper为了保证高吞吐和低延迟,在内存中维护了这个树状的目录结构,这种特性使得zookeeper不能用于存放大量的数据,每个节点的存放数据上限为1M。 ================================================ FILE: 12.Zookeeper篇/12.1.3 zookeeper的四种类型的znode.md ================================================ #### 题目:zookeeper的四种类型的znode #### 参考答案: PERSISTENT 持久化节点 PERSISTENT_SEQUENTIAL 顺序自动编号持久化节点,这种节点会根据当前已存在的节点数自动加 1 EPHEMERAL 临时节点, 客户端session超时这类节点就会被自动删除 EPHEMERAL_SEQUENTIAL 临时自动编号节点 ================================================ FILE: 12.Zookeeper篇/12.1.4 zookeeper通知机制.md ================================================ #### **题目**:zookeeper通知机制 #### **参考答案**: client端会对某个znode建立一个watcher事件,当该znode发生变化时,zk会主动通知watch这个znode的client,然后client根据znode的变化来做出业务上的改变等。 #### watcher的特点: - 轻量级:一个callback函数。 - 异步性:不会block正常的读写请求。 - 主动推送:Watch被触发时,由Zookeeper服务端主动将更新推送给客户端。 - 一次性:数据变化时,Watch只会被触发一次。如果客户端想得到后续更新的通知,必须要在 Watch 被触发后重新注册一个 Watch。 - 仅通知:仅通知变更类型,不附带变更后的结果。 - 顺序性:如果多个更新触发了多个Watch,那 Watch 被触发的顺序与更新顺序一致。 #### 使用watch的注意事项: - 由于watcher是一次性的,所以需要自己去实现永久watch - 如果被watch的节点频繁更新,会出现“丢数据”的情况 - watcher数量过多会导致性能下降 ================================================ FILE: 12.Zookeeper篇/12.1.5 zookeeper有哪些应用场景?.md ================================================ #### **题目**:zookeeper有哪些应用场景 #### **参考答案**: 1、名字服务 2、配置管理 3、集群管理 4、分布式锁 5、队列管理 6、消息订阅 ================================================ FILE: 12.Zookeeper篇/12.1.6 zk的命名服务.md ================================================ #### **题目**: zk的命名服务 #### **参考答案**: 命名服务是指通过指定的名字来获取资源或者服务的地址,利用zk创建一个全局的路径,即是唯一的路径,这个路径就可以作为一个名字,指向集群中的集群,提供的服务的地址,或者一个远程的对象等等。 ================================================ FILE: 12.Zookeeper篇/12.1.7 zk的配置管理服务.md ================================================ #### **题目**:zk的配置管理 #### **参考答案**: 程序分布式的部署在不同的机器上,将程序的配置信息放在zk的znode下,当有配置发生改变时,也就是znode发生变化时,可以通过改变zk中某个目录节点的内容,利用watcher通知给各个客户端,从而更改配置。 ================================================ FILE: 12.Zookeeper篇/12.1.8 zk的集群管理.md ================================================ #### **题目**:zookeeper集群管理 #### **参考答案**: 所谓集群管理无在乎两点:是否有机器退出和加入、选举master。 对于第一点,所有机器约定在父目录下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道:它上船了。 新机器加入也是类似,所有机器收到通知:新兄弟目录加入,highcount又有了,对于第二点,我们稍微改变一下,所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好。 ================================================ FILE: 12.Zookeeper篇/12.1.9 zk的分布式锁.md ================================================ #### **题目**:zookeeper分布式锁 #### **参考答案**: 有了zookeeper的一致性文件系统,锁的问题变得容易。锁服务可以分为两类,一个是保持独占,另一个是控制时序。 对于第一类,我们将zookeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建的distribute_lock 节点就释放出锁。 对于第二类, /distribute_lock 已经预先存在,所有客户端在它下面创建临时顺序编号目录节点,和选master一样,编号最小的获得锁,用完删除,依次方便。 **获取分布式锁的流程** 在获取分布式锁的时候在locker节点下创建临时顺序节点,释放锁的时候删除该临时节点。客户端调用createNode方法在locker下创建临时顺序节点, 然后调用getChildren(“locker”)来获取locker下面的所有子节点,注意此时不用设置任何Watcher。客户端获取到所有的子节点path之后,如果发现自己创建的节点在所有创建的子节点序号最小,那么就认为该客户端获取到了锁。如果发现自己创建的节点并非locker所有子节点中最小的,说明自己还没有获取到锁,此时客户端需要找到比自己小的那个节点,然后对其调用exist()方法,同时对其注册事件监听器。之后,让这个被关注的节点删除,则客户端的Watcher会收到相应通知,此时再次判断自己创建的节点是否是locker子节点中序号最小的,如果是则获取到了锁,如果不是则重复以上步骤继续获取到比自己小的一个节点并注册监听。当前这个过程中还需要许多的逻辑判断。 代码的实现主要是基于互斥锁,获取分布式锁的重点逻辑在于BaseDistributedLock,实现了基于Zookeeper实现分布式锁的细节。 ================================================ FILE: 12.Zookeeper篇/12.2.0 zk队列管理.md ================================================ #### **题目**:zk队列管理 #### **参考答案**: 两种类型的队列: 1、同步队列,当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。 2、队列按照 FIFO 方式进行入队和出队操作。 第一类,在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。 第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。在特定的目录下创建PERSISTENT_SEQUENTIAL节点,创建成功时Watcher通知等待的队列,队列删除序列号最小的节点用以消费。此场景下Zookeeper的znode用于消息存储,znode存储的数据就是消息队列中的消息内容,SEQUENTIAL序列号就是消息的编号,按序取出即可。由于创建的节点是持久化的,所以不必担心队列消息的丢失问题。 ================================================ FILE: 12.Zookeeper篇/12.2.1 zk数据复制.md ================================================ #### **题目**:zk数据复制 #### **参考答案**: Zookeeper作为一个集群提供一致的数据服务,自然,它要在所有机器间做数据复制。
数据复制的好处:
1、容错:一个节点出错,不致于让整个系统停止工作,别的节点可以接管它的工作;
2、提高系统的扩展能力 :把负载分布到多个节点上,或者增加节点来提高系统的负载能力;
3、提高性能:让客户端本地访问就近的节点,提高用户访问速度。

从客户端读写访问的透明度来看,数据复制集群系统分下面两种:
1、写主(WriteMaster) :对数据的修改提交给指定的节点。读无此限制,可以读取任何一个节点。这种情况下客户端需要对读与写进行区别,俗称读写分离;
2、写任意(Write Any):对数据的修改可提交给任意的节点,跟读一样。这种情况下,客户端对集群节点的角色与变化透明。
对zookeeper来说,它采用的方式是写任意。通过增加机器,它的读吞吐能力和响应能力扩展性非常好,而写,随着机器的增多吞吐能力肯定下降(这也是它建立observer的原因),而响应能力则取决于具体实现方式,是延迟复制保持最终一致性,还是立即复制快速响应。 ================================================ FILE: 12.Zookeeper篇/12.2.2 zk中zab的工作原理.md ================================================ #### **题目**:zk中zab的工作原理 #### **参考答案**: ZAB 是 ZooKeeper Atomic Broadcast (ZooKeeper 原子广播协议)的缩写,它是特别为 ZooKeeper 设计的崩溃可恢复的原子消息广播算法。ZooKeeper 使用 Leader来接收并处理所有事务请求,并采用 ZAB 协议,将服务器数据的状态变更以事务 Proposal 的形式广播到所有的 Follower 服务器上去。这种主备模型架构保证了同一时刻集群中只有一个服务器广播服务器的状态变更,因此能够很好的保证事物的完整性和顺序性。 Zab协议有两种模式,它们分别是恢复模式(recovery)和广播模式(broadcast)。当服务启动或者在leader崩溃后,Zab就进入了恢复模式,当leader被选举出来,且大多数follower完成了和leader的状态同步以后, 恢复模式就结束了,ZAB开始进入广播模式。 ================================================ FILE: 12.Zookeeper篇/12.2.3 zk是如何保证事务的顺序一致性.md ================================================ #### **题目**:zookeeper是如何保证事务的顺序一致性的? #### **参考答案**: zookeeper采用了递增的事务Id来标识,所有的proposal(提议)都在被提出的时候加上了zxid,zxid实际上是一个64位的数字,高32位是epoch(时期; 纪元; 世; 新时代)用来标识leader是否发生改变,如果有新的leader产生出来,epoch会自增,低32位用来递增计数。当新产生proposal的时候,会依据数据库的两阶段过程,首先会向其他的server发出事务执行请求,如果超过半数的机器都能执行并且能够成功,那么就会开始执行。 ================================================ FILE: 12.Zookeeper篇/12.2.4 zk集群下server工作状态.md ================================================ #### **题目**:zk集群下server工作状态 #### **参考答案**: 每个Server在工作过程中有四种状态: LOOKING:当前Server不知道leader是谁,正在搜寻 LEADING:当前server角色为leader FOLLOWING:当前server角色为follower OBSERVING:当前server角色为observer ================================================ FILE: 12.Zookeeper篇/12.2.5 zk是如何选举Leader的?.md ================================================ #### **题目**:zookeeper是如何选举Leader的? #### **参考答案**: 当leader崩溃或者leader失去大多数的follower,这时zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的Server都恢复到一个正确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos。 1、Zookeeper选主流程(basic paxos) (1)选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server; (2)选举线程首先向所有Server发起一次询问(包括自己); (3)选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中; (4)收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server; (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会记录事务日志并定期进行快照,方便在恢复时进行状态恢复。 2、Zookeeper选主流程(fast paxos) fast paxos流程是在选举过程中,某Server首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和 zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。 ================================================ FILE: 12.Zookeeper篇/12.2.6 zk同步流程.md ================================================ #### **题目**:zookeeper同步流程 #### **参考答案**: 选完Leader以后,zk就进入状态同步过程。 1. Leader等待Follower和Observer连接; 2. Follower连接leader,将最大的zxid发送给leader; 3. Leader根据follower的zxid确定同步点; 4. 完成同步后通知follower 已经成为uptodate状态; 5. Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。 数据同步的4种方式: 1、SNAP-全量同步 - 条件:peerLastZxidmaxCommittedLog - 说明:证明follower上有些提议proposal并未在leader上提交,follower需要回滚到zxid为maxCommittedLog对应的事务操作 4、TRUNC+DIFF-回滚+增量同步 - 条件:minCommittedLog<=peerLastZxid<=maxCommittedLog - 说明:leader a已经将事务truncA提交到本地事务日志中,但没有成功发起proposal协议进行投票就宕机了;然后集群中剔除原leader a重新选举出新leader b,又提交了若干新的提议proposal,然后原leader a重新服务又加入到集群中说明:此时a,b都有一些对方未提交的事务,若b是leader, a需要先回滚truncA然后增量同步新leader b上的数据。 ================================================ FILE: 12.Zookeeper篇/12.2.7 分布式通知和协调.md ================================================ #### **题目**:分布式通知和协调 #### **参考答案**: 对于系统调度来说:操作人员发送通知实际是通过控制台改变某个节点的状态,然后zk将这些变化发送给注册了这个节点的watcher的所有客户端。 对于执行情况汇报:每个工作进程都在某个目录下创建一个临时节点。并携带工作的进度数据,这样汇总的进程可以监控目录子节点的变化获得工作进度的实时的全局情况。 ================================================ FILE: 12.Zookeeper篇/12.2.8 zk的session机制.md ================================================ #### **题目**:zk的session机制 #### **参考答案**: zookeeper会为每个客户端分配一个session,类似于web服务器一样,用来标识客户端的身份。 session的作用: - 客户端标识 - 超时检查 - 请求的顺序执行 - 维护临时节点的生命周期 - watcher通知 session的状态: - CONNECTING - CONNECTED - RECONNECTING - RECONNECTED - CLOSED session的属性: - SessionID:会话ID,全局唯一 - TimeOut:会话超时时间 - TickTime:下次会话超时时间点 - isClosing:会话是否已经被关闭 sessionID的构成: - 高8位代表创建Session时所在的zk节点的id - 中间40位代表zk节点当前角色在创建的时候的时间戳 - 低16位是一个计数器,初始值为0 ================================================ FILE: 21.面经/2020秋招面经总结.md ================================================ @[LiuYongQiang6](https://github.com/LiuYongQiang6) # 目标岗位 本硕均为机电专业相关,比赛和项目也是软硬件结合,个人软开背景中学已经学过pascal和数据结构与算法,大学本科除了C语言和微机原理基本没学过CS相关课程,研究生才把操作系统、组原以及计算机网络补上,顺便补了个c++,抽空玩linux,秋招前3个月开始刷题(牛客300,力扣350)。 **第一目标岗位:嵌入式软件。**
**第二目标岗位:C++后台开发。**
**第三目标岗位:游戏相关岗位以及硬件。**
投递公司:大疆深圳(嵌入式软件,offer),华为杭州(操作系统内核开发,offer,签约),小米武汉(物联网嵌入式软件,offer),远景智能(C++后台,offer),网易雷火游戏服务器提前批(笔试挂),网易雷火游戏测试开发(offer),中兴南京(软件开发,offer),网易互娱游戏策划(一面挂),腾讯(c++后台,笔试挂),oppo(c/c++软件开发,笔试通过拒绝面试),小马智行/图森未来(简历石沉大海),株洲中车时代电气(大数据智能部门?,offer),。 ## 前期准备 今年秋招前期体验十分艰难,十分庆幸当时没有轻信师兄做深度学习,学完吴恩达的机器学习课程及时刹车选择了做自己喜欢的嵌入式linux开发方向,顺便利用学习下来的东西一个人参加了下中兴算法大赛,摸了个名次,并且找了个学校附近的物联网公司做嵌入式linux的实习,下班复习基础与刷题:
**1. 笔试刷题** ,非常重要,不然面试机会都没有,leetcode感觉是普通应用题,实际笔试可能是综合应用题,我采取的是专题速刷,半个月回顾一次;
**2. 专业面试准备** ,重点复习数据结构、操作系统与计算机网络,我采取的方式先看别人的面经总结,并结合笔记,最后结合书籍构建系统,有时间可以看看源码,个人除了后台相关重点关注了嵌入式相关的总结以及linux源码分析,深入理解linux内核,linux驱动开发。
**3. 综合面试准备**,个人项目精炼,个人职责,亮点总结,个人项目介绍从结构、硬件、软件角度分析,完成的工作,可采用第一点、第二点等方法表示,个人项目逐点介绍采用为什么?怎么做?取得的效果?流程介绍,并准备一两个超级亮点和超级难点(你并未解决)。 ## 面经 **1.大疆**:
**一面**,仔细询问笔试细节,并且挖深,被仔细询问了在笔试中用的bitmap算法,为何要用,有什么特点,怎么做的,然后抓住linux驱动开发项目追问细节,并引申,open/read/write等函数具体是怎么工作的,从用户态的系统调用闻到内核态的数据结构,基数树等,内存管理相关问到了linux系统中页缓存、缓存命中以及mmap相关的问题,比如两个大文件需要进行交互如何做,中断的上半部以及下半部等,为何要设置上半部和下半部,怎么做的,自旋锁和互斥锁的区别以及应用场景,如何实现一把自旋锁。
**二面**,基本就是问项目,RM比赛中学到了什么,比赛看了没有,觉得有什么问题,哪些可以改进,如果让你重新设计一个机器人,你希望设计出什么新功能可以在比赛中取到突出的效果。项目中涉及到硬件电路设计,被问到了信号链如何分析以及电源管理如何设计,开关电源与线性稳压器的对比,能接受提前实习么?
**三面**,应该是个pm,项目介绍,你觉得你做的最好的是哪块,最差的是哪块,个人优缺点,合作中出现问题应该怎么做,然后就是介绍公司业务和发展。
**2.华为:**
**一面**,笔试回顾,个人情况特殊,笔试40分钟A了两个题便出去做oppo笔试,第三题没看,面试官看提交情况很好,只有3次提交,便放我一马,没问第三题,然后询问项目,细节记不大清,都是基本操作,最后做算法题,leetcode原题,打家劫舍,简单动态规划,分析一下算法复杂度。
**二面**,说一面面试官评价不错,直接跳过了项目介绍与询问,问中学时候参加信息学竞赛的经历以及中兴算法大赛,最后环节是算法题,消灭进程树,hash表加队列。
**三面**,项目介绍,什么是一份好的代码,了解操作系统么,做过哪些相关的工作,看过哪些相关的书籍。
**3.小米**:
**一面**,询问项目细节,RTOS与linux的区别,如果让你写一个RTOS你应该写哪些功能,哪些是必须的,会用到哪些重要的数据结构,指针熟悉么,和C++中的引用的区别,什么时候用二级指针,C++中动态数组vector是怎么实现的,C语言中的设计模式了解么,最后做了一个简单的题,找出区间内乘积最大的两个素数。
**二面**,基本是项目,没啥印象了,然后问拿了哪些offer。
**4.远景**:
**一面**,项目细节,三次握手以及四次挥手,超时重传算法,如何给一个超大文件进行排序,hash分桶;
**二面**,跟大疆三面差不多;
**三面**,跟hr聊天;
**终面**,会什么,能做什么,然后就是岗位介绍画饼。
## 总结 时间过了太久,只有大疆印象深刻,其他基本忘得差不多,网易雷火游戏测试那部分虽然5面,刷人较多,但是看完牛客上的面经应该问题不大,唯一有点难度的是总监面时的算法题,当时做的一个dfs,比较复杂,分4种情况。中兴和中车感觉只要是个985应该问题不大,中兴一面讲了一下epoll的实现面试官眼睛都亮了,强行给我加上了南京的软件岗,中车同上,背景相关即可。 后台面试虽然准备了很多,但是由于基本找的都是C相关的底层岗位,基本没怎么问,redis和ngix基本没问,数据库相关的问题基本没碰到,可能第一目标岗位面试比较顺利便没怎么投C++后台相关的岗位开发,简历上基本没写C++后台相关的项目。
**以上**,重点还是代码基础,也就是数据结构和算法,和项目结合的代码的逻辑实现,CS基础知识个人认为自己用的少的把面经看完即可,把自己做的项目细节融汇贯通,能抗住连环5问即可,答不上来避免强答,然后整理思路理清条理,平时多思考为什么怎么做有什么效果,然后干净一点吐词清晰即可,给自己一个好的面试体验以及给面试官一个好的面试体验,回答的时候尽量看着面试官(虽然有时候面试官在敲代码),最后,网易的小姐姐很漂亮。 ================================================ FILE: README.md ================================================ ## 2021年最新总结,腾讯、阿里、美团、百度、字节跳动、京东等技术面试题,以及答案,专家出题人分析汇总。持续更新中。 ## 整理那么辛苦,求个star,谢谢!!! * [阿里篇](#1) * [华为篇](#2) * [百度篇](#3) * [腾讯篇](#4) * [美团篇](#5) * [字节跳动篇](#6) * [滴滴篇](#7) * [京东篇](#8) * [MySQL篇](#9) * [Redis篇](#10) * [MongoDB篇](#11) * [Zookeeper篇](#12) * [Nginx篇](#13) * [算法篇](#14) * [内存篇](#15) * [cpu篇](#16) * [磁盘篇](#17) * [网络通信篇](#18) * [安全篇](#19) * [并发篇](#20)

阿里篇

--- ##### [1.1.1 如何实现一个高效的单向链表逆序输出?](01.阿里篇/1.1.1%20%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E9%AB%98%E6%95%88%E7%9A%84%E5%8D%95%E5%90%91%E9%93%BE%E8%A1%A8%E9%80%86%E5%BA%8F%E8%BE%93%E5%87%BA%EF%BC%9F.md) ##### [1.1.2 已知sqrt(2)约等于1.414,要求不用数学库,求sqrt(2)精确到小数点后10位](01.阿里篇/1.1.2%20%E5%B7%B2%E7%9F%A5sqrt%282%29%E7%BA%A6%E7%AD%89%E4%BA%8E1.414%EF%BC%8C%E8%A6%81%E6%B1%82%E4%B8%8D%E7%94%A8%E6%95%B0%E5%AD%A6%E5%BA%93%EF%BC%8C%E6%B1%82sqrt%282%29%E7%B2%BE%E7%A1%AE%E5%88%B0%E5%B0%8F%E6%95%B0%E7%82%B9%E5%90%8E10%E4%BD%8D.md) ##### [1.1.3 给定一个二叉搜索树(BST),找到树中第 K 小的节点](01.阿里篇/1.1.3%20%E7%BB%99%E5%AE%9A%E4%B8%80%E4%B8%AA%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%28BST%29%EF%BC%8C%E6%89%BE%E5%88%B0%E6%A0%91%E4%B8%AD%E7%AC%AC%20K%20%E5%B0%8F%E7%9A%84%E8%8A%82%E7%82%B9.md) ##### [1.1.4 LRU缓存机制](01.阿里篇/1.1.4%20LRU%E7%BC%93%E5%AD%98%E6%9C%BA%E5%88%B6.md) ##### [1.1.5 关于epoll和select的区别,以下哪些说法是正确的](01.阿里篇/1.1.5%20%E5%85%B3%E4%BA%8Eepoll%E5%92%8Cselect%E7%9A%84%E5%8C%BA%E5%88%AB%EF%BC%8C%E4%BB%A5%E4%B8%8B%E5%93%AA%E4%BA%9B%E8%AF%B4%E6%B3%95%E6%98%AF%E6%AD%A3%E7%A1%AE%E7%9A%84.md) ##### [1.1.6 从innodb的索引结构分析,为什么索引的 key 长度不能太长](01.阿里篇/1.1.6%20%E4%BB%8Einnodb%E7%9A%84%E7%B4%A2%E5%BC%95%E7%BB%93%E6%9E%84%E5%88%86%E6%9E%90%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%E7%B4%A2%E5%BC%95%E7%9A%84%20key%20%E9%95%BF%E5%BA%A6%E4%B8%8D%E8%83%BD%E5%A4%AA%E9%95%BF.md) ##### [1.1.7 MySQL的数据如何恢复到任意时间点?](01.阿里篇/1.1.7%20MySQL%E7%9A%84%E6%95%B0%E6%8D%AE%E5%A6%82%E4%BD%95%E6%81%A2%E5%A4%8D%E5%88%B0%E4%BB%BB%E6%84%8F%E6%97%B6%E9%97%B4%E7%82%B9%EF%BC%9F.md) ##### 1.1.8 NFS 和 SMB 是最常见的两种 NAS(Network Attached Storage)协议,当把一个文件系统同时通过 NFS 和 SMB 协议共享给多个主机访问时,以下哪些说法是错误的 ##### [1.1.9 输入 ping IP 后敲回车,发包前会发生什么?](01.阿里篇/1.1.9%20%E8%BE%93%E5%85%A5%20ping%20IP%20%E5%90%8E%E6%95%B2%E5%9B%9E%E8%BD%A6%EF%BC%8C%E5%8F%91%E5%8C%85%E5%89%8D%E4%BC%9A%E5%8F%91%E7%94%9F%E4%BB%80%E4%B9%88%EF%BC%9F.md) ##### [1.2.0 请解释下为什么鹿晗发布恋情的时候,微博系统会崩溃,如何解决?](01.阿里篇/1.2.0%20%E8%AF%B7%E8%A7%A3%E9%87%8A%E4%B8%8B%E4%B8%BA%E4%BB%80%E4%B9%88%E9%B9%BF%E6%99%97%E5%8F%91%E5%B8%83%E6%81%8B%E6%83%85%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E5%BE%AE%E5%8D%9A%E7%B3%BB%E7%BB%9F%E4%BC%9A%E5%B4%A9%E6%BA%83%EF%BC%8C%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%EF%BC%9F.md) ##### [1.2.1 现有一批邮件需要发送给订阅顾客,且有一个集群(集群的节点数不定,会动态扩容缩容)来负责具体的邮件发送任务,如何让系统尽快地完成发送?](01.阿里篇/1.2.1%20%E7%8E%B0%E6%9C%89%E4%B8%80%E6%89%B9%E9%82%AE%E4%BB%B6%E9%9C%80%E8%A6%81%E5%8F%91%E9%80%81%E7%BB%99%E8%AE%A2%E9%98%85%E9%A1%BE%E5%AE%A2%EF%BC%8C%E4%B8%94%E6%9C%89%E4%B8%80%E4%B8%AA%E9%9B%86%E7%BE%A4%EF%BC%88%E9%9B%86%E7%BE%A4%E7%9A%84%E8%8A%82%E7%82%B9%E6%95%B0%E4%B8%8D%E5%AE%9A%EF%BC%8C%E4%BC%9A%E5%8A%A8%E6%80%81%E6%89%A9%E5%AE%B9%E7%BC%A9%E5%AE%B9%EF%BC%89%E6%9D%A5%E8%B4%9F%E8%B4%A3%E5%85%B7%E4%BD%93%E7%9A%84%E9%82%AE%E4%BB%B6%E5%8F%91%E9%80%81%E4%BB%BB%E5%8A%A1%EF%BC%8C%E5%A6%82%E4%BD%95%E8%AE%A9%E7%B3%BB%E7%BB%9F%E5%B0%BD%E5%BF%AB%E5%9C%B0%E5%AE%8C%E6%88%90%E5%8F%91%E9%80%81%EF%BC%9F.md) ##### [1.2.2 有一批气象观测站,现需要获取这些站点的观测数据,并存储到 Hive 中。但是气象局只提供了 api 查询,每次只能查询单个观测点。那么如果能够方便快速地获取到所有的观测点的数据?](01.阿里篇/1.2.2%20%E6%9C%89%E4%B8%80%E6%89%B9%E6%B0%94%E8%B1%A1%E8%A7%82%E6%B5%8B%E7%AB%99%EF%BC%8C%E7%8E%B0%E9%9C%80%E8%A6%81%E8%8E%B7%E5%8F%96%E8%BF%99%E4%BA%9B%E7%AB%99%E7%82%B9%E7%9A%84%E8%A7%82%E6%B5%8B%E6%95%B0%E6%8D%AE%EF%BC%8C%E5%B9%B6%E5%AD%98%E5%82%A8%E5%88%B0%20Hive%20%E4%B8%AD%E3%80%82%E4%BD%86%E6%98%AF%E6%B0%94%E8%B1%A1%E5%B1%80%E5%8F%AA%E6%8F%90%E4%BE%9B%E4%BA%86%20api%20%E6%9F%A5%E8%AF%A2%EF%BC%8C%E6%AF%8F%E6%AC%A1%E5%8F%AA%E8%83%BD%E6%9F%A5%E8%AF%A2%E5%8D%95%E4%B8%AA%E8%A7%82%E6%B5%8B%E7%82%B9%E3%80%82%E9%82%A3%E4%B9%88%E5%A6%82%E6%9E%9C%E8%83%BD%E5%A4%9F%E6%96%B9%E4%BE%BF%E5%BF%AB%E9%80%9F%E5%9C%B0%E8%8E%B7%E5%8F%96%E5%88%B0%E6%89%80%E6%9C%89%E7%9A%84%E8%A7%82%E6%B5%8B%E7%82%B9%E7%9A%84%E6%95%B0%E6%8D%AE%EF%BC%9F.md) ##### [1.2.3 如何实现两金额数据相加(最多小数点两位)](01.阿里篇/1.2.3%20%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E4%B8%A4%E9%87%91%E9%A2%9D%E6%95%B0%E6%8D%AE%E7%9B%B8%E5%8A%A0%EF%BC%88%E6%9C%80%E5%A4%9A%E5%B0%8F%E6%95%B0%E7%82%B9%E4%B8%A4%E4%BD%8D%EF%BC%89.md) ##### [1.2.4 关于并行计算的一些基础开放问题](01.阿里篇/1.2.4%20%E5%85%B3%E4%BA%8E%E5%B9%B6%E8%A1%8C%E8%AE%A1%E7%AE%97%E7%9A%84%E4%B8%80%E4%BA%9B%E5%9F%BA%E7%A1%80%E5%BC%80%E6%94%BE%E9%97%AE%E9%A2%98.md) ##### [1.2.5 请计算XILINX公司VU9P芯片的算力相当于多少TOPS,给出计算过程与公式](01.阿里篇/1.2.5%20%E8%AF%B7%E8%AE%A1%E7%AE%97XILINX%E5%85%AC%E5%8F%B8VU9P%E8%8A%AF%E7%89%87%E7%9A%84%E7%AE%97%E5%8A%9B%E7%9B%B8%E5%BD%93%E4%BA%8E%E5%A4%9A%E5%B0%91TOPS%EF%BC%8C%E7%BB%99%E5%87%BA%E8%AE%A1%E7%AE%97%E8%BF%87%E7%A8%8B%E4%B8%8E%E5%85%AC%E5%BC%8F.md) ##### [1.2.6 一颗现代处理器,每秒大概可以执行多少条简单的MOV指令,有哪些主要的影响因素](01.阿里篇/1.2.6%20%E4%B8%80%E9%A2%97%E7%8E%B0%E4%BB%A3%E5%A4%84%E7%90%86%E5%99%A8%EF%BC%8C%E6%AF%8F%E7%A7%92%E5%A4%A7%E6%A6%82%E5%8F%AF%E4%BB%A5%E6%89%A7%E8%A1%8C%E5%A4%9A%E5%B0%91%E6%9D%A1%E7%AE%80%E5%8D%95%E7%9A%84MOV%E6%8C%87%E4%BB%A4%EF%BC%8C%E6%9C%89%E5%93%AA%E4%BA%9B%E4%B8%BB%E8%A6%81%E7%9A%84%E5%BD%B1%E5%93%8D%E5%9B%A0%E7%B4%A0.md) ##### [1.2.7 请分析 MaxCompute 产品与分布式技术的关系、当前大数据计算平台类产品的市场现状和发展趋势](01.阿里篇/1.2.7%20%E8%AF%B7%E5%88%86%E6%9E%90%20MaxCompute%20%E4%BA%A7%E5%93%81%E4%B8%8E%E5%88%86%E5%B8%83%E5%BC%8F%E6%8A%80%E6%9C%AF%E7%9A%84%E5%85%B3%E7%B3%BB%E3%80%81%E5%BD%93%E5%89%8D%E5%A4%A7%E6%95%B0%E6%8D%AE%E8%AE%A1%E7%AE%97%E5%B9%B3%E5%8F%B0%E7%B1%BB%E4%BA%A7%E5%93%81%E7%9A%84%E5%B8%82%E5%9C%BA%E7%8E%B0%E7%8A%B6%E5%92%8C%E5%8F%91%E5%B1%95%E8%B6%8B%E5%8A%BF.md) ##### [1.2.8 对大数据平台中的元数据管理是怎么理解的,元数据收集管理体系是怎么样的,会对大数据应用有什么样的影响](01.阿里篇/1.2.8%20%E5%AF%B9%E5%A4%A7%E6%95%B0%E6%8D%AE%E5%B9%B3%E5%8F%B0%E4%B8%AD%E7%9A%84%E5%85%83%E6%95%B0%E6%8D%AE%E7%AE%A1%E7%90%86%E6%98%AF%E6%80%8E%E4%B9%88%E7%90%86%E8%A7%A3%E7%9A%84%EF%BC%8C%E5%85%83%E6%95%B0%E6%8D%AE%E6%94%B6%E9%9B%86%E7%AE%A1%E7%90%86%E4%BD%93%E7%B3%BB%E6%98%AF%E6%80%8E%E4%B9%88%E6%A0%B7%E7%9A%84%EF%BC%8C%E4%BC%9A%E5%AF%B9%E5%A4%A7%E6%95%B0%E6%8D%AE%E5%BA%94%E7%94%A8%E6%9C%89%E4%BB%80%E4%B9%88%E6%A0%B7%E7%9A%84%E5%BD%B1%E5%93%8D.md) ##### [1.2.9 你理解常见如阿里,和友商大数据平台的技术体系差异以及发展趋势和技术瓶颈,在存储和计算两个方面进行概述](01.阿里篇/1.2.9%20%E4%BD%A0%E7%90%86%E8%A7%A3%E5%B8%B8%E8%A7%81%E5%A6%82%E9%98%BF%E9%87%8C%EF%BC%8C%E5%92%8C%E5%8F%8B%E5%95%86%E5%A4%A7%E6%95%B0%E6%8D%AE%E5%B9%B3%E5%8F%B0%E7%9A%84%E6%8A%80%E6%9C%AF%E4%BD%93%E7%B3%BB%E5%B7%AE%E5%BC%82%E4%BB%A5%E5%8F%8A%E5%8F%91%E5%B1%95%E8%B6%8B%E5%8A%BF%E5%92%8C%E6%8A%80%E6%9C%AF%E7%93%B6%E9%A2%88%EF%BC%8C%E5%9C%A8%E5%AD%98%E5%82%A8%E5%92%8C%E8%AE%A1%E7%AE%97%E4%B8%A4%E4%B8%AA%E6%96%B9%E9%9D%A2%E8%BF%9B%E8%A1%8C%E6%A6%82%E8%BF%B0.md) ##### 1.3.0 在云计算大数据处理场景中,每天运行着成千上万的任务,每个任务都要进行 IO 读写。存储系统为了更好的服务,经常会保证高优先级的任务优先执行。当多个作业或用户访问存储系统时,如何保证优先级和公平性 ##### [1.3.1 最大频率栈](01.阿里篇/1.3.1%20%E6%9C%80%E5%A4%A7%E9%A2%91%E7%8E%87%E6%A0%88.md) ##### [1.3.2 给定一个链表,删除链表的倒数第N个节点,并且返回链表的头结点](01.阿里篇/1.3.2%20%E7%BB%99%E5%AE%9A%E4%B8%80%E4%B8%AA%E9%93%BE%E8%A1%A8%EF%BC%8C%E5%88%A0%E9%99%A4%E9%93%BE%E8%A1%A8%E7%9A%84%E5%80%92%E6%95%B0%E7%AC%ACN%E4%B8%AA%E8%8A%82%E7%82%B9%EF%BC%8C%E5%B9%B6%E4%B8%94%E8%BF%94%E5%9B%9E%E9%93%BE%E8%A1%A8%E7%9A%84%E5%A4%B4%E7%BB%93%E7%82%B9.md) ##### [1.3.3 如果让你设计一个通用的、支持各种数据库秒级备份和恢复的系统,你会如何设计](01.阿里篇/1.3.3%20%E5%A6%82%E6%9E%9C%E8%AE%A9%E4%BD%A0%E8%AE%BE%E8%AE%A1%E4%B8%80%E4%B8%AA%E9%80%9A%E7%94%A8%E7%9A%84%E3%80%81%E6%94%AF%E6%8C%81%E5%90%84%E7%A7%8D%E6%95%B0%E6%8D%AE%E5%BA%93%E7%A7%92%E7%BA%A7%E5%A4%87%E4%BB%BD%E5%92%8C%E6%81%A2%E5%A4%8D%E7%9A%84%E7%B3%BB%E7%BB%9F%EF%BC%8C%E4%BD%A0%E4%BC%9A%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1.md) ##### [1.3.4 如果让你来设计一个支持数据库、NOSQL 和大数据之间数据实时流动的数据流及处理的系统,你会考虑哪些问题?如何设计?](01.阿里篇/1.3.4%20%E5%A6%82%E6%9E%9C%E8%AE%A9%E4%BD%A0%E6%9D%A5%E8%AE%BE%E8%AE%A1%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E6%95%B0%E6%8D%AE%E5%BA%93%E3%80%81NOSQL%20%E5%92%8C%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E9%97%B4%E6%95%B0%E6%8D%AE%E5%AE%9E%E6%97%B6%E6%B5%81%E5%8A%A8%E7%9A%84%E6%95%B0%E6%8D%AE%E6%B5%81%E5%8F%8A%E5%A4%84%E7%90%86%E7%9A%84%E7%B3%BB%E7%BB%9F%EF%BC%8C%E4%BD%A0%E4%BC%9A%E8%80%83%E8%99%91%E5%93%AA%E4%BA%9B%E9%97%AE%E9%A2%98%EF%BC%9F%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%EF%BC%9F.md) ##### [1.3.5 给定一个整数数组和一个整数,返回两个数组的索引,这两个索引指向的数字的加和等于指定的整数。需要最优的算法,分析算法的空间和时间复杂度](01.阿里篇/1.3.5%20%E7%BB%99%E5%AE%9A%E4%B8%80%E4%B8%AA%E6%95%B4%E6%95%B0%E6%95%B0%E7%BB%84%E5%92%8C%E4%B8%80%E4%B8%AA%E6%95%B4%E6%95%B0%EF%BC%8C%E8%BF%94%E5%9B%9E%E4%B8%A4%E4%B8%AA%E6%95%B0%E7%BB%84%E7%9A%84%E7%B4%A2%E5%BC%95%EF%BC%8C%E8%BF%99%E4%B8%A4%E4%B8%AA%E7%B4%A2%E5%BC%95%E6%8C%87%E5%90%91%E7%9A%84%E6%95%B0%E5%AD%97%E7%9A%84%E5%8A%A0%E5%92%8C%E7%AD%89%E4%BA%8E%E6%8C%87%E5%AE%9A%E7%9A%84%E6%95%B4%E6%95%B0%E3%80%82%E9%9C%80%E8%A6%81%E6%9C%80%E4%BC%98%E7%9A%84%E7%AE%97%E6%B3%95%EF%BC%8C%E5%88%86%E6%9E%90%E7%AE%97%E6%B3%95%E7%9A%84%E7%A9%BA%E9%97%B4%E5%92%8C%E6%97%B6%E9%97%B4%E5%A4%8D%E6%9D%82%E5%BA%A6.md) ##### [1.3.6 假如给你一个新产品,你将从哪些方面来保障它的质量?](01.阿里篇/1.3.6%20%E5%81%87%E5%A6%82%E7%BB%99%E4%BD%A0%E4%B8%80%E4%B8%AA%E6%96%B0%E4%BA%A7%E5%93%81%EF%BC%8C%E4%BD%A0%E5%B0%86%E4%BB%8E%E5%93%AA%E4%BA%9B%E6%96%B9%E9%9D%A2%E6%9D%A5%E4%BF%9D%E9%9A%9C%E5%AE%83%E7%9A%84%E8%B4%A8%E9%87%8F%EF%BC%9F.md) ##### [1.3.7 请评估一下程序的执行结果?](01.阿里篇/1.3.7%20%E8%AF%B7%E8%AF%84%E4%BC%B0%E4%B8%80%E4%B8%8B%E7%A8%8B%E5%BA%8F%E7%9A%84%E6%89%A7%E8%A1%8C%E7%BB%93%E6%9E%9C%EF%BC%9F.md)

华为篇

--- ##### 2.1.0 static有什么用途?(请至少说明两种) ###### 2.1.1 引用与指针有什么区别? ##### 2.1.2 描述实时系统的基本特性 ##### 2.1.3 全局变量和局部变量在内存中是否有区别?如果有,是什么区别? ##### 2.1.4 什么是平衡二叉树? ##### 2.1.5 堆栈溢出一般是由什么原因导致的? ##### 2.1.6 什么函数不能声明为虚函数? ##### 2.1.7 冒泡排序算法的时间复杂度是什么? ##### 2.1.8 写出float x 与“零值”比较的if语句 ##### 2.1.9 Internet采用哪种网络协议?该协议的主要层次结构? ##### 2.2.0 Internet物理地址和IP地址转换采用什么协议? ##### 2.2.1 IP地址的编码分为哪俩部分? ##### 2.2.2 用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。 ##### 2.2.3 不能做switch()的参数类型是 ##### 2.2.4 int A[nSize],其中隐藏着若干0,其余非0整数,写一个函数int Func(int* A, int nSize),使A把0移至后面,非0整数移至数组前面并保持有序,返回值为原数据中第一个元素为0的下标。 ##### 2.2.5 写一个程序, 要求功能:求出用1,2,5这三个数不同个数组合的和为100的组合个数 ##### 2.2.6 实现一个函数,把一个字符串中的字符从小写转为大写 ##### 2.2.7 随机输入一个数,判断它是不是对称数(回文数)(如3,121,12321,45254)。不能用字符串库函数 ##### 2.2.8 求2~2000的所有素数.有足够的内存,要求尽量快 ##### 2.2.9 A,B,C,D四个进程,A向buf里面写数据,B,C,D向buf里面读数据,当A写完,且B,C,D都读一次后,A才能再写。用P,V操作实现。 ##### 2.3.0 将单向链表reverse,如ABCD变成DCBA,只能搜索链表一次。 ##### 2.3.1 将二叉树的两个孩子换位置,即左变右,右变左。不能用递规。 ##### 2.3.2 以下属于物理层的设备是? ##### 2.3.3 在以太网中,是根据()地址来区分不同的设备的? ##### 2.3.4 以下为传输层协议的是? ##### 2.3.5 以下对MAC地址描述正确的是? ##### 2.3.6 以下属于数据链路层功能的是? ##### 2.3.7 IEEE802.3u标准是指? ##### 2.3.8 如果要将两计算机通过双绞线直接连接,正确的线序是? ##### 2.3.9 在V.35和V.24规程中,控制信号RTS表示? ##### 2.4.0 路由器作为网络互连设备,必须具备以下哪些特点? ##### 2.4.1 路由器的作用有? ##### 2.4.2 调用上一条历史命令的快捷键是? ##### 2.4.3 交换机工作在OSI七层的哪一层? ##### 2.4.4 以下对CSMA/CD描述正确的是? ##### 2.4.5 以下对STORE ANDFORWARD描述正确的是? ##### 2.4.6 以下对交换机工作方式描述正确的是? ##### 2.4.7 VLAN的主要作用有? ##### 2.4.8 在交换机中用户权限分为几个级别? ##### 2.4.9 在路由器的配置过程中查询以S开头所有命令的方法是? ##### 2.5.0 第一次配置路由器时可以使用的方法为? ##### 2.5.1 在何种状态下可以为路由器改名? ##### 2.5.2 某公司申请到一个C类IP地址,但要连接6个的子公司,最大的一个子公司有 26台计算机,每个子公司在一个网段中,则子网掩码应设为? ##### 2.5.3 与10.110.12.29mask 255.255.255.224属于同一网段的主机IP地址是? ##### 2.5.4 ARP协议的作用是? ##### 2.5.5 当路由器接收的IP报文的TTL值等于1时,采取的策略是? ##### 2.5.6 在NetWare 网络中,客户需要访问某个类型的服务器时,首先要发送一个 ()广播报文来寻找服务器? ##### 2.5.7 IPX地址网络地址有( )个字节? ##### 2.5.8 对于帧中继描述正确的是? ##### 2.5.9 对于INVERSE ARP的描述正确的是?

百度篇

--- ##### 3.1.0 在函数内定义一个字符数组,用gets函数输入字符串的时候,如果输入越界,为什么程序会崩溃? ##### 3.1.1 C++中引用与指针的区别 ##### 3.1.2 C/C++程序的内存分区 ##### 3.1.3 快速排序的思想、时间复杂度、实现以及优化方法 ##### 3.1.4 IO模型——IO多路复用机制? ##### 3.1.5 常用的Linux命令 ##### 3.1.6 C中变量的存储类型有哪些? ##### 3.1.7 动态规划的本质 ##### 3.1.8 实践中如何优化MySQL? ##### 3.1.9 什么情况下设置了索引但无法使用? ##### 3.2.0 SQL语句的优化 ##### 3.2.1 数据库索引的底层实现原理和优化 ##### 3.2.2 HTTP和HTTPS的主要区别? ##### 3.2.3 如何设计一个高并发的系统? ##### 3.2.4 两条相交的单向链表,如何求他们的第一个公共节点? ##### 3.2.5 求单向局部循环链表的环入口? ##### 3.2.6 IP地址如何在数据库中存储? ##### 3.2.7 new/delete和malloc/free的底层实现? ##### 3.2.8 overload、override、overwrite的介绍? ##### 3.2.9 小端/大端机器? ##### 3.3.0 守护进程 ##### 3.3.1 多线程的优缺点 ##### 3.3.2 长连接与短连接 ##### 3.3.3 二分图应用于最佳匹配问题(游客对房间的满意度之和最大问题) ##### 3.3.4 class与struct的区别? ##### 3.3.5 虚函数和纯虚函数 ##### 3.3.6 menset()函数 ##### 3.3.7 实现一个函数,对一个正整数n,算得到1需要的最少操作次数。操作规则为:如果n为偶数,将其除以2;如果n为奇数,可以加1或减1;一直处理下去。 ##### 3.3.8 找到满足条件的数组 ##### 3.3.9 一个大的含有50M个URL的记录,一个小的含有500个URL的记录,找出两个记录里相同的URL ##### 3.4.0 海量日志数据,提取出某日访问百度次数最多的那个IP ##### 3.4.1 有10个文件,每个文件1G,每个文件的每一行都存放的是用户的query,每个文件的query都可能重复。如何按照query的频度排序? ##### 3.4.2 蚂蚁爬杆问题 ##### 3.4.3 当在浏览器中输入一个url后回车,后台发生了什么?比如输入url后,你看到了百度的首页,那么这一切是如何发生的呢? ##### 3.4.4 判断两棵树是否相等,请实现两棵树是否相等的比较,相等返回1,否则返回其他值,并说明算法复杂度 ##### 3.4.5 三个警察和三个囚徒的过河问题 ##### 3.4.6 从300万字符串中找到最热门的10条 ##### 3.4.7 如何找出字典中的兄弟单词。给定一个单词a,如果通过交换单词中字母的顺序可以得到另外的单词b,那么定义b是a的兄弟单词。现在给定一个字典,用户输入一个单词,如何根据字典找出这个单词有多少个兄弟单词? ##### 3.4.8 找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数。 ##### 3.4.9 找出被修改过的数字 ##### 3.5.0 设计DNS服务器中cache的数据结构。要求设计一个DNS的Cache结构,要求能够满足每秒5000以上的查询,满足IP数据的快速插入,查询的速度要快。(题目还给出了一系列的数据,比如:站点数总共为5000万,IP地址有1000万,等等) ##### 3.5.1 找出给定字符串对应的序号 ##### 3.5.2 找出第k大的数字所在的位置。写一段程序,找出数组中第k大小的数,输出数所在的位置。例如{2,4,3,4,7}中,第一大的数是7,位置在4。第二大、第三大的数都是4,位置在1、3随便输出哪一个均可。 ##### 3.5.3 给40亿个不重复的unsigned int的整数,没排过序的,然后再给几个数,如何快速判断这几个数是否在那40亿个数当中? ##### 3.5.4 在一个文件中有10G个整数,乱序排列,要求找出中位数。内存限制为2G。 ##### 3.5.5 时分秒针在一天之类重合多少次?(24小时) ##### 3.5.6 将多个集合合并成没有交集的集合。 ##### 3.5.7 平面内有11个点,由它们连成48条不同的直线,由这些点可连成多少个三角形?

腾讯篇

--- #### Java基础 ##### [4.1.0 JAVA中的几种基本数据类型是什么,各自占用多少字节。](04.腾讯篇/4.1.0%20JAVA%E4%B8%AD%E7%9A%84%E5%87%A0%E7%A7%8D%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%8C%E5%90%84%E8%87%AA%E5%8D%A0%E7%94%A8%E5%A4%9A%E5%B0%91%E5%AD%97%E8%8A%82.md) ##### [4.1.1 String类能被继承吗,为什么。](04.腾讯篇/4.1.1%20String%E7%B1%BB%E8%83%BD%E8%A2%AB%E7%BB%A7%E6%89%BF%E5%90%97%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88.md) ##### [4.1.2 String,Stringbuffer,StringBuilder的区别。](04.腾讯篇/4.1.2%20String%EF%BC%8CStringbuffer%EF%BC%8CStringBuilder%E7%9A%84%E5%8C%BA%E5%88%AB.md) ##### [4.1.3 ArrayList和LinkedList有什么区别。](04.腾讯篇/4.1.3%20ArrayList%E5%92%8CLinkedList%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB.md) ##### [4.1.4 讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,当new的时候,他们的执行顺序。](04.腾讯篇/4.1.4%20%E8%AE%B2%E8%AE%B2%E7%B1%BB%E7%9A%84%E5%AE%9E%E4%BE%8B%E5%8C%96%E9%A1%BA%E5%BA%8F%EF%BC%8C%E6%AF%94%E5%A6%82%E7%88%B6%E7%B1%BB%E9%9D%99%E6%80%81%E6%95%B0%E6%8D%AE%EF%BC%8C%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%EF%BC%8C%E5%AD%97%E6%AE%B5%EF%BC%8C%E5%AD%90%E7%B1%BB%E9%9D%99%E6%80%81%E6%95%B0%E6%8D%AE%EF%BC%8C%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%EF%BC%8C%E5%AD%97%E6%AE%B5%EF%BC%8C%E5%BD%93new%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E4%BB%96%E4%BB%AC%E7%9A%84%E6%89%A7%E8%A1%8C%E9%A1%BA%E5%BA%8F.md) ##### [4.1.5 用过哪些Map类,都有什么区别,HashMap是线程安全的吗,并发下使用的Map是什么,他们内部原理分别是什么,比如存储方式,hashcode,扩容,默认容量等。](04.腾讯篇/4.1.5%20%E7%94%A8%E8%BF%87%E5%93%AA%E4%BA%9BMap%E7%B1%BB%EF%BC%8C%E9%83%BD%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%8CHashMap%E6%98%AF%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%E7%9A%84%E5%90%97,%E5%B9%B6%E5%8F%91%E4%B8%8B%E4%BD%BF%E7%94%A8%E7%9A%84Map%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%8C%E4%BB%96%E4%BB%AC%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86%E5%88%86%E5%88%AB%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%8C%E6%AF%94%E5%A6%82%E5%AD%98%E5%82%A8%E6%96%B9%E5%BC%8F%EF%BC%8Chashcode%EF%BC%8C%E6%89%A9%E5%AE%B9%EF%BC%8C%E9%BB%98%E8%AE%A4%E5%AE%B9%E9%87%8F%E7%AD%89.md) ##### [4.1.6 JAVA8的ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何设计。](04.腾讯篇/4.1.6%20JAVA8%E7%9A%84ConcurrentHashMap%E4%B8%BA%E4%BB%80%E4%B9%88%E6%94%BE%E5%BC%83%E4%BA%86%E5%88%86%E6%AE%B5%E9%94%81%EF%BC%8C%E6%9C%89%E4%BB%80%E4%B9%88%E9%97%AE%E9%A2%98%E5%90%97%EF%BC%8C%E5%A6%82%E6%9E%9C%E4%BD%A0%E6%9D%A5%E8%AE%BE%E8%AE%A1%EF%BC%8C%E4%BD%A0%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1.md) ##### [4.1.7 有没有有顺序的Map实现类,如果有,他们是怎么保证有序的。](04.腾讯篇/4.1.7%E6%9C%89%E6%B2%A1%E6%9C%89%E6%9C%89%E9%A1%BA%E5%BA%8F%E7%9A%84Map%E5%AE%9E%E7%8E%B0%E7%B1%BB%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%9C%89%EF%BC%8C%E4%BB%96%E4%BB%AC%E6%98%AF%E6%80%8E%E4%B9%88%E4%BF%9D%E8%AF%81%E6%9C%89%E5%BA%8F%E7%9A%84.md) ##### [4.1.8 抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口么。](04.腾讯篇/4.1.8%E6%8A%BD%E8%B1%A1%E7%B1%BB%E5%92%8C%E6%8E%A5%E5%8F%A3%E7%9A%84%E5%8C%BA%E5%88%AB%EF%BC%8C%E7%B1%BB%E5%8F%AF%E4%BB%A5%E7%BB%A7%E6%89%BF%E5%A4%9A%E4%B8%AA%E7%B1%BB%E4%B9%88%EF%BC%8C%E6%8E%A5%E5%8F%A3%E5%8F%AF%E4%BB%A5%E7%BB%A7%E6%89%BF%E5%A4%9A%E4%B8%AA%E6%8E%A5%E5%8F%A3%E4%B9%88%2C%E7%B1%BB%E5%8F%AF%E4%BB%A5%E5%AE%9E%E7%8E%B0%E5%A4%9A%E4%B8%AA%E6%8E%A5%E5%8F%A3%E4%B9%88.md) ##### [4.1.9 继承和聚合的区别在哪。](04.腾讯篇/4.1.9%E7%BB%A7%E6%89%BF%E5%92%8C%E8%81%9A%E5%90%88%E7%9A%84%E5%8C%BA%E5%88%AB%E5%9C%A8%E5%93%AA.md) ##### [4.2.0 IO模型有哪些,讲讲你理解的nio ,他和bio,aio的区别是啥,谈谈reactor模型。](04.腾讯篇/4.2.0IO%E6%A8%A1%E5%9E%8B%E6%9C%89%E5%93%AA%E4%BA%9B%EF%BC%8C%E8%AE%B2%E8%AE%B2%E4%BD%A0%E7%90%86%E8%A7%A3%E7%9A%84nio%EF%BC%8C%E4%BB%96%E5%92%8Cbio%EF%BC%8Caio%E7%9A%84%E5%8C%BA%E5%88%AB%E6%98%AF%E5%95%A5%EF%BC%8C%E8%B0%88%E8%B0%88reactor%E6%A8%A1%E5%9E%8B.md) ##### [4.2.1 反射的原理,反射创建类实例的三种方式是什么。](04.腾讯篇/4.2.1%E5%8F%8D%E5%B0%84%E7%9A%84%E5%8E%9F%E7%90%86%EF%BC%8C%E5%8F%8D%E5%B0%84%E5%88%9B%E5%BB%BA%E7%B1%BB%E5%AE%9E%E4%BE%8B%E7%9A%84%E4%B8%89%E7%A7%8D%E6%96%B9%E5%BC%8F%E6%98%AF%E4%BB%80%E4%B9%88.md) ##### [4.2.2 反射中,Class.forName和ClassLoader区别 。](04.腾讯篇/4.2.2%E5%8F%8D%E5%B0%84%E4%B8%AD%EF%BC%8CClass.forName%E5%92%8CClassLoader%E5%8C%BA%E5%88%AB.md) ##### [4.2.3 描述动态代理的几种实现方式,分别说出相应的优缺点。](04.腾讯篇/4.2.3%E6%8F%8F%E8%BF%B0%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E7%9A%84%E5%87%A0%E7%A7%8D%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F%EF%BC%8C%E5%88%86%E5%88%AB%E8%AF%B4%E5%87%BA%E7%9B%B8%E5%BA%94%E7%9A%84%E4%BC%98%E7%BC%BA%E7%82%B9.md) ##### 4.2.4 动态代理与cglib实现的区别。 ##### 4.2.5 为什么CGlib方式可以对接口实现代理。 ##### 4.2.6 final的用途。 ##### 4.2.7 写出三种单例模式实现 。 ##### 4.2.8 如何在父类中为子类自动完成所有的hashcode和equals实现?这么做有何优劣。 ##### 4.2.9 请结合OO设计理念,谈谈访问修饰符public、private、protected、default在应用设计中的作用。 ##### 4.3.0 深拷贝和浅拷贝区别。 ##### 4.3.1 数组和链表数据结构描述,各自的时间复杂度。 ##### 4.3.2 error和exception的区别,CheckedException,RuntimeException的区别。 ##### 4.3.3 请列出5个运行时异常。 ##### 4.3.4 在自己的代码中,如果创建一个java.lang.String类,这个类是否可以被类加载器加载?为什么。 ##### 4.3.5 说一说你对java.lang.Object对象中hashCode和equals方法的理解。在什么场景下需要重新实现这两个方法。 ##### 4.3.6 在jdk1.5中,引入了泛型,泛型的存在是用来解决什么问题。 ##### 4.3.7 这样的a.hashcode() 有什么用,与a.equals(b)有什么关系。 ##### 4.3.8 有没有可能2个不相等的对象有相同的hashcode。 ##### 4.3.9 Java中的HashSet内部是如何工作的。 ##### 4.4.0 什么是序列化,怎么序列化,为什么序列化,反序列化会遇到什么问题,如何解决。 ##### 4.4.1 java8的新特性。 #### JVM ##### 4.4.2 什么情况下会发生栈内存溢出。 ##### 4.4.3 JVM的内存结构,Eden和Survivor比例。 ##### 4.4.4 JVM内存为什么要分成新生代,老年代,持久代。新生代中为什么要分为Eden和Survivor。 ##### 4.4.5 JVM中一次完整的GC流程是怎样的,对象如何晋升到老年代,说说你知道的几种主要的JVM参数。 ##### 4.4.6 你知道哪几种垃圾收集器,各自的优缺点,重点讲下cms和G1,包括原理,流程,优缺点。 ##### 4.4.7 垃圾回收算法的实现原理。 ##### 4.4.8 当出现了内存溢出,你怎么排错。 ##### 4.4.9 JVM内存模型的相关知识了解多少,比如重排序,内存屏障,happen-before,主内存,工作内存等。 ##### 4.5.0 简单说说你了解的类加载器,可以打破双亲委派么,怎么打破。 ##### 4.5.1 讲讲JAVA的反射机制。 ##### 4.5.2 你们线上应用的JVM参数有哪些。 ##### 4.5.3 g1和cms区别,吞吐量优先和响应优先的垃圾收集器选择。 ##### 4.5.4 怎么打出线程栈信息。 #### 开源框架 ##### 4.5.5 简单讲讲tomcat结构,以及其类加载器流程,线程模型等。 ##### 4.5.6 tomcat如何调优,涉及哪些参数 。 ##### 4.5.7 讲讲Spring加载流程。 ##### 4.5.8 Spring AOP的实现原理。 ##### 4.5.9 讲讲Spring事务的传播属性。 ##### 4.6.0 Spring如何管理事务的。 ##### 4.6.1 Spring怎么配置事务(具体说出一些关键的xml 元素)。 ##### 4.6.2 说说你对Spring的理解,非单例注入的原理?它的生命周期?循环注入的原理,aop的实现原理,说说aop中的几个术语,它们是怎么相互工作的。 ##### 4.6.3 Springmvc 中DispatcherServlet初始化过程。 ##### 4.6.4 netty的线程模型,netty如何基于reactor模型上实现的。 ##### 4.6.5 为什么选择netty。 ##### 4.6.6 什么是TCP粘包,拆包。解决方式是什么。 ##### 4.6.7 netty的fashwheeltimer的用法,实现原理,是否出现过调用不够准时,怎么解决。 ##### 4.6.8 netty的心跳处理在弱网下怎么办。 ##### 4.6.9 netty的通讯协议是什么样的。 ##### 4.7.0 springmvc用到的注解,作用是什么,原理。 ##### 4.7.1 springboot启动机制。 #### 操作系统 ##### 4.7.2 Linux系统下你关注过哪些内核参数,说说你知道的。 ##### 4.7.3 Linux下IO模型有几种,各自的含义是什么。 ##### 4.7.4 epoll和poll有什么区别。 ##### 4.7.5 平时用到哪些Linux命令。 ##### 4.7.6 用一行命令查看文件的最后五行。 ##### 4.7.7 用一行命令输出正在运行的java进程。 ##### 4.7.8 介绍下你理解的操作系统中线程切换过程。 ##### 4.7.9 进程和线程的区别。 ##### 4.8.0 top 命令之后有哪些内容,有什么作用。 ##### 4.8.1 线上CPU爆高,请问你如何找到问题所在。

美团篇

--- ##### 5.1.0 java虚拟机内存模型 ##### 5.1.1 内存溢出一般发生在哪个区?永久代会不会导致内存溢出? ##### 5.1.2 动态加载类的框架了解哪些? ##### 5.1.3 动态代理一般有哪几种实现方式?动态代理的应用场景有哪些? ##### 5.1.4 栈会不会溢出?栈溢出一般抛什么异常?jvm在哪里设置栈的大小?设置的参数是什么? ##### 5.1.5 用过哪些命令查看jvm的状态、堆栈信息? ##### 5.1.6 jvm的垃圾回收机制? ##### 5.1.7 java类加载机制?如何实现自定义类加载器?findClass与loadClass的区别? ##### 5.1.8 String、StringBuffer、StringBuilder的区别?对应的使用场景? ##### 5.1.9 如何实现不可变的类? ##### 5.2.0 浅复制和深复制?怎样实现深复制? ##### 5.2.1 HashMap、HashTable、ConcurrentHashMap的区别? ##### 5.2.2 CAS是一种什么样的同步机制? ##### 5.2.3 NIO的原理,包括哪几个组件? ##### 5.2.4 简单介绍一下java的反射机制?反射在哪些地方有应用场景? ##### 5.2.5 spring加载bean的流程? ##### 5.2.6 java线程池?线程池构造函数的几个参数含义?keepAliveTime解释一下? ##### 5.2.7 一个接口,要去调用另外5个接口,每一个接口都会返回数据给这个调用接口,调用接口要对数据进行合并并返回给上层。这样一种场景可能用到并发包下的哪些类?你会怎么去实现这样的业务场景? ##### 5.2.8 CountDownLatch和CyclicBarrier的区别? ##### 5.2.9 线程加锁有哪些方式?synchronized和lock的区别? ##### 5.3.0 volatile关键字的作用?为什么使用AtomicLong而不使用Long?AtomicLong的底层是怎么实现的? ##### 5.3.1 mysql的存储引擎有哪几种? ##### 5.3.2 sql优化有哪些着手点?组合索引的最左前缀原则的含义? ##### 5.3.3 springmvc处理请求的流程? ##### 5.3.4 spring的事务怎么使用?事务回滚?自定义异常? ##### 5.3.5 脏读?幻读? ##### 5.3.6 tcp四次挥手的过程?TIME_WAIT为什么至少设置两倍的MSL时间? ##### 5.3.7 get和post请求的区别? ##### 5.3.8 cookie和session的请求? ##### 5.3.9 了解哪些开源的中间件?缓存?消息?分布式框架? ##### 5.4.0 用到过哪些设计模式?单例模式的实现? ##### 5.4.1 数据库的事务实现原理、操作过程、如何做到事物之间的独立性等问题 ##### 5.4.2 数据库的脏读,幻读,不可重复读出现的原因原理,解决办法 ##### 5.4.3 数据库的隔离级别、MVCC ##### 5.4.4 乐观锁、悲观锁、互斥锁、读写锁的原理实现与区别 ##### 5.4.5 线程的生命周期 ##### 5.4.6 一致性hash算法原理与应用 ##### 5.4.7 CAP原则 ##### 5.4.8 CAS操作 ##### 5.4.9 分布式raft算法

字节跳动篇

--- ##### 6.1.0 5个人去一个海岛寻宝,最后一共找到了100枚金币。他们约定了一个分配方案。 ##### 6.1.1 给你一个有序整数数组,数组中的数可以是正数、负数、零,请实现一个函数,这个函数返回一个整数:返回这个数组所有数的平方值中有多少种不同的取值。 ##### 6.1.2 一个环有10个节点,编号0-9。从0点出发,走N步又能回到0点,共有多少种走法? ##### 6.1.3 一个乱序数组,求第K大的数。排序方式使用字典序。 ##### 6.1.4 一棵二叉树,求最大通路长度。(即最大左右子树高度之和) ##### 6.1.5 进程和线程的区别,使用线程真的能节省时间? ##### 6.1.6 go协程的调度方式,使用协程真的能节省时间? ##### 6.1.7 水平触发边沿触发的区别?在边沿触发下,一个socket有500的数据,已读取200然后不再处理,是不是剩下的300就永远无法读取? ##### 6.1.8 有函数如下,输入1,返回什么? ##### 6.1.9 设计http协议,A端发送 AAAA,至少让B端知道AAAA已发送完成。 ##### 6.2.0 流量总入口为api_gateway,api_gateway挂了会导致全部挂挂,用什么机制增大可用性? ##### 6.2.1 mysql为什么要用b+树,不用平衡二叉树做索引结构? ##### 6.2.2 创建数据库索引应该怎么考虑? ##### 6.2.3 使用int 做primary key和使用string 有什么优劣? ##### 6.2.4 数据库分表的方法? ##### 6.2.5 表结构,订单纪录如下,写一个语句,求卖的最好的 top 10 product_id。 ##### 6.2.6 微服务,A服务请求B服务B1接口,B1接口又请求A服务A2接口。会不会有问题? ##### 6.2.7 不使用高级工具,只使用Linux自带的工具,你会如何debug? ##### 6.2.8 如何预估一个mysql语句的性能? ##### 6.2.9 go函数中,返回值未命名,发生了panic,但是在函数内recover了。函数返回什么值? ##### 6.3.0 socket中,在tcp协议层面,数据分为10个报文发放。1-7次很顺利,第8次丢失。这次通信一定失败吗?如果第8次数据会重发,那在接收端是不是:先读取到1-7次的数据,然后读取到8-10次的数据?还是9-10次的数据会先到达? ##### 6.3.1 free -h,buffers 和cached有什么不同 ##### 6.3.2 后台进程有什么特点,如果要你设计一个进程是后台进程,你会考虑什么 ##### 6.3.3 僵尸进程是什么,如果产生一个僵尸进程,如何查找僵尸进程 ##### 6.3.4 孤儿进程是什么 ##### 6.3.5 一个进程有20个线程,在某个线程中调用fork,新的进程会有20个线程吗? ##### 6.3.6 tcp/ip 流量控制和拥塞控制 ##### 6.3.7 301/302有什么区别?应用上有什么异同。 ##### 6.3.8 50X相关错误码的内涵是什么? ##### 6.3.9 close wait和time wait是什么?如何排查?有什么意义? ##### 6.4.0 http req和resp的中数据有哪些 ##### 6.4.1 什么是连接的半打开,半关闭状态 ##### 6.4.2 假如一个业务依赖单点redis,此redis故障将导致业务不可用,如何改进 ##### 6.4.3 redis sharding有哪些做法 ##### 6.4.4 当大量数据要求用redis保存,单机单点难以满足需要,设计(换寻找)一个负载均衡的方案 ##### 6.4.5 当redis 采用hash做sharding,现在有8个节点,负载方案是 pos = hash(key) % 8,然后保存在pos节点上。这样做有什么好处坏处?当8个节点要扩充到10个节点,应该怎么办?有什么更方便扩充的方案吗?(一致性hash, presharding) ##### 6.4.6 如何保证redis和数据库数据的一致性。比如用户名既保存在数据库,又保存在redis做缓存。有如下操作 update_db(username); update_redis(username)。但是执行update_db后故障,update_redis没有执行。有什么简单办法解决这个问题。 ##### 6.5.0 数据库表包含三列:广告编号ad_id,广告开始投放时间ad_start,广告投放结束时间ad_end。用一行SQL语句查询给定时间段内存在的广告。 ##### 6.5.1 讲讲MapReduce的原理。 ##### 6.5.2 举出几种进程通信、线程通信的方式。 ##### 6.5.3 对列表中每一个元素找出比它大的第一个元素:输入一个listin,返回一个listout。对于任意listin[x],将满足 y > x 且 listin[y] > listin[x] 的第一个 listin[y] 值作为 listout[x] 的值。时间复杂度限制为O(n)。

滴滴篇

--- ##### 7.1.0 B+树、B-树的区别? ##### 7.1.1 数据库隔离级别,幻读和不可重复读的区别? ##### 7.1.2 有hell, well, hello, world等字符串组,现在问能否拼接成helloworld,代码实现。 ##### 7.1.3 快排算法实现 ##### 7.1.4 线程安全的单例模式 ##### 7.1.5 25匹马赛跑,有一个赛场,只有五个赛道,没有计时器,只能通过目测来记录快慢,求出第三3快的马要多少场比赛? ##### 7.1.6 kmp算法next数组的求解思路 ##### 7.1.7 数组中有三个数字出现超过3/4,求这三个数字? ##### 7.1.8 1到n+2个数组中缺了两个数,如何用O(n)时间,O(1)空间找到这两个数字。 ##### 7.1.9 一条线段长为1,随机选两个点,将改线段分为三段,三段能成三角形的概率是多少? ##### 7.2.0 有一个教授,他三个学生,脑袋背后分别各写了一个数字,其中一个数字是另外两个数字的和,经过几轮后,有一个学生猜出了自己的数字请问是什么原因? ##### 7.2.1 B+树做索引时,B+树通常高度为多少层?要参考哪些条件?

京东篇

--- ##### 8.1.0 一般sql注入怎么发现触点的,从源码阐述sqlmap如何测试注入点的。 ##### 8.1.1 masscan扫描端口时靠什么检测,为什么这么快? 请详述. ##### 8.1.2 你写过哪些小工具,你为你使用过的工具做过什么修改. ##### 8.1.3 如何提高采用python编写的扫描速度,谈谈对GIL锁的了解. ##### 8.1.4 你觉得你发现的那个漏洞影响比较大. ##### 8.1.5 常见的web漏洞有哪些. ##### 8.1.6 有没有玩过硬件安全,研究程度如何. ##### 8.1.7 反爬虫,如果是你如何进行反爬虫,如何绕过反爬措施。 使用无头浏览器被检测到了,如何绕过 ##### 8.1.8 nmap扫描如何进行扫描。发包与协议,握手和不握手,哪些协议握手,哪些不握手. 如何不直接接触目标服务器探测对方端口是否开放 ##### 8.1.9 有没有自己编写过yara扫描模块,如果要解决扫描{k1:v1, k2:v2, k3:v3} ,保证同时在k1中的v1里出现特定值,k2中出现v2特定值,以及k3,v3。怎么实现 ##### 8.2.0 xss什么原理,如何自己实现一个beef类似的xss平台. 既然这样实现,面临的跨域如何解决? ##### 8.2.1 ip 频率限制, ip信誉度模型? ##### 8.2.2 SCTP协议是什么?如何使用 SCTP 优化网络?

mysql篇

--- ##### [9.1.0 主键 超键 候选键 外键](09.MySQL篇/9.1.0%20%E4%B8%BB%E9%94%AE%20%E8%B6%85%E9%94%AE%20%E5%80%99%E9%80%89%E9%94%AE%20%E5%A4%96%E9%94%AE.md) ##### [9.1.1 数据库事务的四个特性及含义](09.MySQL篇/9.1.1%20%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BA%8B%E5%8A%A1%E7%9A%84%E5%9B%9B%E4%B8%AA%E7%89%B9%E6%80%A7%E5%8F%8A%E5%90%AB%E4%B9%89.md) ##### [9.1.2 视图的作用,视图可以更改么?](09.MySQL篇/9.1.2%20%E8%A7%86%E5%9B%BE%E7%9A%84%E4%BD%9C%E7%94%A8%EF%BC%8C%E8%A7%86%E5%9B%BE%E5%8F%AF%E4%BB%A5%E6%9B%B4%E6%94%B9%E4%B9%88%EF%BC%9F.md) ##### [9.1.3 drop,delete与truncate的区别](09.MySQL篇/9.1.3%20drop%2Cdelete%E4%B8%8Etruncate%E7%9A%84%E5%8C%BA%E5%88%AB.md) ##### [9.1.4 索引的工作原理及其种类](09.MySQL篇/9.1.4%20%E7%B4%A2%E5%BC%95%E7%9A%84%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E5%8F%8A%E5%85%B6%E7%A7%8D%E7%B1%BB.md) ##### [9.1.5 连接的种类](09.MySQL篇/9.1.5%20%E8%BF%9E%E6%8E%A5%E7%9A%84%E7%A7%8D%E7%B1%BB.md) ##### [9.1.6 数据库范式](09.MySQL篇/9.1.6%20%E6%95%B0%E6%8D%AE%E5%BA%93%E8%8C%83%E5%BC%8F.md) ##### [9.1.7 数据库优化的思路](09.MySQL篇/9.1.7%20%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BC%98%E5%8C%96%E7%9A%84%E6%80%9D%E8%B7%AF.md) ##### [9.1.8 存储过程与触发器的区别](09.MySQL篇/9.1.8%20%E5%AD%98%E5%82%A8%E8%BF%87%E7%A8%8B%E4%B8%8E%E8%A7%A6%E5%8F%91%E5%99%A8%E7%9A%84%E5%8C%BA%E5%88%AB.md)

redis篇

--- ##### [10.1.0 使用Redis有哪些好处?](10.Redis篇/10.1.0%20%E4%BD%BF%E7%94%A8Redis%E6%9C%89%E5%93%AA%E4%BA%9B%E5%A5%BD%E5%A4%84%EF%BC%9F.md) ##### [10.1.1 redis相比memcached有哪些优势?](10.Redis篇/10.1.1%20redis%E7%9B%B8%E6%AF%94memcached%E6%9C%89%E5%93%AA%E4%BA%9B%E4%BC%98%E5%8A%BF%EF%BC%9F.md) ##### [10.1.2 redis常见性能问题和解决方案](10.Redis篇/10.1.2%20redis%E5%B8%B8%E8%A7%81%E6%80%A7%E8%83%BD%E9%97%AE%E9%A2%98%E5%92%8C%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88.md) ##### [10.1.3 MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据](10.Redis篇/10.1.3%20MySQL%E9%87%8C%E6%9C%892000w%E6%95%B0%E6%8D%AE%EF%BC%8Credis%E4%B8%AD%E5%8F%AA%E5%AD%9820w%E7%9A%84%E6%95%B0%E6%8D%AE%EF%BC%8C%E5%A6%82%E4%BD%95%E4%BF%9D%E8%AF%81redis%E4%B8%AD%E7%9A%84%E6%95%B0%E6%8D%AE%E9%83%BD%E6%98%AF%E7%83%AD%E7%82%B9%E6%95%B0%E6%8D%AE.md) ##### [10.1.4 Memcache与Redis的区别都有哪些?](10.Redis篇/10.1.4%20Memcache%E4%B8%8ERedis%E7%9A%84%E5%8C%BA%E5%88%AB%E9%83%BD%E6%9C%89%E5%93%AA%E4%BA%9B%EF%BC%9F.md) ##### [10.1.5 Redis 常见的性能问题都有哪些?如何解决?](10.Redis篇/10.1.5%20Redis%20%E5%B8%B8%E8%A7%81%E7%9A%84%E6%80%A7%E8%83%BD%E9%97%AE%E9%A2%98%E9%83%BD%E6%9C%89%E5%93%AA%E4%BA%9B%EF%BC%9F%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%EF%BC%9F.md) ##### 10.1.6 redis 最适合的场景 ##### [10.1.7 Redis的同步机制了解么?](10.Redis篇/10.1.7%20Redis%E7%9A%84%E5%90%8C%E6%AD%A5%E6%9C%BA%E5%88%B6%E4%BA%86%E8%A7%A3%E4%B9%88%EF%BC%9F.md) ##### [10.1.8 是否使用过Redis集群,集群的原理是什么?](10.Redis篇/10.1.8%20%E6%98%AF%E5%90%A6%E4%BD%BF%E7%94%A8%E8%BF%87Redis%E9%9B%86%E7%BE%A4%EF%BC%8C%E9%9B%86%E7%BE%A4%E7%9A%84%E5%8E%9F%E7%90%86%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F.md) ##### 10.1.9 redis集群如何保证一致性?

MongoDB篇

--- ##### [11.1.0 什么是MongoDB?](11.MongoDB篇/11.1.0%20%E4%BB%80%E4%B9%88%E6%98%AFMongoDB%EF%BC%9F.md) ##### [11.1.1 MongoDB是由哪种语言写的?](11.MongoDB篇/11.1.1%20MongoDB%E6%98%AF%E7%94%B1%E5%93%AA%E7%A7%8D%E8%AF%AD%E8%A8%80%E5%86%99%E7%9A%84%EF%BC%9F.md) ##### [11.1.2 MongoDB的优势有哪些?](11.MongoDB篇/11.1.2%20MongoDB%E7%9A%84%E4%BC%98%E5%8A%BF%E6%9C%89%E5%93%AA%E4%BA%9B%EF%BC%9F.md) ##### [11.1.3 什么是数据库?](11.MongoDB篇/11.1.3%20%E4%BB%80%E4%B9%88%E6%98%AF%E6%95%B0%E6%8D%AE%E5%BA%93%EF%BC%9F.md) ##### [11.1.4 什么是集合?](11.MongoDB篇/11.1.4%20%E4%BB%80%E4%B9%88%E6%98%AF%E9%9B%86%E5%90%88%EF%BC%9F.md) ##### [11.1.5 什么是文档?](11.MongoDB篇/11.1.5%20%E4%BB%80%E4%B9%88%E6%98%AF%E6%96%87%E6%A1%A3%EF%BC%9F.md) ##### [11.1.6 MongoDB和关系型数据库术语对比图](11.MongoDB篇/11.1.6%20MongoDB%E5%92%8C%E5%85%B3%E7%B3%BB%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93%E6%9C%AF%E8%AF%AD%E5%AF%B9%E6%AF%94%E5%9B%BE.md) ##### [11.1.7 什么是“mongod”?](11.MongoDB篇/11.1.7%20%E4%BB%80%E4%B9%88%E6%98%AF%E2%80%9Cmongod%E2%80%9D%EF%BC%9F.md) ##### [11.1.8 “mongod”参数有什么?](11.MongoDB篇/11.1.8%20%E2%80%9Cmongod%E2%80%9D%E5%8F%82%E6%95%B0%E6%9C%89%E4%BB%80%E4%B9%88%EF%BC%9F.md) ##### [11.1.9 什么是“mongo”?](11.MongoDB篇/11.1.9%20%E4%BB%80%E4%B9%88%E6%98%AF%E2%80%9Cmongo%E2%80%9D%EF%BC%9F.md) ##### [11.2.0 MongoDB哪个命令可以切换数据库?](11.MongoDB篇/11.2.0%20MongoDB%E5%93%AA%E4%B8%AA%E5%91%BD%E4%BB%A4%E5%8F%AF%E4%BB%A5%E5%88%87%E6%8D%A2%E6%95%B0%E6%8D%AE%E5%BA%93%EF%BC%9F.md) ##### [11.2.1 什么是非关系型数据库?](11.MongoDB篇/11.2.1%20%E4%BB%80%E4%B9%88%E6%98%AF%E9%9D%9E%E5%85%B3%E7%B3%BB%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93%EF%BC%9F.md) ##### [11.2.2 非关系型数据库有哪些类型?](11.MongoDB篇/11.2.2%20%E9%9D%9E%E5%85%B3%E7%B3%BB%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93%E6%9C%89%E5%93%AA%E4%BA%9B%E7%B1%BB%E5%9E%8B%EF%BC%9F.md) ##### [11.2.3 为什么用MongoDB?](11.MongoDB篇/11.2.3%20%E4%B8%BA%E4%BB%80%E4%B9%88%E7%94%A8MOngoDB%EF%BC%9F.md) ##### [11.2.4 在哪些场景使用MongoDB?](11.MongoDB篇/11.2.4%20%E5%9C%A8%E5%93%AA%E4%BA%9B%E5%9C%BA%E6%99%AF%E4%BD%BF%E7%94%A8MongoDB%EF%BC%9F.md) ##### 11.2.5 MongoDB中的命名空间是什么意思? ##### 11.2.6 哪些语言支持MongoDB? ##### [11.2.7 在MongoDB中如何创建一个新的数据库?](11.MongoDB篇/11.2.7%20%E5%9C%A8MongoDB%E4%B8%AD%E5%A6%82%E4%BD%95%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E6%96%B0%E7%9A%84%E6%95%B0%E6%8D%AE%E5%BA%93%EF%BC%9F.md) ##### [11.2.8 在MongoDB中如何查看数据库列表?](11.MongoDB篇/11.2.8%20%E5%9C%A8MongoDB%E4%B8%AD%E5%A6%82%E4%BD%95%E6%9F%A5%E7%9C%8B%E6%95%B0%E6%8D%AE%E5%BA%93%E5%88%97%E8%A1%A8%EF%BC%9F.md) ##### [11.2.9 MongoDB中的分片是什么意思?](11.MongoDB篇/11.2.9%20MongoDB%E4%B8%AD%E7%9A%84%E5%88%86%E7%89%87%E6%98%AF%E4%BB%80%E4%B9%88%E6%84%8F%E6%80%9D%EF%BC%9F.md) ##### [11.3.0 如何查看使用MongoDB的连接?](11.MongoDB篇/11.3.0%20%E5%A6%82%E4%BD%95%E6%9F%A5%E7%9C%8B%E4%BD%BF%E7%94%A8MongoDB%E7%9A%84%E8%BF%9E%E6%8E%A5%EF%BC%9F.md) ##### [11.3.1 什么是复制?](11.MongoDB篇/11.3.1%20%E4%BB%80%E4%B9%88%E6%98%AF%E5%A4%8D%E5%88%B6%EF%BC%9F.md) ##### [11.3.2 在MongoDB中如何在集合中插入一个文档?](11.MongoDB篇/11.3.2%20%E5%9C%A8MongoDB%E4%B8%AD%E5%A6%82%E4%BD%95%E5%9C%A8%E9%9B%86%E5%90%88%E4%B8%AD%E6%8F%92%E5%85%A5%E4%B8%80%E4%B8%AA%E6%96%87%E6%A1%A3%EF%BC%9F.md) ##### [11.3.3 在MongoDB中如何除去一个数据库?](11.MongoDB篇/11.3.3%20%E5%9C%A8MongoDB%E4%B8%AD%E5%A6%82%E4%BD%95%E9%99%A4%E5%8E%BB%E4%B8%80%E4%B8%AA%E6%95%B0%E6%8D%AE%E5%BA%93%EF%BC%9F.md) ##### [11.3.4 在MongoDB中如何创建一个集合?](11.MongoDB篇/11.3.4%20%E5%9C%A8MongoDB%E4%B8%AD%E5%A6%82%E4%BD%95%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E9%9B%86%E5%90%88%EF%BC%9F.md) ##### [11.3.5 在MongoDB中如何查看一个已经创建的集合?](11.MongoDB篇/11.3.5%20%E5%9C%A8MongoDB%E4%B8%AD%E5%A6%82%E4%BD%95%E6%9F%A5%E7%9C%8B%E4%B8%80%E4%B8%AA%E5%B7%B2%E7%BB%8F%E5%88%9B%E5%BB%BA%E7%9A%84%E9%9B%86%E5%90%88%EF%BC%9F.md) ##### [11.3.6 在MongoDB中如何删除一个集合?](11.MongoDB篇/11.3.6%20%E5%9C%A8MongoDB%E4%B8%AD%E5%A6%82%E4%BD%95%E5%88%A0%E9%99%A4%E4%B8%80%E4%B8%AA%E9%9B%86%E5%90%88%EF%BC%9F.md) ##### [11.3.7 为什么要在MongoDB中使用分析器?](11.MongoDB篇/11.3.7%20%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E5%9C%A8MongoDB%E4%B8%AD%E4%BD%BF%E7%94%A8%E5%88%86%E6%9E%90%E5%99%A8%EF%BC%9F.md) ##### [11.3.8 MongoDB支持主键外键关系吗?](11.MongoDB篇/11.3.8%20MongoDB%E6%94%AF%E6%8C%81%E4%B8%BB%E9%94%AE%E5%A4%96%E9%94%AE%E5%85%B3%E7%B3%BB%E5%90%97%EF%BC%9F.md) ##### [11.3.9 MongoDB支持哪些数据类型?](11.MongoDB篇/11.3.9%20MongoDB%E6%94%AF%E6%8C%81%E5%93%AA%E4%BA%9B%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%EF%BC%9F.md) ##### 11.4.0 为什么要在MongoDB中用"Code"数据类型? ##### 11.4.1 为什么要在MongoDB中用"Regular Expression"数据类型? ##### 11.4.2 为什么在MongoDB中使用"Object ID"数据类型? ##### [11.4.3 如何在集合中插入一个文档?](11.MongoDB篇/11.4.3%20%E5%A6%82%E4%BD%95%E5%9C%A8%E9%9B%86%E5%90%88%E4%B8%AD%E6%8F%92%E5%85%A5%E4%B8%80%E4%B8%AA%E6%96%87%E6%A1%A3%EF%BC%9F.md) ##### [11.4.4 “ObjectID”有哪些部分组成?](11.MongoDB篇/11.4.4%20%E2%80%9CObjectID%E2%80%9D%E6%9C%89%E5%93%AA%E4%BA%9B%E9%83%A8%E5%88%86%E7%BB%84%E6%88%90%EF%BC%9F.md) ##### [11.4.5 在MongoDB中什么是索引?](11.MongoDB篇/11.4.5%20%E5%9C%A8MongoDb%E4%B8%AD%E4%BB%80%E4%B9%88%E6%98%AF%E7%B4%A2%E5%BC%95%EF%BC%9F.md) ##### [11.4.6 如何添加索引?](11.MongoDB篇/11.4.6%20%E5%A6%82%E4%BD%95%E6%B7%BB%E5%8A%A0%E7%B4%A2%E5%BC%95%EF%BC%9F.md) ##### [11.4.7 MongoDB有哪些可替代产品?](11.MongoDB篇/11.4.7%20MongoDB%E6%9C%89%E5%93%AA%E4%BA%9B%E5%8F%AF%E6%9B%BF%E4%BB%A3%E4%BA%A7%E5%93%81%EF%BC%9F.md) ##### [11.4.8 如何查询集合中的文档?](11.MongoDB篇/11.4.8%20%E5%A6%82%E4%BD%95%E6%9F%A5%E8%AF%A2%E9%9B%86%E5%90%88%E4%B8%AD%E7%9A%84%E6%96%87%E6%A1%A3%EF%BC%9F.md) ##### [11.4.9 用什么方法可以格式化输出结果?](11.MongoDB篇/11.4.9%20%E7%94%A8%E4%BB%80%E4%B9%88%E6%96%B9%E6%B3%95%E5%8F%AF%E4%BB%A5%E6%A0%BC%E5%BC%8F%E5%8C%96%E8%BE%93%E5%87%BA%E7%BB%93%E6%9E%9C%EF%BC%9F.md) ##### 11.5.0 如何使用"AND"或"OR"条件循环查询集合中的文档? ##### [11.5.1 在MongoDB中如何更新数据?](11.MongoDB篇/11.5.1%20%E5%9C%A8MongoDB%E4%B8%AD%E5%A6%82%E4%BD%95%E6%9B%B4%E6%96%B0%E6%95%B0%E6%8D%AE%EF%BC%9F.md) ##### [11.5.2 如何删除文档?](11.MongoDB篇/11.5.2%20%E5%A6%82%E4%BD%95%E5%88%A0%E9%99%A4%E6%96%87%E6%A1%A3%EF%BC%9F.md) ##### [11.5.3 在MongoDB中如何排序?](11.MongoDB篇/11.5.3%20%E5%9C%A8MongoDB%E4%B8%AD%E5%A6%82%E4%BD%95%E6%8E%92%E5%BA%8F%EF%BC%9F.md) ##### [11.5.4 什么是聚合?](11.MongoDB篇/11.5.4%20%E4%BB%80%E4%B9%88%E6%98%AF%E8%81%9A%E5%90%88%EF%BC%9F.md) ##### [11.5.5 在MongoDB中什么是副本集?](11.MongoDB篇/11.5.5%20%E5%9C%A8MongoDB%E4%B8%AD%E4%BB%80%E4%B9%88%E6%98%AF%E5%89%AF%E6%9C%AC%E9%9B%86%EF%BC%9F.md) ##### 11.5.6 Mongodb存储特性与内部原理?

Zookeeper篇

--- ##### [12.1.0 zookeeper是什么?](12.Zookeeper篇/12.1.0%20zookeeper%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F.md) ##### [12.1.1 zookeeper提供了什么?](12.Zookeeper篇/12.1.1%20zookeeper%E6%8F%90%E4%BE%9B%E4%BA%86%E4%BB%80%E4%B9%88%EF%BC%9F.md) ##### [12.1.2 zookeeper文件系统](12.Zookeeper篇/12.1.2%20zookeeper%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F.md) ##### [12.1.3 zookeeper的四种类型的znode](https://github.com/0voice/interview_internal_reference/blob/master/12.1.3%20zookeeper%E7%9A%84%E5%9B%9B%E7%A7%8D%E7%B1%BB%E5%9E%8B%E7%9A%84znode.md) ##### [12.1.4 zookeeper通知机制](12.Zookeeper篇/12.1.4%20zookeeper%E9%80%9A%E7%9F%A5%E6%9C%BA%E5%88%B6.md) ##### [12.1.5 zookeeper有哪些应用场景?](12.Zookeeper篇/12.1.5%20zookeeper%E6%9C%89%E5%93%AA%E4%BA%9B%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%EF%BC%9F.md) ##### [12.1.6 zk的命名服务](12.Zookeeper篇/12.1.6%20zk%E7%9A%84%E5%91%BD%E5%90%8D%E6%9C%8D%E5%8A%A1.md) ##### [12.1.7 zk的配置管理服务](12.Zookeeper篇/12.1.7%20zk%E7%9A%84%E9%85%8D%E7%BD%AE%E7%AE%A1%E7%90%86%E6%9C%8D%E5%8A%A1.md) ##### [12.1.8 zk的集群管理](12.Zookeeper篇/12.1.8%20zk%E7%9A%84%E9%9B%86%E7%BE%A4%E7%AE%A1%E7%90%86.md) ##### [12.1.9 zk的分布式锁](12.Zookeeper篇/12.1.9%20zk%E7%9A%84%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81.md) ##### [12.2.0 zk队列管理](12.Zookeeper篇/12.2.0%20zk%E9%98%9F%E5%88%97%E7%AE%A1%E7%90%86.md) ##### [12.2.1 zk数据复制](12.Zookeeper篇/12.2.1%20zk%E6%95%B0%E6%8D%AE%E5%A4%8D%E5%88%B6.md) ##### [12.2.2 zk的工作原理](12.Zookeeper篇/12.2.2%20zk%E7%9A%84%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86.md) ##### [12.2.3 zk是如何保证事物的顺序一致性](12.Zookeeper篇/12.2.3%20zk%E6%98%AF%E5%A6%82%E4%BD%95%E4%BF%9D%E8%AF%81%E4%BA%8B%E7%89%A9%E7%9A%84%E9%A1%BA%E5%BA%8F%E4%B8%80%E8%87%B4%E6%80%A7.md) ##### [12.2.4 zk集群下server工作状态](12.Zookeeper篇/12.2.4%20zk%E9%9B%86%E7%BE%A4%E4%B8%8Bserver%E5%B7%A5%E4%BD%9C%E7%8A%B6%E6%80%81.md) ##### [12.2.5 zk是如何选举Leader的?](12.Zookeeper篇/12.2.5%20zk%E6%98%AF%E5%A6%82%E4%BD%95%E9%80%89%E4%B8%BELeader%E7%9A%84%EF%BC%9F.md) ##### [12.2.6 zk同步流程](12.Zookeeper篇/12.2.6%20zk%E5%90%8C%E6%AD%A5%E6%B5%81%E7%A8%8B.md) ##### [12.2.7 分布式通知和协调](12.Zookeeper篇/12.2.7%20%E5%88%86%E5%B8%83%E5%BC%8F%E9%80%9A%E7%9F%A5%E5%92%8C%E5%8D%8F%E8%B0%83.md) ##### [12.2.8 zk的session机制](12.Zookeeper篇/12.2.8%20zk的session机制.md)

nginx篇

--- ##### 13.1.0 请解释一下什么是Nginx? ##### 13.1.1 请列举Nginx的一些特性? ##### 13.1.2 请列举Nginx和Apache 之间的不同点? ##### 13.1.3 请解释Nginx如何处理HTTP请求。 ##### 13.1.4 在Nginx中,如何使用未定义的服务器名称来阻止处理请求? ##### 13.1.5 使用“反向代理服务器”的优点是什么? ##### 13.1.6 请列举Nginx服务器的最佳用途。 ##### 13.1.7 请解释Nginx服务器上的Master和Worker进程分别是什么? ##### 13.1.8 请解释你如何通过不同于80的端口开启Nginx? ##### 13.1.9 请解释是否有可能将Nginx的错误替换为502错误、503? ##### 13.2.0 在Nginx中,解释如何在URL中保留双斜线? ##### 13.2.1 请解释ngx_http_upstream_module的作用是什么? ##### 13.2.2 请解释什么是C10K问题,后来是怎么解决的? ##### 13.2.3 请陈述stub_status和sub_filter指令的作用是什么? ##### 13.2.4 解释Nginx是否支持将请求压缩到上游? ##### 13.2.5 解释如何在Nginx中获得当前的时间? ##### 13.2.6 用Nginx服务器解释-s的目的是什么? ##### 13.2.7 解释如何在Nginx服务器上添加模块? ##### 13.2.8 nginx中多个work进程是如何监听同一个端口的?如何处理客户连接的惊群问题? ##### 13.2.9 nginx程序的热更新是如何做的?