当前位置: 首页 > news >正文

面试常见八股

JAVA篇

基础

1、自动拆箱和装箱

装箱:装箱是将值类型(如intdoublestruct等)转换为object类型或任何接口类型的过程。由于object是所有类型的基类(在.NET中),并且接口是引用类型,因此装箱操作实际上是在堆(Heap)上分配一个新的对象,并将值类型的值复制到该对象中。这个新分配的对象是对原始值类型值的引用包装。

例如:

Integer i =19;

原因:需要将值类型作为参数传递给接受object类型或接口类型的方法

拆箱:拆箱是将之前装箱的对象转换回原始的值类型的过程。拆箱操作包括检查对象是否确实包含原始值类型的值,并提取该值。

int n = i;

实际案例:

public static void main(String[] args) {  // 创建一个ArrayList来存储Integer对象  List<Integer> numbers = new ArrayList<>();  // 装箱:将int值添加到ArrayList中  numbers.add(5); // 这里自动发生了装箱:int -> Integer  numbers.add(10);  // 遍历ArrayList并打印每个元素  for (Integer number : numbers) {  System.out.println(number);  }  // 拆箱:从ArrayList中获取Integer对象并作为int值处理  // 假设我们知道列表中确实存储的是int值对应的Integer对象  int firstNumber = numbers.get(0); // 这里自动发生了拆箱:Integer -> int  System.out.println("第一个数字是:" + firstNumber);  // 注意:如果尝试从一个可能包含null的ArrayList中拆箱,可能会引发NullPointerException  // 因此,在拆箱之前进行null检查是一个好习惯  }  

2、接口和抽象类

共同点:都不能直接实例化,接口要通过实现类,抽象类要通过继承才能创建具体的对象。

区别:

  接口主要是为了对类的行为进行约束,而抽象类是为了代码复用,强调从属关系。

  一个类只能继承一个类包括抽象类,但是可以实现多个接口,一个接口也能继承多个接口。

  接口中的成员变量只能是 public static final 类型的,不能被修改且必须有初始值。抽象类的成员变量可以有任何修饰符(private, protected, public),可以在子类中被重新定义或赋值。

3、深拷贝和浅拷贝

浅拷贝:浅拷贝在堆上创建一个新的对象,但是如果当前对象内部属性是引用类型的话就直接拷贝引用的地址,之后创建的新对象和原对象共用一个对象。

深拷贝:完全复制整个对象,包括这个对象内部的对象。

4、String、StringBuffer、StringBuilder

String对象因为有final修饰符修饰,所以不可变,可以理解为常量,线程安全。而另外2个继承自AbstractStringBuilder类,没有修饰符所以可变。而且提供了一些修改字符串的方法可以使用比如append、insert这些。其中StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。

集合

1、Map

HashMap的实现

JDK1.8 之前 HashMap底层是数组和链表结合在一起使用也就是链表散列。HashMap通过key的 hashcode 经过扰动函数处理过后得到hash值,然后通过 (n - 1)&hash 判断当前元素存放的位置(这里的 n 指的是数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突。

JDK1.8 之后改为红黑树,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。

HashMap和HashTable的区别

线程安全方面(table内部方法都用synchornized修饰)、效率、null key和null value、底层数据结构

扩容:不指定的话,默认table为11,扩充到2n+1;map默认为16,扩充到2n。指定的话,table直接使用指定的大小,map会扩充为2的幂次。

HashMap为什么不安全?Table为什么安全?

因为在JDK1.8前,hashmap如果在多线程情况下,好几个线程同时对链表进行扩容,会造成死循环。1.8之后,也会有数据丢失的问题,因为多个键值对被分到一个桶中,采用红黑树进行存储,多个线程操作可能因为时间片的问题,导致同样哈希值的一个操作覆盖另一个操作结果,不安全。

ConcurrentHashMap 和 Hashtable 的区别

ConcurrentHashMap:1.7的时候,采用分段思想,segment。之后,采用Node数组+树的方式,使用synchornized和CAS来操作。

Hashtable:同一把锁,synchornized,效率比较低。

并发

1、CAS

全称是比较和交换,通常用于乐观锁之中。乐观锁与悲观锁区别在对于共享资源访问时候不同的上锁方式,悲观是默认修改每次都上锁,一次只给一个线程使用。乐观锁默认不修改,但是其他线程提交前需要判断是否有修改。CAS 的思想很简单,就是用一个预期值和要更新的变量值进行比较,两值相等才会进行更新。CAS 是一个原子操作,底层依赖于一条 CPU 的原子指令。

2、ThreadLocal

想实现一个线程有自己的专属本地变量,绑定自己的值。如果创建了一个ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的本地副本,线程使用 get()set() 方法来获取默认值或将其值更改为当前线程所存的副本的值,从而避免了线程安全问题。

3、线程池

  • 降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗
  • 提高响应速度:当任务到达时,任务可以不需要等到线程创建就能立即执行
  • 提高线程的可管理性:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

 

http://www.lryc.cn/news/436999.html

相关文章:

  • 第十八章 番外 余弦相似度
  • HPA和helm
  • 基于人工智能的智能语音助手
  • java实际开发——数据库存储金额时用什么数据类型?(MySQL、PostgreSQL)
  • Java 设计模式-状态模式
  • 2024.9.13 Python与图像处理新国大EE5731课程大作业,索贝尔算子计算边缘,高斯核模糊边缘,Haar小波计算边缘
  • 动态IP池的IP都是纯净IP吗?
  • 【MySQL】查询表中重复数据、模糊查询列信息、快速copy表数据(1)
  • 计算机操作系统之并行性与并发性笔记
  • 顶级高效的ChatGPT论文润色提示词和使用技巧
  • WebAPI (一)DOM树、DOM对象,操作元素样式(style className,classList)。表单元素属性。自定义属性。间歇函数定时器
  • 若依框架开发
  • 局域网windows下使用Git
  • Redis访问工具
  • vue3+ant design vue动态实现级联菜单~
  • 软件可维护性因素例题
  • git的一些操作
  • opencv实战项目二十三:基于BEBLID描述符的特征点匹配实现表盘校正
  • 数据库是全表扫描是怎么扫描法?
  • 认准这10款人力资源系统,90%的企业都在用!
  • 2024年我的利基出版转型——新战略与重点解析
  • 【数据结构】双向链表专题
  • 大二上学期计划安排
  • HarmonyOS开发实战( Beta5.0)图片编辑实现马赛克效果详解
  • 【新书介绍】《JavaScript前端开发与实例教程(微课视频版)(第2版)》
  • 什么是GWAS全基因组关联分析?
  • k8s dashboard token 生成/获取
  • windows@openssh免密登陆配置@基于powershell快速配置脚本
  • 【深度学习】【图像分类】【OnnxRuntime】【Python】VggNet模型部署
  • 手写排班日历