2021.04.21牛客网Java校招面经汇总(1~12)

交行软开一面面经 遇见TA

1.Java的类加载机制**

解析:
https://gitee.com/SnailClimb/JavaGuide/blob/master/docs/java/jvm/%E7%B1%BB%E5%8A%A0%E8%BD%BD%E8%BF%87%E7%A8%8B.md

系统加载 Class 类型的文件主要三步:加载->连接->初始化。连接过程又可分为三步:验证->准备->解析。

(1)加载

①通过全类名获取定义此类的二进制字节流
②将字节流所代表的静态存储结构转换为方法区的运行时数据结构
③在内存中生成一个代表该类的 Class 对象,作为方法区这些数据的访问入口

(2)验证:

文件格式,元数据,字节码,符号引用验证

(3)准备阶段:

内存分配的仅包括类变量(static),而不包括实例变量,实例变量会在对象实例化时随着对象一块分配在 Java 堆中。

(4)解析阶段:

是虚拟机将常量池内的符号引用替换为直接引用的过程。解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用限定符7类符号引用进行。

(5)初始化:

是类加载的最后一步,也是真正执行类中定义的 Java 程序代码(字节码),初始化阶段是执行初始化方法 ()方法的过程。

(6)卸载:

卸载自定义加载器加载的类

携程后台一面面经 牛客705237269号

2.hashmap 和 hashtable 的区别**

https://www.jianshu.com/p/5c34133ed372
区别
①HashMap允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许。
②HashMap 把 Hashtable 的 contains 方法去掉了,改成 containsValue 和 containsKey。因为 contains 方法容易让人引起误解。
③HashTable 继承自 Dictionary 类,而 HashMap 是 Java1.2 引进的 Map interface 的一个实现。
④HashTable 的方法是 Synchronize 的,而 HashMap 不是,在多个线程访问 Hashtable 时,不需要自己为它的方法实现同步,而 HashMap 就必须为之提供外同步。
⑤Hashtable的enumerator迭代器不是fail-fast, HashMap则是fail-fast,因此当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException

3. hashtable 和 concurrenthashmap的区别***

https://www.cnblogs.com/heyonggang/p/9112731.html
①ConcurrentHashMap底层采用分段的数组+链表实现,
HashTable底层数组+链表实现
②concurrenthashmap线程安全通过把整个Map分为N个Segment,可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。(读操作不加锁,由于HashEntry的value变量是 volatile的,也能保证读取到最新的值。)
Hashtable的synchronized是针对整张Hash表的,即每次锁住整张表让线程独占,效率相对concurrenthashmap低下

注意:ConcurrentHashMap有些方法需要跨段,比如size()和containsValue(),它们可能需要锁定整个表而而不仅仅是某个段,这需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段的锁

4. stringBuilder ,StringBuffer的区别****

String类是不可变类,任何对String的改变都 会引发新的String对象的生成;(少量数据使用),线程安全,速度最慢
StringBuffer则是可变类,任何对它所指代的字符串的改变都不会产生新的对象,线程安全,适用多线程下在字符缓冲区进行大量操作的情况,效率仅次于stringBuilder
stringBuilder:适用单线程下在字符缓冲区进行大量操作的情况,线程不安全,效率最快

用法:https://blog.csdn.net/mad1989/article/details/26389541
StringBuffer sb = new StringBuffer(“KMing”);
sb. deleteCharAt(1);//删除序号为1字符,输出结果:King
StringBuffer sb = new StringBuffer(“TestString”);
sb. delete (1,4);//删除[1,4}字符,结果:TString
StringBuffer sb = new StringBuffer(“TestString”);
sb.insert(4,false);
该示例代码的作用是在对象sb的索引值4的位置插入false值,形成新的字符串,则执行以后对象sb的值是”TestfalseString”。

5. String 和 StringBuilder在合并字符串上的区别****

String:创建一个StringBuilder的存储空间,大小为第一个字符串的长度+16,之后创建新字符串1,添加至缓冲区…创建新字符串N,添加至缓冲区,最后将缓冲区对象转换为字符串对象
StringBuilder拼接字符串:①创建一个新的StringBuilder的存储空间
②.在StringBuilder的基础上进行添加,不创建新的字符串
③.循环完成之后,将StringBuilder转成String
https://blog.csdn.net/m0_46325925/article/details/110144790

字节后端开发一面面经【校招】牛客43800845号

6. 隔离具体是怎么实现的

根据快照版本号知道事务执行时间进而决定事务之后执行顺序。insert、update和delete会更新版本号

7. 操作系统怎么管理内存的

分为连续内存分配和非连续内存分配

一.连续内存分配:

给程序分配一块连续内存区域,会出现内/外部碎片,
内部碎片产生缘由:分配的内存大小是否要取整
外部碎片:被分配的内存区域之间没的的空闲区域

二.非连续内存分配:

连续内存分配会出现内/外部碎片、动态修改比较困难、内存必须连续,而且内存利用率不高。因此提出了非连续内存分配的方法,允许程序使用非连续的内存空间、允许共享代码和数据,以提高内存利用效率和管理的灵活性。

下面介绍三种方式:
①段式存储管理(segmentation):

段(segment)指一类地址空间,一个段就是一个地址连续的内存块,若干个段组成程序的逻辑地址空间。

段式存储管理下的逻辑地址组成格式为(s, o),s为段号,o为段内偏移量,段号和对应内存中的物理起始地址由段表记录。寻址时,先根据段号到段表中查到物理起始地址(基址),然后加上偏移量,得到最终的物理地址。

②页式存储管理(paging):

物理页帧(Frame | Page Frame | 帧 | 页帧):把物理地址空间分成大小相同的基本单位。大小为2^n,如512/4096等。
逻辑页面(Page | 页):把逻辑地址空间划分为相同大小的基本单位
页帧大小和页面大小必须一致

页式存储管理的寻址方式和段式管理类似,逻辑地址格式为(p, o),表示页中的地址,其中p表示页号,o表示偏移量。物理地址格式为(f, o),表示页帧中的地址,其中f表示页帧号,o表示偏移量,页偏移量和页帧偏移量是相等的。

页和页帧的对应关系使用**页表(Page Table)**来管理。寻址时首先根据页号找到页表中对应的页帧号,然后用得到的页帧号与偏移量组

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值