【决战西二旗】|聊聊后端面试中的一些问题和思考
本文首发于:https://mp.weixin.qq.com/s/lBZxwkdMPUxIu_OPVcYEmA
微信公众号:后端技术指南针
持续干货 专注原创 欢迎关注 共同进步
原创文章 转载请与我联系
0.前言
之前写了一些具体知识点的相关文章,本次聊聊面试实战。
面试是为了查漏补缺、明确学习方向和斩获offer,所以写一些自己以及好朋友们遇到过的面试题、以及个人对面试的一些看法。
题目主要来自百度、阿里、腾讯、微博、搜狗、FunPlus、高德、滴滴、快手、旷视、360、迅雷、猎豹、TME等公司,由于时间原因做到100%完整描述不太可能,但是基本上也都达意了,有一定的参考价值。
1.修炼心法
-
不打无准备之仗
知己知彼百战不殆,面试之前需要在拉勾、BOSS直聘上大致了解一下招聘岗位的工作描述,不排除一些公司虚张声势写些个根本用不着的玩意,所以如果觉得岗位对口却匹配度低,也不必紧张试试再说。
内推是了解岗位要求的重要渠道,不过从经验看如果不是内推人本组的招聘岗位,很难做到深入细致的了解,总起来说这样的内推和在线投递差别并不太大,不要以为内推就稳了,否则笔者内推奖金早拿到手软了。另外相同岗位不同级别考察的侧重点也有很大区别,因此要根据意向岗位级别在深度和广度上进行差异化准备。
-
面试官什么路子
一百场面试就有一百种侧重点,但并不能都算得上高质量的面试,知乎上有关于高质量面试的话题,感兴趣可以看看。
作为主导者的面试官,个人认为最重要的原则是:明确在招岗位的职责内容,并以此为出发点对候选人进行考察,一般来说候选人过往经历和在招岗位很相似的情况比较少,在此情况下就要从候选人的基础是否扎实、学习能力如何等方面来衡量候选人快速适应新岗位内容的能力。
举个例子:“并不一定要把1TB的硬盘装满才能证明这个硬盘是1TB的”因此很多时候面试就像是一场证明500GB硬盘具备1TB空间的过程,至于测试手段是否科学就是面试官需要拿捏的了,如果面试官都不清楚自己问这个问题究竟是为了考察什么,那么这就是一场低质量的面试,所以对于候选人来说成败与否都不用在意,毕竟这种糊涂面试官如果以后作为同事也是件很糟糕的事情。
-
做个合格的面试者
候选人无法左右面试官的问题,但是对于非大神面试者还是要做到几点,来提高面试成功率,包括但不限于:
-
珍惜机会切忌裸面
毫无准备地去面试既浪费自己的时间也浪费面试官的时间,任何事情都有机会成本,重要的是现在大厂都有自己的人才库体系,如果一年半载后再投,上次裸面的评价都依然还在,新的面试官对候选人的印象会大打折扣,甚至不给面试机会,所以要珍惜面试机会,裸面的面试者并不少见,问几个问题就GameOver了,场面也十分尴尬。
-
理清思路清晰表达
在面试官表述了问题之后,就算问题在射程范围内也不要急于回答,先理清楚条件,如有疑问立即求证,确定问题所有条件再做解答。在笔者作为面试官时比较看重这一点,因为这种性格在工作中是非常可贵的,很多时候你会遇到很多模糊需求,如果不反复确定就按照你以为的开干,只能是缘木求鱼,最终delay掉需求。
-
拓展思维勇敢作答
对于大部分面试者来说,遇到没见过的题目也不必慌张要冷静分析当前问题中的难点,进而结合自己的实际经验和知识储备来提出你的分析和解决方案,纵然短时间内很难提出最优方案,或许可以很接近答案了,但是也不要胡说,否则只能让人觉得你胆大心更大,具备删库跑路的潜力。
-
相信自己信心满满
时常出现面试者去二三线厂面试,最后给的评价很低,完全与其本人技术实力不匹配,之后短时间内反手拿了BAT的offer,所以任何时候都不要妄自菲薄,要无条件相信自己。我对此深有体会,笔者本硕都非CS专业且有一定跨度,遥想当年校招隔壁实验室一起打球的CS硕们收割大厂offer,我这边就算小公司也会被鄙视一通,所以无论现境如何,坚定信念、找准方向、持续发力、总会有所斩获。
2.实战题目
由于笔者以及好朋友们大都是Linux C/C++/Python/Go技术栈,所以实战题目也是围绕这个技术栈展开的,其他语言栈的大神可以选择性阅读无语言差异的共性问题,比如MySQL、Redis、Linux系统等。
-
题目分类
Linux C/C++技术栈的题目一般包括但不限于以下几大类:
-
编程语言
-
数据结构和算法
-
数据库存储
-
Linux系统
-
开源组件
-
工程设计
-
题目汇总
按照上面分类来归纳一些大厂的问题,更能看到各个分类下的热门问题,从而更好地把握面试方向。
-
编程语言
-
阐述如何设计一个C++类?实现String类。
-
谈谈对C++虚函数机制的理解。
-
STL的Vector原理及迭代器失效的理解。
-
设计一个C++HashMap类。
-
使用C++实现一个堆的模板类。
-
写一个宏定义比较函数并解释宏展开过程。
-
谈谈std::move的理解和使用。
-
malloc的内存可以用delete释放吗?原因?
-
简述C++11的新特性以及解决了什么问题。
-
STL的Map原理、插入和删除复杂度分析。
-
STL的Map基于红黑树实现的原因,为什么不选择哈希表?
-
为什么需要虚析构?虚析构和普通析构函数的区别是什么?
-
说明C++对象的内存布局模型。
-
聊聊C++临时对象和右值引用,写个例子。
-
使用C++写一个高效的多维矩阵乘法。
-
谈谈对智能指针的认识并实现一个智能指针类。
-
STL中Map的查找时[]和find区别是什么?哪个更快?
-
实现memcpy函数效率尽可能高。
-
尝试实现C/C++中常用字符串库函数。
-
谈谈C++中强制类型转换的原理和使用,写个例子。
-
谈谈C++的设计模式,重点介绍下单例模式、工程模式等。
-
数据结构和算法
-
求二叉树节点和为N的所有路径。
-
实现二叉树的镜像。
-
实现两棵二叉树相加生成一棵新的二叉树。
-
实现单链表的递归逆置和非递归逆置。
-
二分查找变种问题。
-
二叉树的后序非递归遍历。
-
两个无序整型数组交换元素使得两数组和差距最小。
-
给定整型数组和目标数输出数组所有两数之和为目标数的组合。
-
找到带权重二叉树中从根到叶子的最大和路径。
-
最长公共子序列LCS问题。
-
二叉树中找到指定两个节点最近公共祖先。
-
实现堆排序求Top10数据。
-
实现最小栈。
-
简述并尝试设计一个布隆过滤器。
-
外排序的基本实现过程。
-
常见排序算法的性能对比。
-
快速排序的非递归实现
注:关于数据结构和算法的网站和书籍非常多,并且这个分类也是面试中变幻最大的,这里就不展开了。对于数据结构和算法能力的切实提高,可以刷LeetCode、《算法导论》、《编程之法》、《编程珠玑》、《程序员面试金典》(注意不是宝典)、《程序员代码面试指南》等书籍,很多公众号或者书籍的作用是对知识点进行梳理归纳总结,没有捷径,只有自己动手多练多写才能真正成为自己的硬实力。
笔者认为虽然数据结构和算法的题目比较繁杂,但是掌握常见数据结构(数组、链表、栈、队列、树等)的基本特性和实现方法,再结合二分、递归、回溯、贪心、动态规划等算法思想,很多问题都可以回答得比较接近正确答案,数据结构做骨架、算法是灵魂,务必多练多写找到感觉。
坚持每天刷leetcode是个好办法,但是对于在职人员来说996已经快被搞死了,LeetCode每日一题确实有些困难,况且刷LeetCode的重点在于一题N解,多个角度多种方法解题,不过还是那句话:”种一棵树的最好时间是十年前,而后是现在”。
-
数据库存储
-
谈谈对于Redis的底层数据结构的理解。
-
跳表了解吗?Redis的zset实现原理以及为什么不用红黑树。
-
Redis哨兵原理以及集群版故障转移过程。
-
基于Redis实现分布式锁。
-
Redis渐进式Rehash的实现原理。
-
Redis和LevelDB的区别以及LevelDB的LSM树和WAL原理。
-
Redis主从同步的实现原理和过程、产生数据丢失的原因。
-
MyISAM和InnoDB的区别。
-
MySQL索引原理和优化。
-
Redis集群版如何实现一致性Hash算法的。
-
Redis的单线程网络框架原理和混合持久化机制。
-
类Redis数据库Pika了解吗?基本设计架构是什么?
-
如何设计一个缓存系统以及缓存击穿的解决方案?
-
一致性协议raft/paxos/2pc/3pc基本原理。
-
Redis的Gossip协议原理。
-
Redis4.0+版本的BIO线程原理和使用。
-
简述如何自己实现一个NoSQL,需要考虑什么。
-
Linux系统
-
LVS实现负载均衡的原理。
-
简述Linux内存管理原理以及伙伴算法和Slab算法。
-
select和epoll的对比以及epoll实现的底层原理和数据结构。
-
epoll的LT模式和ET模式下读写操作,实现一下ET模式的read/write。
-
使用C++简单实现一个生产者消费者模型。
-
Linux虚拟内存和物理内存的区别与联系
-
如何使用gdb调试多进程、多线程程序。
-
谈谈C10K和C10M问题及大致实现思路。
-
Linux地址复用和端口复用的使用。
-
谈谈Reactor和Proactor模式区别与联系。
-
尝试基于epoll实现一个高并发网络框架。
-
Nginx的基本原理以及负载均衡实现方法。
-
谈谈Linux服务器内存/cpu/磁盘/网络带宽的监控命令和问题排查。
-
谈谈CAP理论以及分布式一致性算法。
-
了解CpuCache吗,如何据此来优化代码。
-
读写锁、RCU锁、自旋锁的对比以及设计读优先/写优先的读写锁
-
自己设计实现一个简单的读写锁。
-
谈谈grpc的使用以及brpc的对比。
-
对比协程和进线程,重点说明系统开销差异和各自优缺点。
-
谈谈对线程同步和多线程安全的理解。
-
Https的C/S交互过程、http1.0/2.0/3.0的对比。
-
多进程通信的方法和对比。
-
多线程同步的实现和线程安全。
-
实现一个基于LRU的本地缓存。
-
TCP/IP的拥塞控制原理和缺陷、BBR算法对比。
-
使用Python实现多进程和多线程以及谈谈对GIL的理解。
-
网络攻击有哪些?简述DDos、CC攻击。
-
对比内存分配malloc/tcmalloc/ptmalloc。
-
Protobuf协议的简单原理和使用。
-
Coredump的常见原因。
-
死锁的原理以及写一个死锁。
-
MapReduce的基本原理、写个简单的map和reduce的程序。
-
同步异步阻塞非阻塞IO的理解。
-
git的基本原理以及常用命令。
-
局部性hash算法simhash的原理。
-
服务端长短连接的区别、优势和场景。
-
如何避免多线程的虚假唤醒问题。
-
实现简单的线程池和连接池。
-
实现一个可以完成C10K+的TCP网络框架。
-
尝试多种方法实现一个守护进程,2 magic fork了解吗?
-
惊群问题知道吗?Nginx是如何解决的?
-
谈谈对服务治理和服务发现的理解。
-
微服务接触过吗?谈谈对微服务的理解。
-
服务异步化编程了解过吗?
-
开源组件
-
常用的MQ有哪些以及各自的对比和场景
-
Kafka的基本原理和实现要点
-
libevent/libuv的基本原理和使用
-
Boost.Asio的原理和使用
-
微信协程库libco原理和使用
-
DPDK的基本原理和用户态协议栈的概念
-
Redis和Memcached对比
-
RPC框架对比:brpc/grpc/thrift
-
STL源码的理解和阅读分析
-
Nginx的架构、原理、使用
注:开源组件的问题一般都比较宽泛,因此没有列举太多具体问题。开源组件的准备重在基本原理和架构的理解,面试官不希望候选人对开源组件的使用是完全的拿来主义和黑盒子式API调用,其次是从开源组件中获得解决问题的思想和套路。因为日常工作场景有很多共性问题,可以借鉴开源组件的经验进行迁移解决,都是要站在巨人的肩膀上的,牛顿都站了,你何必要闭门造车呢?
-
工程设计
-
信息流推荐中会生成大量点击率文章,设计一个程序实现即时排序,返回热门文章。
-
词库每个词都有根据点击率来计算的热度,实现一个系统,支持前缀匹配并且返回Top10的热词。
-
设计一个支持千万级文章相似度去重的程序,来实现抄袭、洗稿文章的识别,时间ms级,准确率不低于95%。
-
小内存机器有两个文件A和B,分别存放5亿条均长64字节的url,试着找到A和B中所有重复的url。
-
尝试实现一个简单的音乐推荐系统,可以不涉及具体算法,主要说明工程部分即可。
-
设计一个黑词服务实现黄反、指令词、敏感词等过滤功能,耗时ms级。
工程设计题目一般会是面试官日常遇到的典型问题,类型很多,但是系统设计类问题经常和海量数据问题、堆排序等一起出现。对于此类问题,重要的是明确功能点、找准解题方向、拆解子问题、分步骤合并、各个击破、先实现再提优化方案,以此原则来解决工程设计问题,基本上就很接近答案了。
3.小结和感慨
题目很多并且没有给出解答,除了工程设计题,其他题目在网上都可以找到解答,但是本号会在后续文章中对上述问题各个击破,建立完整分类的体系,敬请期待。
2018下半年以及整个2019一直被认为是寒冬时期,也总能听到裁员或者公司倒闭的一些消息,有校招生比offer也有刚毕业的应届生被裁,有套现离场的也有昨天还在熬夜加班优化代码,次日被裁的,还有甚嚣尘上的35岁失业问题,林林总总。
无论如何作为求职者和在职者都要坦然面对,市场波动在所难免,我们能做的只有:拥抱变化 时刻准备着。
版权声明:
原创文章 转载请与我联系 进行授权
微信公众号:后端技术指南针