版权声明:本文为 冬夏 原创文章,可以随意转载,但请注明出处。
谨以此篇文章,纪念我的漫漫求职路。
掐指一算,从今年3月份开始复习准备实习生招聘,到10月底秋招正式结束,经历了半年的坎坷求职路。还好,结果还算满意,也想把这段时间的面试经验、总结和个人的一些看法分享给大家,希望大家都能找到满意的工作。
截至到目前为止,投过简历的公司有:
阿里巴巴,腾讯,百度,网易,网易游戏,华为,美团,CVTE,4399
面试过的公司有:
阿里巴巴,腾讯,网易游戏,华为,美团,4399
拿到offer的公司有:
阿里巴巴,网易游戏,美团,4399
文章主要内容
- 面试过程中遇到的问题及简要答案
- 每次面试后的总结
- 校招总结及建议
面试过程中遇到的问题及简要答案
Java相关
Q1:Java内存模型(4399)
A1:堆、栈、方法区,程序计数器
Q2:Java如何实现垃圾回收(4399、阿里巴巴)
A2:典型的垃圾回收算法包括
- Mark-Sweep(标记-清除)算法
优点:效率高,实现简单
缺点:产生内存碎片 - Copying(复制)算法
优点:实现简单、不容易产生内存碎片
缺点:可使用内容变为原来一半 - Mark-Compact(标记-整理)算法
优点:不容易产生内存碎片
缺点:,复杂、耗时 - Generational Collection(分代收集)算法
JVM根据对象存活时间将内存划分为永久代,老年代,新生代。- 新生代垃圾回收算法:Copying(复制)算法
- 老年代垃圾回收算法:Mark-Compact(标记-整理)算法
- 永久代:垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全垃圾回收
(注: Java8中已经移除了永久代,新加了一个叫做元数据区(meta data)的native内存区)
- Mark-Sweep(标记-清除)算法
Q3:Java发生垃圾回收时程序会怎么样(阿里巴巴)
A3:stop the world
Q4:Java线程同步的几种方式(网易游戏)
A4:- 同步方法
- 同步代码块
- wait与notify
- volatile
- 重入锁
- ThreadLocal
- 阻塞队列
Q5:一行代码从写完到执行过程中经历了什么?(阿里巴巴)
A5:编译-加载-校验-准备-解析-使用-卸载
Q6:HashMap 和 HashTable的区别(阿里巴巴)
A6:- HashMap非线程安全、HashTable线程安全
- 支持key和value为null 不支持支持key和value为null
- HashMap在JDK1.8之后当链表长度大于8时自动转为红黑树,小于6转回来(设定两个阈值是为了不频繁发生转换)
Q7:Concurrenthashmap和Hashtable的区别(网易游戏)
A7:效率高:Concurrenthashmap锁的粒度(一个桶)比Hashtable(整个结构)小Q8:创建线程的方法(阿里巴巴)
A8:
- 继承Thread类
- 实现Runnable接口
- 应用程序可以使用Executor框架来创建线程池
- Q9:线程池的种类及区别(网易游戏)
A9:- Executors.newFixedThreadPool(nThreads):可重用的,固定线程数的线程池
- Executors.newCachedThreadPool():根据需要创建线程
- Executors.newSingleThreadExecutor():单个线程的线程池,特点:如果线程执行过程中被kill,会重新生成一个线程
- Executors.newScheduledThreadPool(corePoolSize):可以调度的线程池,可以在指定延迟之后执行
Q10:Java异常(4399)
A10:Java的两种异常:checked异常和runtime异常,区别- checked异常:调用方法需捕获,定义方法需声明
- runtime异常:调用方法不需捕获,定义方法不需声明
Q11:Java里引用的类型和区别(阿里巴巴)
A11:
- 强引用(Strong References)
强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。(注:强引用其实也就是我们平时A a = new A()这个意思) - 软引用(SoftReference)
用来实现一些内存敏感的缓存(Soft references are for implementing memory-sensitive caches),只要内存空间足够,对象就会保持不被回收。反之,当宿主进程的内存空间不足时,对象就会被GC回收。所以SoftReference意味着:hold on until you can’t. - 弱引用(WeakReference)
可以用来实现一些规范化映射(WeakHashMap),其中key或者value当它们不再被引用时可以自动被回收。当你想引用一个对象,但是这个对象有自己的生命周期,你不想介入这个对象的生命周期,这时候你就是用弱引用。这个引用不会在对象的垃圾回收判断中产生任何附加的影响。 - 虚引用(PlantomReference)
与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。
- 强引用(Strong References)
Q12:Java类加载机制(阿里巴巴)
A12:
- 父类委托(双亲委托):先由父类加载器尝试加载该类,加载不成功时才尝试从自己的类路径中加载
- 缓存机制:加载过的类存放在方法区,这就是为什么修改了class,必须重启JVM才生效的原因
Q13:==、equals、hashcode的区别与联系(4399)
A13:
- ==表示两个变量指向同一个对象
- 覆盖equals一定要覆盖hashcode
- 两个equals相等的对象hashcode一定相等,反之不然
Q14:为什么String要设计成不可变类(腾讯)
A14:
- 字符串常量池的需要
- 允许String对象缓存HashCode
- 安全性
Android相关
Q1:Android内存泄露情况分析(网易游戏)
A1:
- 单例造成的内存泄漏
- 非静态内部类创建静态实例造成的内存泄漏(非静态内部类默认会持有外部类的引用)
- Handler造成的内存泄漏(Handler的生命周期和Activity不同造成的)Handler发送的Message尚未被处理,则MessageQueue持有Handler的引用(post方法)。而Handler又持有Activity的引用
- 匿名内部类和线程造成的内存泄漏(匿名内部类持有外部类的引用,如果这时候将匿名内部类的引用传入一个异步线程,则有可能造成内存泄漏)
- 资源未关闭造成的内存泄漏
Q2:Android启动流程(腾讯)
A2:
Q3:Android动画的种类(美团)
A3:逐帧动画、补间动画、属性动画
Q4:ListView的优化(网易游戏,美团)
A4:
- 判断converView是否为空
- 使用ViewHolder保存View的各个Widget引用。避免每次都重新findViewbyId
Q5:View的绘制机制(腾讯)
A5:onMeasure()、onLayout()、onDraw()(这个问题很经典也很复杂,建议仔细研究)
Q6:Android的序列化方式(美团)
A6:Serializable、Parcelable
Q7:Activity的四种启动模式及其区别(阿里巴巴)
A7:
- standard:默认模式,在这个模式下,都会创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。
- singleTop:可以有多个实例,但是不允许多个相同Activity叠加。即,如果Activity在栈顶的时候,启动相同的Activity,不会创建新的实例,而会调用其onNewIntent方法。
- singleTask:只有一个实例。在同一个应用程序中启动它的时候,若Activity不存在,则会在当前task创建一个新的实例,若存在,则会把task中在其之上的其它Activity destory掉并调用它的onNewIntent方法。如果是在别的应用程序中启动它,则会新建一个task,并在该task中启动这个Activity,singleTask允许别的Activity与其在一个task中共存,也就是说,如果我在这个singleTask的实例中再打开新的Activity,这个新的Activity还是会在singleTask的实例的task中。
- singleInstance:只有一个实例,并且这个实例独立运行在一个task中,这个task只有这个实例,不允许有别的Activity存在。
Q8: Android从按下图标到应用启动的过程(腾讯)
A8:用户在Launcher程序里点击应用图标时,会通知ActivityManagerService启动应用的默认Activity,ActivityManagerService发现这个应用还未启动,则会通知Zygote进程孵化出应用进程,然后在这个dalvik应用进程里执行ActivityThread的main方法。应用进程接下来通知ActivityManagerService应用进程已启动,ActivityManagerService(绑定)保存应用进程的一个代理对象(applicationthread),这样ActivityManagerService可以通过这个代理对象控制应用进程,然后ActivityManagerService通知应用进程创建入口Activity的实例,并执行它的生命周期方法。
Q9:如何保证service在后台不被杀死(网易游戏)
A9:
- 设置1像素Avticity,监听锁屏广播,服务在另外进程减少主进程使用内存(5.0以后会一起杀死进程组,所以不适合)
- 设置前台服务,startForeground(降低kill概率)
- 粘性服务,在onStartCommand中设置成START_STICKY,kill之后会重启
- 捆绑系统服务
- 双进程Service相互守护
- 账号同步唤醒APP
- 全家桶相互唤醒
- JobSheduler
- native进程方式
- 设置高优先级(貌似无效)
- 应用拆分
Q10:为什么一定要在UI线程更新视图(阿里巴巴、腾讯)
A10:在移动设备中,UI的使用是绝对设备对于用户体验的重要因素之一。而Android系统当中的控件都不是线程安全的,这导致当使用多线程模式的时候在多个线程共同使用同一个UI控件时容易发生不可控的错误,而这是致命的。不过这里提一点的就是,在Activity的onResume执行之前,是可以在子线程里更新UI的,具体原因这里就不细讲了,有兴趣的可以自己去查。
Q11:Android进程间通信方式(美团)
A11:
- AIDL
- Broadcast
- ContentProvider
- Binder
- Intent
- Socket
Q12:IntentFilter和Intent的匹配规则(美团)
A12:Intent包括显式Intent和隐式Intent,显示Intent通过直接指定类名进行匹配。隐式Intent则与IntentFilter中的action、category、data进行匹配。
action匹配规则
- 一个intent-filter中可以有多个action
- intent中的action与intent-filter中有一个相同即可
- action区分大小写
category匹配规则
- Intent中可以不存在category,但如果存在就必须匹配intent-filter其中一个
- 系统在startActivity或者startActivityForResult的时候默认为Intent加上一个android.intent.category.DEAFAULT,所以必须在intent-filter中加上android.intent.category.DEFAULT这个category
data匹配规则
data由两部分组成,mimeType和URI。
URI格式:://:[||]
//示例
content://com.example.project:200/folder/subfolder/etcURI的scheme的默认值为content和file
minType指数据类型
匹配规则与action类似,只要有一个data匹配就可以
Q13:Android常用布局,Activity生命周期(腾讯)
A13:
常用布局:
- RelativeLayout
- FrameLayout
- LinearLayout
- AbsoluteLayout
- GridLayout
- TableLayout
生命周期:
Q14:Activity弹出Dialog会触发什么生命周期方法(腾讯)
A14:如果是当前Activity弹出的dialog则不会执行Activity任何生命周期中的方法,只有其它Activity弹出了Dialog或者拦住了当前的Activity才会执行onPause()
Q15:Handle、Looper、MessageQueue之间的关系(网易游戏、阿里巴巴)
A15:
Handler:
目的:线程间信息传递,比如非UI线程可以通过Handler发送信息到UI线程从而修改界面。
Handler在创建的时候绑定到创建它的线程和线程的消息队列MessageQueue
主要有两种使用方法:
- 通过post或者postAtTime发送Runable对象
通过sendMessage,sendMessageAtTime,sendMessageDelayed发送消息对象(Message),然后在Handler所在线程的handleMessage中处理(需要自己实现Handler的子类或者实现callback接口)。
当程序运行时,进程为主线程分配一个消息队列MessageQueue,负责处理activities,broadcast,receivers等对象和它们创建的窗口,你可以新建自己的线程,然后通过Hanlder和主线程进行交流。
Looper:每个线程只有一个Looper,不停地从MessageQueue中取消息出来处理,创建Looper对象的时候回创建MessageQueue对象(主线程系统为其创建了Looper,自己创建的线程必须调用Looper.prepare()创建Looper对象)
MessageQueue:先进先出消息队列
计算机基础
Q1:死锁的条件和避免方法(网易游戏)
A1:
- 互斥:一个资源每次只能一个线程使用
- 请求与保持:一个线程因请求资源而阻塞时,对已获得的资源保持不放
- 不可剥夺:线程已获得的资源,在未使用完之前,不可强行剥夺
- 循环等待:若干线程之间形成一种收尾相接的循环等待资源关系
防止死锁的手段
- 静态分配资源(破坏 请求与保持)
- 层次分配(破坏 循环等待)
死锁避免
- 避免线程永久地占有系统资源
- 防止进程在处于等待的情况下占用资源
Q2:线程和进程的区别(网易游戏)
A2:
- 进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动
- 进程是操作系统进行资源分配和调度的一个独立单位
Q3:Http/Https原理分析以及Https如何保证安全(网易游戏,腾讯)
A3:Https = Http + SSL,其实就是证书验证,公钥加密,私钥解密的整个流程,建议自己理解一下,常问
Q4:TCP为什么有四次挥手,但是只有三次握手(腾讯)
A4:因为SYN和ACK和并在一起了
Q5:TCP和IP的报文格式
A5:
IP报文格式:
TCP报文格式:
设计模式
Q1:常用的设计模式有哪些(美团)
A1:策略模式、观察者模式、装饰着模式、工厂模式、单例模式、外观模式、设配器模式、组合模式、状态模式,生成器模式等
Q2:单例模式怎么保证线程安全(网易游戏)
A2:恶汉模式、懒汉模式、双重检查锁机制、静态内置类、枚举类型
Q3:MVP、MVC、MVVM的区别和联系(美团)
A3:
MVC:
MVP:
MVVM:
算法
Q1:如何求一个数的平方根(网易游戏)
A1:牛顿法、平方根倒数速算法、平方根倒数速算法
Q2:判断一个整数链表是否存在环路(阿里巴巴)
A2:快慢指针
Q3:大数乘法(腾讯)
A3:模拟手工计算法,分治算法、FFT算法
Q4: 各种排序算法的比较(腾讯)
A4:
- 稳定排序
- 不稳定的排序
其他
Q1:自我介绍
A1:建议时长1-3分钟,介绍内容包括姓名、学校、专业、研究方向、对应聘岗位所需技能的熟悉程度、为什么要应聘这个岗位、相关项目等,兴趣爱好一般不介绍,介绍的时候要和面试管有互动。
Q2:你觉得你比别人优秀的一点是什么?
A2:选一个自己性格上的特点,不要选特长,而且要有例子说明你的这个优点对工作是有帮助的。比如应聘Android开发时说自己对技术很敏感,经常关注技术动态,并且对技术有自己的理解。
Q3:你的缺点
A3:建议选一个从一方面看是缺点,但是从另外一方面看又是优点的特点。比如说自己很纠结细节,因此浪费了不少时间,但是从另一方面看又表现了自己很认真仔细。
Q4:印象最深刻的一件事
A4:可以说和技术有关的或者和技术无关的,但是要体现出为什么这件事让你的印象那么深,比如让你明白了什么道理等。
Q5:还有什么问题问我
A5:这个问题一般都是最后一个问题,一般可以问职业上的困惑,比如对前景的看法、对某向新技术的看法、咨询岗位工作内容、或者问自身的不足、之前回答不上的问题的思路等,要让面试官觉得你很重视这份工作,同时体现出自己很好学、上进。
每次面试后的总结
春招
网易游戏内推 一面挂
面试总结:网易游戏是实习里面面得最早的,当时准备得并不好,所以挂了也很正常,出网易大厦的时候也没有觉得不开心,只想着抓紧复习准备其他的面试。
华为 录用池挂
面试总结:华为的面试是面试过的所有公司里面最看不透的。面试基本不问基础知识,问项目也都是自己在说,没有追问细节,总体来说就是缺少互动。面试通过率高得吓人,基本都是刷学校的。还好我是个例外,不然也不会有后面的故事了,感谢华为不录之恩。
腾讯内推 三面挂
面试总结:一面是电话面试,二面和三面是在腾讯总部面的。总体上来说表现得并不好,感觉腾讯非常注重底层原理和计算机网络,不是那种知道就行,还要知道为什么,这些没有长时间的积累和实际项目锻炼很难获取的知识。
阿里内推 四面挂
面试总结:全程电话面试,一面,三面,四面都面得还可以,就是最重要的二面面得不好。阿里巴巴非常注重对技术的理解,比如一个问题除了用一种方法解决还能用什么方法解决,还有就是如果笔试的题当时不会做,过后有没有再去思考。
腾讯校招 一面挂
面试总结:虽然是一面就挂了,但是面试官和我聊得还行,只是他问我如果让我做游戏我会怎么看,因为我觉得做游戏需要那种算法很厉害的人,当时我回答他说可能我的能力不够,所以就跪了。
4399 三面offer
面试总结:面试4399的时候,是我找实习最低落的时光。周围的人基本都找到实习了,只有我没有,很虚。虽然最后没有去4399,但是还是很感谢4399的面试官给了我肯定。
阿里校招 三面offer
面试总结:阿里的内推不通过就自动转校招了。当时我宿舍没有网络,所以三次视频面试都是在实验室面的。整个实验室的小伙伴包括导师都静静地听我和面试官吹水。面试阿里我觉得有两次让面试官眼前一亮的,一次是二面面试官问函数原理的时候我说出来了,让他惊讶了一下。还有一次是HR问我缺点的时候,我的回答让她表示了赞同。
秋招
网易游戏 四面offer
面试总结:网易游戏的招聘的时候指定了特定学校才能投简历,这样就限制了很多人了。虽然我是这个规定的受益者,但是我并不觉得这个规定好。面试的时候感觉网易游戏非常注重算法和基础。但是我的算法并不好,能拿到offer可能是因为我有了阿里的offer和有一些看法和面试官不谋而合把。
百度 放弃面试
面试总结:百度的面试通知来得非常晚,当时我已经拿了阿里和网易游戏的offer了,再加上百度的岗位在北京,所以就放弃了。
腾讯内推 一面挂
面试总结:接到腾讯的电话的时候我刚刚做上从杭州回广州的飞机,所以只能另外约时间。是微信部门打电话过来的,问了我阿里的项目,应用架构,开发遇到的问题,动态化框架的理解等。微信部门的要求很高,我也觉得我并没有达到他们的要求,不过还是感谢面试官。
美团内推 四面offer
面试总结:美团是通过同学内推的,一面是电话面试,二面、三面是视频面试,四面是电话面试。感觉美团很注重实战能力,二面的时候直接就给我一张截图让我分析布局。感觉美团在技术上的积累还是不错的,个人也看好美团的发展前景,只是因为岗位在上海,最终还是拒了。
腾讯校招 一面挂
面试总结:第四次面腾讯,我已经不抱希望了,果然,一面就挂了。不过还是感谢面试官给我指出了面试过程中的问题,不要带很多的语气词。
校招总结及建议
就我了解的情况来说,今年周围同学就业情况并不太乐观。虽然人工智能大火导致了相应的岗位需求量大增,而且工资开得都比较高,40w+的也经常听到。但是与人工智能有关的机器学习,深度学习,数据挖掘等岗位大多只招聘硕士和博士,而且每个公司招聘的数量并没有开发的人数多,而且有加速饱和的趋势。
如果你现在还没有选择方向,那么在选择人工智能之前要先考虑好以下几点
- 自己是真的喜欢和适合这个方向还是只是冲着高薪去的。如果你不是真的感兴趣,可能最后会很痛苦。
- 自己的数学水平,特别是概率论和矩阵分析水平怎么样。如果理论知识不够最后很可能会沦为调参工程师,只是重复地做着别人的实验。
- 不像做开发的门槛比较低,机器学习的从业人员大多具有比较高的学历和名校背景做背书,在这样的情况下要脱颖而出会比较困难,这点应该做好准备。
关于移动开发,现在的岗位需求量已经很小了,而且和前端的融合趋势已经很明显了。如果你没有基础,现在已经不建议学习移动开发了,性价比太低。当然,高端人才还是稀缺的,不管是对某个领域有比较深造诣的人才还是全栈人才。
关于后台,需求一直比较大,也比较稳定,技术更新换代对比移动端和前端也比较慢,如果你有兴趣,可以往后台发展。
最后,再次希望大家都能找到满意的工作!