Java开发模拟面试记录

8.5

请你说说 Linux 中 fork() 函数的作用

fork函数作用是在已经存在的进程中创建一个子进程,而原来的进程称为父进程。

简述一下 GDB 常见的调试命令

GDB是在linux操作系统下的命令行窗口
常用命令
(gdb)help:查看命令帮助,具体命令查询在gdb中输入help + 命令,简写h
(gdb)run:重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件),简写r
(gdb)start:单步执行,运行程序,停在第一执行语句
(gdb)list:查看原代码(list-n,从第n行开始查看代码。list+ 函数名:查看具体函数),简写l
(gdb)set:设置变量的值
(gdb)next:单步调试(逐过程,函数直接执行),简写n
(gdb)step:单步调试(逐语句:跳入自定义函数内部执行),简写s
(gdb)backtrace:查看函数的调用的栈帧和层级关系,简写bt
(gdb)frame:切换函数的栈帧,简写f
(gdb)info:查看函数内部局部变量的数值,简写i
(gdb)finish:结束当前函数,返回到函数调用点
(gdb)continue:继续运行,简写c
(gdb)print:打印值及地址,简写p
(gdb)quit:退出gdb,简写q
(gdb)break+num:在第num行设置断点,简写b
(gdb)info breakpoints:查看当前设置的所有断点
(gdb)delete breakpoints num:删除第num个断点,简写d
(gdb)display:追踪查看具体变量值
(gdb)undisplay:取消追踪观察变量
(gdb)watch:被设置观察点的变量发生修改时,打印显示
(gdb)i watch:显示观察点
(gdb)enable breakpoints:启用断点
(gdb)disable breakpoints:禁用断点
(gdb)x:查看内存x/20xw 显示20个单元,16进制,4字节每单元
(gdb)run argv[1] argv[2]:调试时命令行传参
(gdb)set follow-fork-mode child#Makefile项目管理:选择跟踪父子进程(fork())

说一说HashMap的扩容机制

HashMap 的扩容机制,就是当达到扩容条件时会进行扩容。HashMap 的扩容条件就是,向HashMap中添加数据时,

  1. 如果数组为空,则进行首次扩容(默认的初始容量为16)。
  2. 将数据加入链表后,如果链表长度达到8,并且数组长度小于64,则扩容。
  3. 添加数据后,如果数组中元素超过阈值,即比例超出限制(默认加载因子为0.75),则扩容。
    ​ 每次扩容时都是将容量翻倍,即创建一个2倍大的新数组,然后再将旧数组中的数组迁移到新数组里。由于HashMap中数组的容量为2^N,所以可以用位移运算计算新容量,效率很高。

说一说ConcurrentHashMap的实现原理

ConcurrentHashMap在JDK1.7和1.8的实现方式是不同的。

  • 在JDK1.7中,ConcurrentHashMap是由segment数组+hashEntry数组的方式实现的,segment实现了ReentrantLock,所以具有锁的性质,HashEntry用于存储键值对。一个ConcurrentHashMap包含了一个segment数组,一个segment数组包含了一个HashEntry数组,如果要获取HashEntry中的元素,要先获取segment的锁。
  • 在JDK1.8中,ConcurrentHashMap跟HashMap类似,是由node数组+链表/红黑树的方式实现,采用CAS+synchronized来保证线程安全。当链表长度大于8,链表转换为红黑树,并且在1.8中synchronized只锁链表或者红黑树的头节点。是一种相比segment更为细粒度的锁,锁的竞争减少,效率更高。
  • 总结:Java开发模拟面试记录_第1张图片

说一说你对双亲委派模型的理解

双亲委派模型的工作过程(启动类加载器《-—扩展类加载器《—应用程序类加载器《—自定义类加载器)

  • 当一个类加载器收到类加载的请求时,它首先不会自己去尝试加载这个类,而是把这个请求委派给自己的父类加载器去完成,每一层的类加载器都是这样的。因此所有的类加载请求都会传送到顶层的启动类加载器,只有当父类的加载器反馈自己无法完成这个加载请求,子加载器才会尝试去加载。

双亲委派模型的好处

  • 使得 Java 类随着它的类加载器一起具有一种带有优先级的层次关系,确保了在各种加载环境的加载顺序。
  • 保证了运行的安全性,避免了多份同样字节码的加载

Redis有哪些数据类型

Redis主要提供了5种数据类型:字符串(string)、哈希(hash)、列表(list)、集合(set)、有序集合(zset)。Redis还提供了Bitmap、HyperLogLog、Geo类型,但这些类型都是基于上述核心数据类型实现的。5.0版本中,Redis新增加了Streams数据类型,它是一个功能强大的、支持多播的、可持久化的消息队列。

  1. string可以存储字符串、数字和二进制数据,除了值可以是String以外,所有的键也可以是string,string最大可以存储大小为512M的数据。
  2. hash的值本身也是一个键值对结构,最多能存储2^32-1个元素。
  3. list保证数据线性有序且元素可重复,它支持lpush、blpush、rpop、brpop等操作,可以当作简单的消息队列使用,一个list最多可以存储2^32-1个元素。
  4. set是无序不可重复的,它支持多个set求交集、并集、差集,适合实现共同关注之类的需求,一个set最多可以存储2^32-1个元素。
  5. zset是有序不可重复的,它通过给每个元素设置一个分数来作为排序的依据,一个zset最多可以存储2^32-1个元素。

Serializable接口为什么需要定义serialVersionUID常量

  • serialVersionUID常量用于标明当前Serializable类的版本,以验证加载的类和序列化对象是否兼容。(serialVersionUID常量值默认为1L)
  • 在进行序列化时会将当前类的serialVersionUID写入到字节序列中,在反序列化时会将当前字节流中的serialVersionUID同本地对象中的serialVersionUID进行对比,如果相同则继续序列化,如果不同则失败报错。

说一说虚拟地址空间有哪些部分

内核空间

存放内核的代码和数据,所有进程的内核代码段都映射到同样的物理内存,并在内存中持续存在,是操作系统的一部分。内核空间为内核保留,不允许应用程序读写该区域的内容或直接调用内核代码定义的函数。

用户空间

用户空间给各个进程使用,也称为使用者空间。用户空间中的代码运行在较低的特权级别上,只能看到允许它们使用的部分系统资源,并且不能使用某些特定的系统功能,也不能直接访问内核空间和硬件设备,以及其他一些具体的使用限制。用户空间又大致细分为下列一些空间:
栈空间
共享区
堆空间
BSS 段(未初始化数据段)
DATA 段(已初始化数据段)
TEXT 段(代码段)
保留区

UDP协议的首部结构?

UDP首部有8个字节,由4个字段构成,每个字段都是两个字节

  • 源端口号: 可有可无,需要对方回信时选用,不需要时全部置0。
  • 目的端口号:必须有,在终点交付报文的时候需要用到。
  • 长度:UDP的数据报的长度(包括首部和数据)其最小值为8字节(只有首部)。
  • 校验和:检测UDP数据报在传输中是否有错,有错则丢弃。

说一说你对Spring AOP的理解

  • AOP,面向切面编程,是一种编程思想,是通过预编译和运行期动态代理的方式实现不修改代码的情况下给程序动态统一添加功能的技术。
  • AOP可以有两种实现方式:
    1、JDK动态代理:Java提供的动态代理技术,通过反射来接收被代理的类,同时要求此类必须实现一个接口。Spring AOP默认采用这种方式。(JDK动态代理的核心是InvocationHandler接口和Proxy类)
    2、CGLib动态代理:通过字节码技术,在运行时创建子类代理的实例。如果目标类没有实现接口,Spring AOP就会采用CGLib来动态代理目标类,在运行时动态的生成某个类的子类。
    注意:CGLib是通过继承的方式来实现动态代理,如果这个类被final修饰,则无法使用CGLib来实现动态代理。
    应用场景:事务、日志管理

SpringMVC中过滤器或者拦截器怎么实现?

  • Spring MVC 的拦截器(Interceptor)与 Java Servlet 的过滤器(Filter)类似,它主要用于拦截用户的请求并做相应的处理,通常应用在权限验证、记录请求信息的日志、判断用户是否登录等功能上。
  • 在 Spring MVC 框架中定义一个拦截器需要对拦截器进行定义和配置,定义一个拦截器可以通过两种方式:一种是通过实现 HandlerInterceptor 接口或继承 HandlerInterceptor 接口的实现类来定义;另一种是通过实现 WebRequestInterceptor 接口或继承 WebRequestInterceptor 接口的实现类来定义。
  • 区别: 两个拦截器都是Spring提供的,但是WebRequestInterceptor只会起到一个请求验证的目的,表示请求会被WebRequestInterceptor实现类接收。并不会像HandlerInterceptor拦截器一样将不合法的请求死死拦截。

JDBC了解嘛,数据源?

  • JDBC:Java提供了用于专门操作数据库的API,即JDBC(Java Data Base Connectivity)。JDBC操作不同数据库仅仅是连接方式上的差异而已,使用JDBC的应用程序一旦和数据库建立连接,就可以使用JDBC提供的API操作数据库。
  • JDBC是连接数据库的最基本的方式,首先加载jdbc驱动程序,然后建立数据库连接Connection,创建执行SQL的语句Statement,处理执行结构ResultSet,最后释放资源。
  • 数据源:数据源是连接到数据库的一类路径,它包含了访问数据库的信息(地址、用户名、密码)。

你可能感兴趣的:(Java面试,java,面试)