面试一般是多个面试官,但是总时长很短
  • 研究所:测评+面试
  • 银行:笔试+面试+体检(笔试题量很大)
比较看重:
  1. 学历和专业
  2. 本科成绩+研究生成绩
  3. Cet-4和Cet-6
  4. 奖项、论文、专利等
面试侧重:
  1. 简单的专业知识
  2. 项目+论文/专利

1-西安-农行-研发

笔试

  1. 80道选择题(40min):数据库知识点+数据库代码+计算机网络+数据结构+Java/C
  2. 10道行测题(10min):数学计算+逻辑运算
  3. 3道编程题(90min):很简单的三道阅读理解编程题

面试(只有一次面试)

腾讯会议,进去有6个面试官,大概10分钟左右
1.自我介绍
简单自我介绍,编号代替名字,但是可以报学校
2.final finally finalize区别
  1. final可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示该变量是一个常量不能被重新赋值。
  2. finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码放到finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。
  3. finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调用,当我们调用System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾,一个对象是否可回收的最后判断。
3.讲一下知道的数据结构
  • 线性结构:数组、线性表、栈和队列
  • 非线性结构:二维数组、树、图、堆
4.BFS用的是什么数据结构?递归用的是什么数据结构
BFS(图的广度优先遍历):队列;
DFS(图的深度优先遍历):递归(底层是通过栈实现的);
5.怎么判断一个对象是否可以被回收?
1.引用计数法
给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0 的对象就是不可能再被使用的。
这个方法实现简单,效率高,但是目前主流的虚拟机中并没有选择这个算法来管理内存,其最主要的原因是它很难解决对象之间相互循环引用的问题。
2.可达性分析算法
这个算法的基本思想就是通过一系列的称为 “GC Roots” 的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连的话,则证明此对象是不可用的。
可作为 GC Roots 的对象包括下面几种:
  • 虚拟机栈(栈帧中的本地变量表)中引用的对象
  • 本地方法栈(Native 方法)中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 所有被同步锁持有的对象
6.Minor GC和Full GC的区别
  • 新生代 GC(Minor GC):指发生新生代的的垃圾收集动作,Minor GC 非常频繁,回收速度一般也比较快。
  • 老年代 GC(Major GC/Full GC):指发生在老年代的 GC,出现了 Major GC 经常会伴随至少一次的 Minor GC(并非绝对),Major GC 的速度一般会比 Minor GC 的慢 10 倍以上。
如果对象在 Eden 出生并经过第一次 Minor GC 后仍然能够存活,并且能被 Survivor 容纳的话,将被移动到 Survivor 空间中,并将对象年龄设为 1.对象在 Survivor 中每熬过一次 MinorGC,年龄就增加 1 岁,当它的年龄增加到一定程度(默认为 15 岁),就会被晋升到老年代中;
7.讲一下Java中的内存泄漏
内存泄漏是指不再被使用的对象或者变量一直被占据在内存中。理论上来说,Java是有GC垃圾回收机制的,也就是说,不再被使用的对象,会被GC自动回收掉,自动从内存中清除。
但是,即使这样,Java也还是存在着内存泄漏的情况,java导致内存泄露的原因很明确:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的发生场景。

内存泄漏达到一定程度会引发OOM
内存泄漏是指编写的代码中含有bug,不是指会引发程序执行结果错误那种,而是不可达的对象停留在堆中,即代码中含有对象的强引用没有没释放掉,导致该无用的对象无法被垃圾收集器收集。
假设内存足够大,而内存泄漏的情况并不严重,只要还有足够的空间分配给新的对象,那样即使内存泄漏也不会引发OOM。
注意:程序计数器不会出现OOM
  • Java堆溢出
java.lang.OutOfMemoryError: Java heap space
堆空间无法给新的对象分配内存空间且GC一次后仍然无法分配足够的空间时会导致堆溢出。
  • 栈溢出
java.lang.StackOverflowError
这是由于线程请求的栈深度大于虚拟机所允许的最大深度,无法压入新的栈帧,这时可以检查一下代码中是否存在死循环的递归调用。
  • 方法区溢出
java.lang.OutOfMemoryError: PermGen space
这里还可以分为运行时常量池溢出和方法区存放Class过多导致溢出。过去的话方法区的大小是设定好的,Java8之后将Class信息放到了元空间,并且元空间是可以动态申请扩展的,详细的描述小伙伴可以自行搜索永久代到元空间的相关博客。
  • 无法创建新进程
java.lang.OutOfMemoryError:unable to create natvie thread
就是栈空间不足了无法创建新的进程。
8.疯狂怼项目

体检 && 签约

去体检,要去研发中心就压学位证和签两方,违约金2w,所以没签约;
农行比较早,所以大佬还是比较多,所以拿了offer不去的人非常多,如果刚开始没有被捞也不用担心,后面有非常大的概率会被捞,感觉前面签的人并不多;

2-南京-中电28所

一面 技术面

腾讯会议,全程25分钟,无技术问题,就是聊天
1.自我介绍
2.讲一讲项目,取得的效果?
3.问成绩?
4.为什么来南京?
5.问了项目中的一些问题?
6.为什么不投南瑞,南瑞也招开发呀?
项目是和南瑞合作的,所以面试官问了这个问题
7.对中电28所有什么了解的?
8.反问:面试官讲了自己工作

二面 HR面

线下:聊天

3-南京-南瑞国家电网

一面 腾讯会议

腾讯会议,全程7min,3位面试官:2个技术+1个HR
1.自我介绍?
2.聊项目?
3.项目难点?
4.懂电力知识吗?
不会,学的都是计算机相关的,只是南瑞合作项目了解过电网的知识
5.怎么看待加班?
6.面试官讲南瑞的福利(讲了3min)

二面 电话聊薪资

按照学校开薪资、福利待遇,说的是有电网编制

4-洛阳-中航613所

一面(线下):收个材料,看了看成绩单,面试官说自己不是学计算机的,后面会有人电话联系;
二面(电话):洛阳座机打过来的,应该是计算机专业的面试官,问的都是简历上写的八股(简单部分),大概15分钟左右;
三面(线下):简单聊了聊,让直接签两方,但是才9.7,太早了,就放弃了
1.介绍项目,会桌面级界面开发相关的吗?Qt之类的?
用过Qt
2.数据库的事务定义?举个自己实际用过的例子
事务是逻辑上的一组操作,要么都执行,要么都不执行。
事务最经典也经常被拿出来说例子就是转账了。假如小明要给小红转账1000元,这个转账会涉及到两个关键操作就是:将小明的余额减少1000元,将小红的余额增加1000元。万一在这两个操作之间突然出现错误比如银行系统崩溃,导致小明余额减少而小红的余额没有增加,这样就不对了。事务就是保证这两个关键操作要么都成功,要么都要失败。
3.都知道哪些排序算法?对比一下
各大排序算法:https://www.nowcoder.com/discuss/807448?source_id=profile_create_nctrack&channel=-1

4.什么是死锁?四个必要条件
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
● 互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
● 请求与保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
● 不可剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能 由获得该资源的进程自己来释放(只能是主动释放)。
● 循环等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。若干个进程间形成了首尾相接循环等待资源的情况
5.Java和C++的区别
  1. 都是面向对象的语言,都支持封装、继承和多态
  2. Java不提供指针来直接访问内存,程序内存更加安全
  3. Java的类是单继承的,C++支持多重继承;虽然Java的类不可以多继承,但是接口可以多继承。
  4. Java有自动内存管理机制,不需要程序员手动释放无用内存
6.如何理解面向对象?面向对象的特性?
  1. 面向对象是模型化的,你只需抽象出一个类,这是一个封闭的盒子,在这里你拥有数据也拥有解决问题的方法。需要什么功能直接使用就可以了,不必去一步一步的实现,至于这个功能是如何实现的,管我们什么事?我们会用就可以了。
  2. 面向对象的底层其实还是面向过程,把面向过程抽象成类,然后封装,方便我们使用的就是面向对象了。
抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。
  • 封装:把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供方法给外界访问。但是如果一个类没有提供给外界访问的方法,那么这个类也没有什么意义了。
  • 继承:是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便地复用以前的代码。
  • 多态:所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定