互联网提前批基本告一段落,大大小小的offer也拿了一些,秉着回报社会,坚持中国特色社会主义,挽救新一代码农的思想,整理了下各个公司的面筋、考点,希望能激励各位搬砖工,起到鼓足干劲,力争上游的作用O(∩_∩)O
干货
这货也不干,过去一整阵子了,我能写多少就给大家写多少吧,考点网上一搜一大把~
比如我面试之前搜到的这份:Java面试题及答案整理(2020版)
技术面
先说说技术面流程:
- 让你做自我介绍(准备好)
- 看看你简历,说你对这个比较熟?balabla...你问的简单就熟,问的难不好意思不太了解
- 看看你实习经历,让你介绍实习干啥了,有没有什么大项目能拿得出手,干聊10-20分钟的
- 问问职业规划。这里表现出你态度的虔诚,不会乱跳槽,踏踏实实的干,让他感受到你想进这家公司,两眼能放光就更好了... 大佬们可以海吹一波
- 你有啥子问题。我一般预备两个问题,您这部门具体做什么能介绍一下?我什么时候能知道自己是过了还是没过呢?尽量不要不问,各路大佬在贴中都说过了
一定要把主动权掌握在自己手中,面试官会问很多你平时不了解或压根不知道的问题,这时你可以说平时我用不到这些(可以理解啊,应届生上哪懂这么多邪门歪道啊,大佬请无视我),然后说自己对xxx领域有点研究,引导他来问你
对面提问你时,其实很考验你答辩技巧的,当你熟悉的东西时,那很OK,balabala即可,问你不熟悉的(你只知道点皮毛,但也在简历上写了),你可以说“我做项目时碰到过一点,大体查了下,有点印象,您可以试着问一下”,这样会让面试官把期望放低,问题难度也会降低,答出来加分,答不出来也无所谓
HR面
- 自我介绍(准备版非技术的! 从本科到大学,研究方向,选择这家公司理由,实习经历拉一拉,时间一般能凑够了,让对方感觉你是个健谈的人)
- 聊聊兴趣爱好(准备些健康的爱好,游戏公司可以考虑非健康的...)
- 聊聊实习经历,和上下级处的如何,有压力怎么办
- 你有啥问题。我对这部门还有些不了解,您能在系统介绍下吗?入职培训介绍一下?
下面具体拉拉各厂面试经历吧,我把比较有特色的问题列出来,统一的我放在下面知识点了,重写太麻烦了...
腾讯
难度:easy,可能我比较幸运?
一面
电话面,问了问Java的基础问题,其中有印象的是
- final这个字段用在字段和方法上的区别,在方法上好像能加速,大家自己查吧。。
二面
现场面,基本围绕着你简历上问
- xgboost相对gbrt改进
- topK问题
三面
总监面,这面基本聊聊实习的项目,用到的技术等,不知死活的我问了问sp的问题...建议各位0-offer党(offer满天飞的大佬请无视我)不要在该环节问sp的问题,最后给不给sp,好像不是这伙计定的,具体还是看聊得情况,聊开了什么都能聊,聊不开,那就88
美团
难度:normal
一、二面
- Java问了一堆
- Spark问了一堆
- 然后给我介绍部门,我基本在听他说了...
后面知识点都有我就不展开写了o_o ....
三面
问我刷题不?(这想要我什么回答呢),杯子倒水智力题,实习项目聊一聊
360
难度:normal+
一面
上来怼了我一堆python的东西,我python当脚本用的,说能不能换个方向聊一聊,然后怼了一堆
- 期望
- 准确率召回率
- AUC和ROC
- 决策树聊一聊
- 阐述自己如何设计模型的
开始问题偏向于算法,后来我说我其实擅长架构类的东西...小姐姐说,这样啊,不过看你答的还可以啊,架构我就不问你了...
二面
问了些数据仓库的问题,雪花型和星型数据库等,我表示一脸懵逼,然后和他扯Spark Streaming,他对这个还挺感兴趣的,算是晃点住了,后面说加班怎么看,然后他开始介绍他NB的团队,我开始瞻仰,膜拜...最后问问能不能来实习,基本回答都是能(不能的好像都没了...),时间节点自己需要把握一下,最好等到所有offer都下来的时候,我自己预估是10月中旬吧
头条
难度:father
一面
- spark streaming 怼一波
- 如何保证exactly once
- tcp中全连接池和半连接池等
- 剑指offer上一道题:二叉树蛇皮走位??
二面
- yarn 调度算法
- 扯了扯spark streaming
- 一道算法,树中两节点找最亲的爸爸...
- 实习聊一聊
面试官不是很感冒,问我还有什么补充了,我竟然说没...猝,血淋淋的教训啊
搜狗
难度:hard
一面
两个面试官,发了张卷子,里面什么题都有:
- 排序、有重复的数组中查询某数的index,注意不要退化成o(N)的算法
- 在一棵树中查找两个节点的最近公共父节点(就是头条二面那道题)
- linux ? $# $0 等含义
- 智力题 50红 50黑 分配两袋子摸球问题
- n!后面有多少个0
- hdfs的基本操作
- 大数据处理问题,用spark处理下
二面
- 问我为啥不考虑读博?(学的太渣,感觉没有必要读...)
- 问我对前面面试官的看法(你要炒他们吗。。。)
- 实习聊一聊
贝壳
难度:normal+
讲道理贝壳我是抱着去打小怪的心态去的,并没打算留下的,但是面试体验很好,最后给的薪水超高、福利也爆炸,缺点的话大家懂得,偏养老,看大家选择吧。算是帮一面的大哥打波广告吧
一面
数据倾斜怎么处理,我个人感觉我回答的比较差,以前没仔细思考过这个问题,后来查了查发现里面有很多道道。
但面试官很nice,问了问我其他方面,感觉还不错,后面和我讨论了30分钟的职业发展问题,感觉来的很值,大哥我能加你微信吗...
二面
比较年轻的高冷小哥面我的
- Spark架构
- shuffle过程
- Spark Streaming 原理
- 一道关于棋盘左上角跑到右下角的问题,从搜索、dp、到数学的方法都讨论了一遍
- 机器学习捎带说了一嘴
- 实习聊了聊
题外话
写给需要的,不想死磕互联网的人:ヽ(。◕‿◕。)ノ
- 读博真的不错,大家可以考虑下,真的是条出路,尤其你比较年轻的话
- 户口互联网不可兼得,最近在考虑户口唉
- 国企、银行、公务员都可以考虑啊,感觉这类工作有空陪家人
知识点
最后,送上我面试过程中整理出的知识点(可能有误-_-||),供大家查漏补全,希望大家都能找到个好offer (@^0^@)
Java
线程并发
这就是一天坑,基本问不完,难度也是拉满的那种...
Q:进程和线程的区别?
- 进程是资源分配的基本单位,线程是程序执行的最小单位
- 进程有独立的地址空间,线程依托于进程存在,线程切换的开销小
- 多进程组成的服务更稳定,一个进程挂了不会对另一个进程造成影响,相反,一个线程挂了,依托该进程的所有线程都会崩溃
Q:进程间通信方式?
- 管道
- 信号量
- 消息队列
- 共享内存(IPC)
- socket
核心目的是交换数据
除了会枚举,这些名词的具体概念也应该做到心中有数,传送门
Q:线程间通信方式?
- 锁机制
- 信号量
核心目的是同步
Q:Callable、Runnable区别?
- 核心区别 Callable 有返回值,Runnable 没有返回值
- Callable的方法是call(),而 Runnable的方法是run()
- Callable可以抛出异常,而 Runnable不可以抛出异常
Q:Future和Callable的关系?
- Callable执行完后会有一个返回结果,可以通过Future类返回(异步计算的结果)。
- 此外,应当了解下FutureTask,其实现了Runnable和Future,并存在接收Callable的构造函数
Q:创建线程的方法?
- 继承Thread,再通过Thread的start()
- 实现Runnable,再通过new Thread(runnable)包装后,start()
- 用ExecutorService提交
Q:volatile关键字的作用?
- 防止指令重排(单例模式中)
- 内存可见性
Q:synchronized的用法?
- 修饰实例方法,作用于当前对象,两个不同对象不冲突
- 修饰静态方法,作用于当前类,两个不同对象也冲突
- 修饰代码块,对指定对象加锁
Q:讲一下Java内存模型?
网上一大堆,引用前人的清明上河图
Q:CountDownLatch和CyclicBarrier了解吗?
- CountDownLatch中一个线程等待其他几个线程完成。
- CyclicBarrier中几个线程相互等待某一事件的达成。
- CyclicBarrier可以复用。
Q:Semaphore用法?
控制一组资源的使用,通过acquire()和release()获取和释放这组锁,盼盼防盗门
Q:ThreadLocal作用?
修饰变量,控制变量作用域,使变量在同一个线程内的若干个函数中共享。
Q:单例与多例的区别?
- 单例非static和static变量都是线程不安全的
- 多例非static变量是线程安全的,但static变量依旧是线程不安全的
- 可以通过synchronized或ThreadLocal来完成static变量的线程安全
Q:锁释放的时机?
- 执行完同步代码块后
- 执行同步代码块途中,发生了异常,导致线程终止
- 执行同步代码块途中,遇到wait关键字,该线程释放对象锁,当前线程会进入线程等待池中,等待被唤醒
Q:notify唤醒时机?
notify后不会立刻唤醒处于线程等待池中的线程,而是等当前同步代码块执行完,才释放当前的对象锁,并唤醒等待线程。
Q:notify和notifyAll区别?
notify通知一个线程获取锁,而notifyAll通知所有相关的线程去竞争锁
Q:讲一下Lock?
Lock是为了弥补synchronized的缺陷而诞生的,主要解决两种场景
- 读写操作,读读不应该互斥
- 避免永久的等待某个锁
Lock是一个类,并非Java本身带的关键字,相对于synchronized而言,需要手动释放锁。
Q:锁的种类?
- 可重入锁,如ReentrantLock
- 可中断锁,lockInterruptibly()反应了Lock的可中断性
- 公平锁,synchronized是非公平锁,Lock默认也是非公平锁(可调整)
- 读写锁,如ReadWriteLock
集合
集合相对容易,常规送分题,基本都会问到HashMap
Q:TreeSet特性?
内部元素通过compare排序。
Q:LinkedHashMap特性?
内部有个双向链表维护了插入key的顺序,使得map能够依据插入key的顺序迭代。
Q:ArrayList与Vector的差别?
ArrayList是非线程安全的,Vector是线程安全的。
Q:LinkedList与ArrayList的差别?
- LinkedList基于链表,ArrayList基于数组
- LinkedList没有随机访问的特性
- ArrayList删除添加元素没有LinkedList高效
Q:HashMap与HashTable的差别?
- HashTable线程安全,HashMap线程不安全
- HashMap允许null key和value,而HashTable不允许
Q:Set与List的差别?各自有哪些子类?
Set不允许重复元素,List允许重复元素,List有索引
- Set:HashSet、LinkedHashMap、TreeSet
- List:Vector、ArrayList、LinkedList
Q:hashCode()、equals()、==区别?
- equals 比较两个对象是否相等,若相等则其hashCode必然相等
- 若两个对象的hashCode不等,则必然不equals
- ==比较内存地址,比较是否是同一对象
Q:Java容器中添加的对象是引用还是值?
引用
Q:Iterator和ListIterator的区别?
- ListIterator 能向前遍历,也能向后遍历
- 可以添加元素
- 可以定位当前index
Q:HashMap实现?
内容巨多,引用大佬面经,值得一看,目录供大家参考
- hashing的概念
- HashMap中解决碰撞的方法(拉链法)
- equals()和hashCode()的应用,在HashMap中到底如何判断一个对象有无
- 不可变对象的好处
- HashMap多线程的条件竞争
- 重新调整HashMap的大小
PS:HashSet是通过HashMap实现的
Q:ConcurrentHashMap和HashTable区别?
- HashTable通过synchronized来实现线程安全
- ConcurrentHashMap通过分段锁,仅锁定map的某一部分
GC
这块主要介绍JVM内存的划分以及GC算法
Q:什么是内存泄漏和内存溢出?
- 内存泄漏:无法释放已申请的内存空间,一次内存泄露危害可以忽略,但堆积后果很严重,无论多少内存,迟早会被漏光。
- 内存溢出:没有足够的内存空间供其使用。
内存泄漏最后会导致没有足够的空间分配对象,从而导致内存溢出,当然也可能开始分配过大的对象导致内存溢出
Q:导致内存溢出的因素?
- 内存中加载的数据量过于庞大,如一次从数据库取出过多数据。
- 集合类中有对象的引用,使用完后未清空,使得JVM不能回收。
- 代码中存在死循环或循环产生过多重复的对象实体。
- 启动参数内存值设定的过小。
Q:JVM内存划分?
- 堆:对象
- 方法区:类、静态变量和常量
- 栈:局部变量表
基本说出上面三条就可以了,更详细的见下图,前门
Q:简单说一下垃圾回收?
这可不简单...
垃圾定义:
- 引用计数法:循环引用会bug
- 可达性算法:GC Roots,如 栈中的引用对象、方法区静态、常量对象、本地方法区内的对象,不在堆中就可以
堆中内存分布:
- 新生代(33%):小对象,Eden:From Survivor:To Survivor=8:1:1
- 老年代(66%):大对象、长期存活的对象
- 永生代(三界之外):通常利用永生代来实现方法区
垃圾回收算法:
- 标记清除算法
- 复制清除(新生代)
- 标记整理清除(老年代)
Q:Minor GC、Major GC和 Full GC的区别?
- Minor GC是对新生代做垃圾回收
- Major GC是对老年代做垃圾回收
- Full GC是对整个堆做垃圾回收
Q:Full GC触发时机?
- System.gc(),并非一定触发,只是建议
- 老年代空间不足(核心触发点,其他方案都是从这里衍生出来)
- 永生代空间不足(当将方法区放在永生代中时)
- Minor GC后晋升到老年代中的大小>老年代剩余空间(其实就是2.老年代空间不足的一种表现)
- 堆中分配大对象(大对象可以直接进入老年代,导致老年代空间不足)
Q:什么是常量池?
常量池分为静态常量池和运行时常量池。
- 静态常量池:指的是在*.class文件中的常量池
- 运行常量池:指的是将*.class文件中的常量装载到内存中方法区的位置(当方法区放在永生代时,也可以理解为内存中的永生代)
包含的信息:
- 字符串字面量
- 类、方法信息
该问题一般会引出字符串常量比较
String s1 = "Hello";
String s2 = "Hello";
String s3 = "Hel" + "lo";
String s4 = "Hel";
String s5 = "lo";
String s6 = s4 + s5;
String s7 = "Hel" + new String("lo");
String s8 = new String("Hello");
String s9 = s8.intern();
System.out.println(s1 == s2); // true,直接取自常量池
System.out.println(s1 == s3); // true,在编译时会优化成常量池内字符串的拼接,区别 s6
System.out.println(s1 == s6); // false,本质上是变量拼接,区别 s3
System.out.println(s1 == s7); // false,含有对象 new String("lo")
System.out.println(s1 == s8); // false,对象与字符串常量比较
System.out.println(s1 == s9); // true,字面量比较
类加载
面试时有人问到过,回去大概查了下
Q:讲一下类加载过程?
-
加载:将*.class文件通过各种类加载器装载到内存中
-
链接:分为三步
- 验证:保证加载进来的字节流符合JVM的规范,我理解成语法上的验证(可能不严谨)
- 准备:为类变量(非实例变量)分配内存,赋予初值(该初值是JVM自已约定的初值,非用户自定义初值,除非是常量,用final static修饰的)
- 解析:将符号引用替换成直接引用(A.a()=> 某一内存地址)
-
初始化:对类变量初始化,执行类变量的构造器
Q:Java初始化顺序?
这是在爱奇艺碰到的一面试道题,当时差点两眼一抹黑过去了...头一次发现这么多东西要初始化
- 一个类中初始化顺序(先类后实例)
类内容(静态变量、静态初始化块) => 实例内容(变量、初始化块、构造器)
- 继承关系的两个类中初始化顺序(先类后实例,再先父后子)
父类的(静态变量、静态初始化块)=> 子类的(静态变量、静态初始化块)=> 父类的(变量、初始化块、构造器)=> 子类的(变量、初始化块、构造器)
Q:Java类加载器的种类?
- 启动Boostrap类加载器:加载路径<JAVA_HOME>/lib
- 扩展Extension类加载器:加载路径<JAVA_HOME>/lib/ext
- 系统System类加载器:加载路径 -classpath
Q:双亲委派模式了解吗?
我理解的深度比较浅,个人理解,委派就是加载类时先看上层加载过没,如果加载过了,当前就不加载了,直接使用当成加载器加载的类。
其次是加载顺序,System->Extension->Boostrap
优点:
- 避免重复加载类
- 核心API不会被改动
面向对象
这些问题很弱鸡,但考的也比较多
Q:面向对象的三大特性?
顺口溜一般的背出来:封装、继承、多态
然后会让你讲讲这三个特性如何体现,大家自己想想吧,言之有理即可
Q:Java中接口和抽象类区别?
- 可以实现多个接口(implement),但只能继承一个抽象类(extend)
- 接口中的方法不能实现,抽象类中可以实现部分方法
- 接口中数据全是public static final类型的,方法全是public abstract的
- 本质上,接口是说对象能干什么,抽象类是说对象是什么
Q:重载和重写?
猪脑子,老记混
- 重载:同一个类中,函数名一样,但接受的参数一定不同,返回的结果可以不同
- 重写:不同类中,函数名一样,参数一样,结果也一样
设计模式
Q:例举一下你了解的设计模式?
一般说5、6个,有个样例就行了
- 组合模式:集合的addAll
- 装饰者模式:stream的各种嵌套
- 抽象工厂:JDBC中driver创建新连接
- 建造者模式:StringBuilder或SQL中PreparedStatement
- 责任链:structs2中对请求的处理各种Filter
- 解释器:正则表达式
- 观察者:swing中的事件监听各种Listener
Q:手撸单例?
撸完,让你讲讲内部细节,volatile或多例问题
public class Singleton {
private volatile static Singleton singleton;
private Singleton(){}
public static Singleton getSingleton(){
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
网络协议
Q:TCP3次握手4次挥手?
基本画张图就K.O.了,fate门,内部的问题也建议看一下
Q:TCP为什么是一定要是3次握手,而不是2次或3次以上?
2次挥手的问题
在第1次建立过程中,client请求链接在网络中滞留过久,导致client发送第2次请求,建立完毕后,这时第1次的请求到达server,server接收又维护一链接,但该链接实际上已经作废,浪费了server端的资源。
3次以上的方案
理论上,做到3次以上是可行的,但真正想做到一个完美可靠的通信是不可能的,因为每次答复都是对上次请求的响应,但该次答复在不可靠的信道中仍是会丢失的,考虑到现实效率问题,3次足以。
Q:TCP为什么是4次挥手,而不是3次呢?
- 握手的第二次携带了,响应ACK和请求SYN信息
- 挥手过程中不能一次性携带这两种信息,因为server方可能还有数据没传输完。
Q:TCP半连接池与全连接池?
- 半连接池:接受client握手第一步请求时,将该次链接放到半连接池中,Synflood的主要攻击对象
- 全连接池:接受client握手第二步请求时,将该次链接从半连接池中取出放到全连接池中。
Q:TCP和UDP的区别?
- TCP基于连接,而UDP基于无连接
- TCP由于有握手和挥手的过程消费资源相对较多
- TCP是传输数据流,而UDP是数据报
- TCP保证数据正确性和顺序性,而UDP可能丢包,不保证有序
Q:TCP和UDP的应用?
- TCP:FTP、HTTP、POP、IMAP、SMTP、TELNET、SSH
- UDP:视频流、网络语音电话
Q:TCP/IP与OSI模型?
TCP/IP模型,自下而上
- 链路层
- 网络层(IP、ICMP、IGMP)
- 运输层(TCP、UDP)
- 应用层(Telnet、FTP)
OSI模型,自下而上
- 物理层
- 数据链路层
- 网络层
- 运输层
- 会话层
- 表示层
- 应用层
Q:ping命令基于哪种协议?
ICMP
Q:阻塞式和非阻塞式IO区别?
阻塞式
- 每来一个连接都会开启一个线程来处理,10个线程对应10个请求
- 线程大多时候都在等在数据的到来,浪费资源
- 适合并发量小,数据量大的应用
非阻塞式
- 基本思想,将所有连接放在一张table中,然后轮询处理
- 实现上可以用事件通知机制,可以用10个线程处理100个请求
- 适合并发量大,数据量小的应用
数据库
用数据库做过开发,但是了解的不深入,面试问我会不会写SQL时,我多答“简单的可以,复杂的尝试一下”...SQL复杂起来真不是人写的...
Q:聚集索引和非聚集索引区别?
- 聚集索引:叶子节点是实际数据,表中只能有一个聚集索引
- 非聚集索引:叶子节点是地址,需要再跳转一次,表中可以有多个非聚集索引
Q:where、group by、having执行顺序?
- where 过滤行数据
- group by 分组
- having 过滤分组
Q:星型、雪花结构?
- 星型:存在部分冗余
- 雪花:表切分的十分细,没有冗余
Q:SQL纵向转横向,横向转纵列?
基本上,除了 group by + 聚集函数 外,这是最难的 SQL 题了
- 纵向转横向
sum(case when A='a' then B else 0 end) as D
这里需要用sum或其他聚集函数,因为作用在一个group中
- 横向转纵向
核心用union
记住这两条做到举一反三就可以了,Demo
Q:脏读、不可重复读、幻读?
- 脏读:事务A读取了事务B提交的值
- 不可重复读:事务A两次读取了事务B的值,事务B在该过程中修改并提交过,导致A两次读取值不一致
- 幻读:事务A修改 a 到 b ,事务B在该过程中添加了新的a,导致新添加的a,没有修改成b
这引出事务隔离级别
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(read-uncommitted) | 是 | 是 | 是 |
不可重复读(read-committed) | 否 | 是 | 是 |
可重复读(repeatable-read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
Q:join实现的三种方式?
- nested loops:嵌套迭代,相当于两个for循环,内部表有索引时,效果较好
- merge join:将两表先sort(如果没sort的话),再合并
- hash join:将表hash,然后扫描另一表
Linux
Q:查看xxx端口占用?
- netstat -tunlp |grep xxx
- lsof -i:xxx
Q:查看xxx进程占用?
- ps -ef |grep xxx
Q:查看CPU使用情况?
- top
Q:查看内存使用情况?
- free
- top
Q:查看硬盘使用情况?
- df -l
Q:$0、$n、$#、$*、$@、$?、?含义?
变量 | 含义 |
---|---|
$0 | 当前脚本的文件名 |
$n | 传递给脚本的第n个参数 |
$# | 传递给脚本的参数个数 |
$* | 传递给脚本所有参数 |
$@ | 传递给脚本所有参数。与$*有小差别,出门下扒 |
$? | 上个命令的退出状态 |
? | 当前Shell进程ID |
Q:>、>>区别?
- >:重定向到一个文件
- >>:追加到一个文件
Q:>、1>、2>、2>&1、2>1区别?
- >:默认是正确输出到某一文件,错误直接输出到控制台
- 1>:正确输出
- 2>:错误输出
- 2>&1:将错误输出重定向到正确输出中,一般前面会有 1> a.txt,这样后面的错误也会输出到 a.txt,通过正确输出
- 2>1:错误输出到 1 文件中,错误写法,区分&1
Q:定时任务命令?
- crontab
算法
算法的海洋的无边无际,但是应付面试题的算法,个人认为《剑指offer》一本足矣...
个人《剑指offer》刷了大概四遍,基本上看到一道题,所有解法都知道,面试上也基本从这里出
我遇到现场出的算法题(除了《剑指offer》上的),一般是暴力搜索题,不要上来想DP...
经典问题
- 子串匹配问题
- 子序列匹配问题
- 合并链表
- 树中两个节点最近的公共父节点
- 快排、堆排
- 各种类型的二分查找
- 两数交换,不用第三变量
- 水塘抽样,大佬题解
智力题
- 一根棍子随机折三节,组成三角形的概率
- 倒水问题
- 面粉称重问题
- 烧绳子问题
最后
如果本文对你有帮助的话,麻烦给博主点一个小小的赞,祝各位都能拿到心仪的offer~