面经 | 双非学校怎么斩获字节跳动、CVTE、快手offer?附送优质简历模板~

1,463 阅读12分钟

01个人情况

本人双非本科,大一大二的时候主要是学专业课,然后自己课外找了一些后端开发相关的资料学习(bilibili有很多学习资料,我是属于笨鸟先飞的那种hhhhh);然后在大三下学期拿到了CVTE、快手、字节跳动的后端实习offer;最后选择了字节深圳,随后转正拿到正式offer。


点击[阅读原文]看完整文章,阅读效果更佳!


02面试内容

(说明:此版块文字较多)

一面


1.二叉树的前序遍历
递归版

非递归

2.连续最大和
一个数组有 N 个元素(N>0),求连续子数组的最大和。例如:[-1,2,1],和最大的连续子数组为[2,1],其和为 3。

3.甲乙轮流抛一枚均匀的硬币,谁先抛到正面谁赢,问谁的赢面大?概率分别为多少?
先抛硬币的人赢的概率为2/3,后抛硬币的人赢的概率为1/3。

4.TCP的四次握手?可以三次么?为什么要4次?
四次握手过程如下:


不能合并为3次。因为TCP开辟了一个全双工的通道,客户端发送FIN只能说明客户端没有数据要传送。但服务端可能还有数据要进行传送。因此每一对FIN与ACK,代表关闭了一边的连接。

5.timewait是tcp的哪个阶段?

6.Nginx怎么配置负载均衡?
在upstream中配置转发的地址以及转发策略,在location中配置请求转发到哪个upstream。

7.Redis怎么部署集群?Redis Cluster的原理?怎么把一个Redis请求负载均衡到具体的某个节点上?(不会)
没有部署过集群。只随便说了官方有个Redis Cluster可以部署集群。通过一致性哈希可以把Redis请求负载均衡到集群中的节点。

8.Redis怎么实现分布式锁?(答得不好)
实现Redis官方的RedLock,每次要获得分布式锁时,向所有Redis节点发出setnx请求锁,若获得超过N/2的节点支持,则说明获得了锁,否则要向所有Redis节点发出请求删除之前的设置的键。

二面


1.HashTable、HashMap、TreeMap的区别
HashTable是线程安全的,HashMap不是线程安全的。HashTable是在方法上加了synchronized关键字,所以并发性能很差。
TreeMap支持排序,默认升序,并且key不能为null。

2.新生代、老年代?为什么要有老年代?
新生代、老年代是Hotspot虚拟机上的概念。因为根据一些统计结果,大部分对象的生命周期很短,创建后不久就会变成垃圾对象。
因此一般来说(大对象除外),新对象创建在新生代,只有经过一定次数的gc后仍未被回收的对象才可以进入老年代。
默认情况下,新生代:老年代是1:4。
我们主观上认为,那些经过一定次数的gc后仍未被回收的对象,被gc的可能性比较小(不是没有可能被gc)。
我们可以设想,如果没有老年代,全部是新生代,那么每次gc都要扫描整个内存,这会提高stop the world的时间。
反之,通过划分老年代,可以使得每次gc的区域只限在新生代,相对整个内存扫描范围就小了很多。
当然按这样处理,老年代里会在某个时间点出现垃圾对象,但无关紧要,因为老年代只要没有出现空间不足,就不影响使用。
当老年代也出现空间不足时,才对老年代进行gc,这时再将这些垃圾对象回收。
总结一句话:缩小gc(准确来说是MinorGC)的范围,减少stop the world的时间,提高吞吐率。

3.怎么产生一个引用?
    • 最常见是new,new一个对象然后将new出来的对象赋值给一个引用变量,这时就持有了该对象的强引用。
    • 假如有一个容器,把new出来的对象放在容器中,那么容器间接持有了这个对象,只要容器不被回收,那么这个对象就不会被回收。

4.怎么判断一个对象是不是垃圾?
从GCROOTS开始遍历,被遍历到的对象则标记为有效节点,无法被遍历到的对象则为垃圾对象。
GCROOTS一般有几种:
    • 栈帧中的对象
    • 静态变量
    • 方法区中常量引用对象
    • 本地方法栈中JNI引用对象

5.在浏览器中输入url后,发生DNS的流程?
    • 浏览器搜索自身的DNS缓存,操作系统的DNS缓存,本地host文件查询,如果都没有则向域名服务器查询。
(感觉说的有点简单就和面试官顺便扯了一下DNS污染)
中国的“长城防火墙”就是通过DNS污染,将域名服务器中的某些国外网站(比如google)的域名对应的ip解析成一个错误的地址,因此无法访问。

6.进程和线程的区别?进程间通信的方式?
在操作系统中,进程是拥有资源并作为调度的单位,但线程出现后,进程则只拥有资源,而将线程作为调度的基本单位。
进程的通信方式:
    • 信号
    • 管道
    • 消息队列
    • 共享内存
7.单链表的相加和,用单链表表示一个数字:1->2(表示12), 3->4(表示34),相加后得到结果4->6(表示46)。

思路一:使用栈实现

思路二:时间复杂度O(N*logN),空间复杂度O(1)。
    • 将对应位上的数字全部加到较长的链表上(此时不管节点超不超过10);
    • 设置标志位flag为false,遍历较长的链表;
    • 若节点值大于等于10,则取val模10的值,并向前一个节点进位,设置标志为true;若节点值小于10,则不做操作;
    • 由于在进位时可能导致前一位超过10(比如前一位是9,进1给它则为10),因此只要flag为true,则继续从头遍历,直至有一个遍历后flag为false。

三面


1.大三还是大四?
大三。
2.毕业工作还是考研?为什么?
工作。因为比较喜欢计算机,也比较喜欢动手实践。
3.最近在学什么?平时怎么学习?
最近在学golang,在看许式伟大佬的书。
平时学习:
    • 通过一些文章了解到一些概念
    • 通过官网了解更详细的信息
    • 通过一些视频快速入门
    • 通过书籍系统的学习
    • 回归官方文档
4.给定两个数字n、k,n表示想要喝酒的瓶数,k表示k个瓶盖可以换一瓶酒,问只需要买多少瓶就行。
版本1:回溯法,时间复杂度O(N),空间复杂度O(N)(因为递归调用会用到栈空间)。

版本2:动态规划,时间复杂度O(N),空间复杂度O(N)。

版本3:动态规划,时间复杂度O(N),空间复杂度O(1)。

5.有什么想问的吗?
Q:(我)如果去字节实习是否有一对一的导师?
A:(面试官)有的,应该说每个公司对新人都会有的。

Q:(我)部门目前在哪个城市?在牛客上听说深圳的岗位招满了,会被调去北京或者广州?
A:(面试官)部门在深圳,没有出现你说的情况。

Q:(我)头条主要使用Golang和Python嘛,那需要我转技术栈吗?
A:(面试官)也不是转技术栈吧,只是多学了一门语言,至于MySQL这些都是一些通用的技能。

Q(面试官):你什么时候可以来实习?
A(我):大概7月份吧,把课程设计和考试弄完。不过如果需要早点去实习也可以,毕竟广州深圳挺近的。

Q(面试官):建议早点来,头条要实习3个月才能走转正流程,如果人才合适的话,走内部流程转正比到时候秋招的压力小的多。A(我):好的,明白了,没什么问题要问了,谢谢。


03面试感想

心态

我春招投了30多家公司,能走到笔试的不到10家,有面试机会的只有5、6家,大部分都是渺无音信、简历被筛;那段时间压力会很大,一定要稳住心态,然后安排好学习计划、笔试面试时间。

技术面试

难度方面,由于是实习生面试,对于项目要求也不会特别高,内容不是特别难,在回答问题时可以大概按如下策略:
  • 对于会的,要能够正确地、逻辑清晰地用自己的语言解答,若能够解答问题的基础上,说一些扩展的东西会加分
  • 对于了解过、但不懂原理的,可以稍加思考,假设是你会怎么实现,不一定正确,但要有一个大概可行的实现思路;
    • 例子:快手三面面试官问tail命令的原理
    • 从使用上倒推,tail是展示文本的倒数几行(默认好像是5),那么我只要拿到数据,以换行符作为分隔符,取倒数几行即可(类似字符串的split操作)
    • 对于大文本、内存有限的情况,肯定不能全部数据读取到内存,那么应该从后往前读取文件数据
    • 涉及到读取文件数据,那就是I/O,众所周知,I/O比内存操作要慢几个数量级,假设一次读取的数据太少,只有倒数一两行,那么就还需要继续读取数据,从而需要有多次的I/O;因此可以用一个1M的buffer(不一定要是1M,可以是其他大小,只是一个假设的值),一次读取1M的数据在内存进行操作,减少I/O次数
  • 对于没听过的、完全不会的,应该直接和面试官表示对这方面不熟悉,避免浪费双方时间,也会留下不好的面评;
  • 对于算法题,一定要想清楚后再coding,没有充分思考就开始coding,必然会有很多bug,面试官是可以看到你的coding过程的。

HR面

一般不会刷人,只要你三观正,能够有团队合作意识即可。
HR面通常会问:
  • 在校经历
  • 学习生活
  • 怎么学习
  • 如果有项目经验你是怎么和其他同学协作的
  • 有分歧是怎么解决的等等

正常回答,然后多用一些能够展示自己比较正面的例子就行。


04
简历制作


篇幅

推荐两页,一页一般内容太少(也得看排版),超过两页又太多,简历筛选时根本没多少时间详细看。

个人信息
  • 姓名、手机、邮箱、博客(如有)、正装照(别搞花里胡哨的)、意向岗位、学校、获奖及证书(如有);
  • 一定要再三检查信息不要出错

技能点

  • 不要太笼统,面试官基本是看你的简历来问的,你用几句很笼统的话把技能点总结了,面试官就没得问了;
    • 反例:“熟悉MySQL”、“熟悉计算机网络”
    • 正例:“熟悉MySQL的使用,了解索引原理、SQL优化、Innodb引擎”、“熟悉常见的网络协议如HTTP、TCP/IP等”
  • 衡量一下自己的技能点是“了解”、“熟悉”、“精通”的哪一种,别以为会用就可以写“精通”,真的很容易被怼。
    • 反例:“精通Java编程语言”
    • 正例:“熟练掌握Java语言,理解OOP思想,了解Java8的Lambda表达式、Java9的模块化等”

项目经验

  • 项目背景;
    • 大概讲项目是做啥的,太细节的东西可以到面试时再口述,简历上不要占篇幅
  • 你负责了哪些功能;
    • 注意:不是介绍这个功能的用途,而是你使用了什么技术完成了这个功能的设计、落地
  • 取得了哪些成果。
    • 性能、架构、优雅的代码实现等等


05
给小朋友的建议

前言

开发者的时间非常宝贵,选择合理的方向,才能调亮一棵较好的技能树。本文针对后端日常所需要的基础、进阶、工具、思想等,给出大致的学习优先级以及大概的学习方向。
(注:下面的建议不一定适合每一个人)

快速上手开发

此路线适用于刚入门的后端开发同学,涵盖了日常开发所需要的知识,大概掌握了以下技能,就大体能够尝试做一些小项目了。

考虑到此阶段的同学大多还是大一在知识深度和广度的抉择上,我认为广度优先级更高,应拓宽知识广度、构建知识体系。因此在下述思维导图中会涉及到其他的技能,如尽管工作室使用Java作为开发语言,但我会“语言”中提到其它语言。
(注:下文中带*号的表示,该知识点必须掌握,不带*号则作为知识扩展,不做硬性要求。)


进阶

此路线适用于已经能够完成日常工作的后端开发同学。

考虑到此阶段的同学大多是大二(即将大三),在下半年或者明年上半年会面临求职,因此在知识深度和广度的抉择上,我认为深度优先级更高,做到不仅知其然,也要知其所以然。

题外话

我在大一大二的时候,也有过很多学习方向上的迷茫,走了很多弯路。现在希望自己的一些分享,可以让后来者少走弯路。


点击[阅读原文]看完整文章,阅读效果更佳!

另外可领取20+优质简历模板和学习资料~