视频面。本次面试分为两大块:
翻转数列
小Q定义了一种数列称为翻转数列:
给定整数n和m, 满足n能被2m整除。对于一串连续递增整数数列1, 2, 3, 4..., 每隔m个符号翻转一次, 最初符号为'-';。
例如n = 8, m = 2, 数列就是: -1, -2, +3, +4, -5, -6, +7, +8.
而n = 4, m = 1, 数列就是: -1, +2, -3, + 4.
小Q现在希望你能帮他算算前n项和为多少。
输入描述
输入包括两个整数n和m(2 <= n <= 109, 1 <= m), 并且满足n能被2m整除。
输出描述
输出一个整数, 表示前n项和。
示例1
输入
8 2
输出
8
腾讯看来的确全部是 c++,面试官也是说基本上都是 c++,没有专门搞 java 的组,所以大家 java 投腾讯还是务必慎重,最开始问我的技术栈是什么,c++是否了解,用的比较多?得知我说基本没咋用过之后,就开始尝试问计算机网络方面的问题。
这个我在上面已经详细说过了…
![preview](https://upload-images.jianshu.io/upload_images/14850956-11795469bf5593d1.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)[1] preview[2]
嘿嘿嘿,这个没问题了,可以看我的最新的文章 —《零拷贝及其周边》
用 key or index 建立索引,优化索引的方法:尽量复用索引,利用好最左前缀和索引下推原则,尽量减少回表次数,利用覆盖索引。
原子性:利用 undolog,回滚机制,完成要么全部成功,要么全部失败; 隔离性:主要是靠一致性视图+当前行的 row_id_transaction,来完成的。 一致性:主要靠加锁防止事务冲突,一致性是另外三个的顶层,只要他们三完成了他才有可能完成,还有mvcc的加持,以及 undolog、redolog。 持久性:redolog保证crash-safe,bin-log保证归档。
略
redo log包括两部分:一是内存中的日志缓冲(redo log buffer),该部分日志是易失性的;二是磁盘上的重做日志文件(redo log file),该部分日志是持久的。 详细分析 Mysql 中的三个日志:redolog、undolog、binloghttps://juejin.im/entry/5ba0a254e51d450e735e4a1f
这个简单,略
简单,略
Mysql 保证主从一致性: 主库接收到客户端的更新请求后,执行内部事务的更新逻辑,同时写binlog。 备库B跟主库A之间维持了一个长连接。主库A内部有一个线程,专门用于服务备库B的这个长连接。一个事务日志同步的完整过程是这样的:
这里需要说明,后来由于多线程复制方案的引入,sql_thread演化成为了多个线程。 ![image-20200325005851525](https://upload-images.jianshu.io/upload_images/14850956-ed61f7489257fdde.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)[3] image-20200325005851525[4]
因为语言上还是有很多区别的,在后面又问了几个有关于 c++ 的问题,答得不是很好
略。
协程的应用场景主要在于 :I/O 密集型任务。 这一点与多线程有些类似,但协程调用是在一个线程内进行的,是单线程,切换的开销小,因此效率上略高于多线程。当程序在执行 I/O 时操作时,CPU 是空闲的,此时可以充分利用 CPU 的时间片来处理其他任务。在单线程中,一个函数调用,一般是从函数的第一行代码开始执行,结束于 return 语句、异常或者函数执行(也可以认为是隐式地返回了 None )。有了协程,我们在函数的执行过程中,如果遇到了耗时的 I/O 操作,函数可以临时让出控制权,让 CPU 执行其他函数,等 I/O 操作执行完毕以后再收回控制权。 简单来讲协程的好处:
缺点:
最后再贴个图来总结一下,更清楚: ![img](https://upload-images.jianshu.io/upload_images/14850956-7053fe4d67e0dd96.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)[5] img[6] 作者:程序猿杂货铺 链接:https://juejin.im/post/5d5df6b35188252ae10bdf42来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
最后谈了谈一些数据结构和算法:
还有一些细枝末节的问题,印象已经不深了,大概就是这些吧。
总结一下:面试官非常擅长挖掘面试者的优势,对面试者不太懂的全部不问,基本上我会什么就问什么,所以大概面试了半小时后,就开始对着我的博客问,所以整体上给人的感觉是很好的。大家如果要面腾讯的话建议多看看c++,并且对常见的 计网 和 os 的问题尽量往深处走,面试官只看中你对问题的深度,不会的问题他不会追问。
最大的收获:
部分拓展
301重定向是永久的重定向,搜索引擎在抓取新的内容的同时也将旧的网址替换为了重定向之后的网址。 302重定向只是暂时的重定向,搜索引擎会抓取新的内容而保留旧的地址,**因为服务器返回302,所以,搜索搜索引擎认为新的网址是暂时的。**所以302,会导致劫持问题:A站通过重定向到B站的资源xxoo,A站实际上什么都没做但是有一个比较友好的域名,web资源xxoo存在B站并由B站提供,但是B站的域名不那么友好,因此对搜索引擎而言,可能会保存A站的地址对应xxoo资源而不是B站,这就意味着B站出了资源版权、带宽、服务器的钱,但是用户通过搜索引擎搜索xxoo资源的时候出来的是A站,A站什么都没做却被索搜引擎广而告之用户,B站做了一切却不被用户知道,价值被A站窃取了。这里 A 就相当于是我们在输入框输入的域名,然后对 B 重定向 302,导致自己的域名不会被替换却还享用 B 的资源。 307意思就是客户端内部自己做了重定向,就比如 www.baidu.com ,我在有了 HSTS 的 max-age 之后会自动从 http://www.baidu.com 跳转到 https://www.baidu.com。
在传输层和应用层中间有个 ssl/tls 层 流程:
跟正常的http传输一致,只不过是密文传输。
https://blog.csdn.net/u013320868/article/details/54090295 对称加密,加密解密时间更快,但是密钥管理是个大问题; 非对称加密,更安全,但是加密解密时间较长一些。
https://zhuanlan.zhihu.com/p/44185847 之所以难解,是因为位数很长,并且去对一个超级大的数进行因式分解,如果没有私钥的话几乎不可能做到。 主要用到的数学知识有欧拉函数、费马小定理等等
这里我在腾讯面试部分也有提到,但是腾讯那部分主要侧重讲了主从一致是如何实现的,而高可用则是建立在主从一致的基础上的。 先上一个自己画的图: ![高可用机制](https://upload-images.jianshu.io/upload_images/14850956-272af610f82eb466.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)[7] 高可用机制[8] mysql 的高可用的实现,基础就是能够做到主备切换,而主备切换的前提是要保证主从的一致性,这样才能切换,不然肯定会影响数据,但是要保证主从一致性,就会带来主从延迟的情况,具体的主从一致性的实现可以看我上面讲的,主从延迟可能会有图中那些原因,针对不可避免的主从延迟,主备切换有两种策略:
Mysql 中常见的三个日志文件分别是 undolog、redolog以及binlog,redolog 主要是负责 crash-safe,也就是崩溃恢复的工作,binlog主要是做一个归档的作用,redolog和binlog是两阶段提交的,这也是常用的分布式的手段吧,大家都okay了才commit,redolog是可擦除的,存储的是物理日志,但是binlog是顺序写,存储的是逻辑日志,并且 redolog 是 Innodb 独有的,binlog则是 server端有的。undlog 主要是负责 mvcc 和回滚,在数据修改的时候,不仅记录了redo,还记录了相对应的undo,如果因为某些原因导致事务失败或回滚了,可以借助该undo进行回滚。undo log和redo log记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。
Mysql 从锁的范围上讲分为全局锁、表级锁以及行锁。 全局锁称为 Flash Tables with Read Lock,主要用来全库逻辑备份,这个命令可以使整个库处于只读状态。**使用该命令之后,数据更新语句、数据定义语句和更新类事务的提交语句等操作都会被阻塞。**如果这个命令在主库操作的话,会导致业务停摆,如果再备库操作的话,会导致备库无法写从主库传来的binlog,造成主备延迟,所以我们很少使用它,一般都是使用mysql自带的 mysqldump 去进行全库逻辑备份,因为 mysqldump 有 mvcc 的支持,所以可以一边备份一边读写,但是这个必须要数据库引擎支持rr这个隔离级别,像 MyISAM 就不行。 表级锁又分为表锁和元数据锁MDL,其中表锁需要我们去显式加锁,例如 lock tables … read/write,如果一个线程对其显式加了表读锁,那么其他线程和该线程只能读该表,如果该线程加了表写锁,那么其他线程啥也干不了,所以这个锁表的粒度还是太大,一般不会采用。 表级锁的另外一种是元数据锁MDL,这是系统默认加上的,对表进行 DML 是加读锁,对表进行 DDL 是加写锁,读写互斥,读共享,相当于 ReadWriteLock,但是这里没有写降级的过程。 行锁是我们最经常用的了,也分为读锁和写锁,这里的读单指 select,这里的写指的是 update、delete、insert等等,当然我们也可以对 select 进行显式的加锁,此时 select 就从乐观读锁「跟 StampedLock 类似,一个是通过 version 判断数据有没有变化,一个是通过 stamp 判断」变成了悲观读锁或者写锁了,此时mvcc是失效的,是跟 update等语句一样强制去当前读的。
索引有很多,常见的就是聚集索引和非聚集索引,聚集索引就是元素的逻辑位置和物理位置保持一致,也称为主键索引,是B+树,因为支持范围查询,并且索引节点只有指针和索引,这样单个节点就能容纳更多的指针域,从而使得树的高度下降。 非聚集索引要注意减少回表的次数,常用的方法就是覆盖索引、使用最左前缀原则尽量减少索引的建立,同时注意可以使用索引下推来减少回表的次数。
mysql中常用的范式就是三大范式 第一范式:确保每列的原子性,比如说地址这一属性,有的业务可能对城市用的比较多,我们就就应该细分,这样在对用户使用城市进行分类的时候就非常方便,也提高了数据库的性能。 第二范式:确保表中的每列都和主键相关,去除部分依赖。最典型的场景就是多对多的场景,比如订单-商品表,因为订单中可能会有多种商品,所以要将订单编号和商品编号作为数据库表的联合主键,如果此时把商品信息也写在这个表中,就不符合第二范式了,这样会造成数据冗余,分表会更好。 第三范式:确保没有传递依赖,也就是每个非主属性都要依赖于主属性,例如订单表,和用户是一对多的关系,此时用户的id会是这个表的外键,如果在这里加上用户的名字,就违反了第三范式,也是会造成数据的冗余的。 参考: https://www.cnblogs.com/linjiqin/archive/2012/04/01/2428695.htm
[1]
preview: https://tva1.sinaimg.cn/large/00831rSTgy1gd09djaf2lj30u00gwmz5.jpg
[2]
preview: https://tva1.sinaimg.cn/large/00831rSTgy1gd09djaf2lj30u00gwmz5.jpg
[3]
image-20200325005851525: https://tva1.sinaimg.cn/large/00831rSTgy1gd5ibtjmvaj314c0u0trb.jpg
[4]
image-20200325005851525: https://tva1.sinaimg.cn/large/00831rSTgy1gd5ibtjmvaj314c0u0trb.jpg
[5]
img: https://tva1.sinaimg.cn/large/00831rSTgy1gdj56e9yqbj30iw07rdkm.jpg
[6]
img: https://tva1.sinaimg.cn/large/00831rSTgy1gdj56e9yqbj30iw07rdkm.jpg
[7]
高可用机制: https://tva1.sinaimg.cn/large/00831rSTgy1gd8uouyrttj31400u0kjm.jpg
[8]
高可用机制: https://tva1.sinaimg.cn/large/00831rSTgy1gd8uouyrttj31400u0kjm.jpg
乔戈里又要来了腾讯面经哈,学弟写这篇一面面经也算是尽心尽力,各位记得在看点一下支持一下!超过100个在看,乔戈里才有动力和学弟继续去要一下面经,毕竟在看数也能说明大家对这种类型的文章感不感兴趣~(对了,点击阅读原文,直达学弟博客。)