Skip to content

Language_Java 面试专题手册

💡 本章节共收录 4392 道面试真题,建议每天复习 10-20 题。


Q1: HashMap和Map的区别是什么?

【核心解析】 Map是接口,HashMap是Map的实现类;HashMap允许null键和值;HashMap基于哈希表实现,非线程安全;HashMap的键无序;HashMap的默认初始容量为16,负载因子0.75。


Q2: ThreadLocal是什么?如何避免内存泄漏?

【核心解析】 ThreadLocal提供线程局部变量;每个线程维护ThreadLocalMap;key为弱引用,value为强引用;内存泄漏:key被回收后value无法访问;避免:使用完调用remove()


Q3: 为什么栈里的局部变量是线程私有,堆里的全局变量是线程共享?

【核心解析】 栈是线程私有的内存区域,每个线程有独立的栈帧,局部变量存储于栈帧中,因此线程私有;堆是线程共享的内存区域,所有线程可访问堆中的对象,因此全局变量(对象实例)是线程共享的。


Q4: ArrayList和LinkedList的区别及适用场景?

【核心解析】 ArrayList基于动态数组实现,随机访问快(O(1)),但中间插入/删除慢(O(n));LinkedList基于双向链表实现,中间插入/删除快(O(1)),但随机访问慢(O(n))。频繁随机访问选ArrayList,频繁中间插入/删除选LinkedList。


Q5: 频繁在ArrayList中间位置插入元素,如何优化性能?

【核心解析】 改用LinkedList;或使用ArrayList时,先通过addAll()批量插入;或使用其他数据结构如CopyOnWriteArrayList(适合读多写少);或使用List.subList()分批处理。


Q6: Map和HashMap的区别?

【核心解析】 Map是接口,HashMap是Map的实现类;HashMap基于哈希表,允许null键和值,非线程安全;其他Map实现如TreeMap有序,LinkedHashMap保持插入顺序。


Q7: StringBuilder和StringBuffer的区别是什么?

【核心解析】 StringBuffer是线程安全的,方法使用synchronized修饰;StringBuilder非线程安全;StringBuilder性能更高;单线程环境下优先使用StringBuilder;多线程环境下使用StringBuffer或手动加锁。


Q8: ArrayList和LinkedList的区别是什么?

【核心解析】 ArrayList基于动态数组实现,LinkedList基于双向链表实现;ArrayList随机访问快O(1),LinkedList随机访问慢O(n);ArrayList插入删除慢(需移动元素),LinkedList插入删除快(只需修改指针);LinkedList内存占用更大(存储前后指针);ArrayList适合频繁读取,LinkedList适合频繁增删。


Q9: 讲一下链表的数据结构,LinkedList是双向链表还是单向链表?

【核心解析】 链表由节点组成,每个节点包含数据和指向下一个节点的指针;单向链表只能从头到尾遍历;双向链表每个节点有前驱和后继指针;Java的LinkedList是双向链表,支持双向遍历;LinkedList实现了List和Deque接口。


Q10: 讲一下HashMap的实现原理。

【核心解析】 基于数组+链表+红黑树(JDK8+);通过key的hashCode计算数组索引;当链表长度>=8且数组长度>=64时转为红黑树;put时先计算hash,定位数组位置,若为空直接插入,否则遍历链表或红黑树;get时类似;扩容因子默认0.75,扩容时重新计算位置。


Q11: HashMap中如何根据hash值定位到数组?

【核心解析】 先计算key的hashCode,再通过扰动函数(高16位异或低16位)减少碰撞;然后与数组长度-1进行按位与运算((n-1) & hash)得到数组下标;数组长度必须是2的幂,保证位运算等价于取模。


Q12: 为什么重写equals时必须重写hashCode?

【核心解析】 Java规定:两个对象equals相等则hashCode必须相等;反之不要求;若不重写hashCode,可能导致equals相等的对象hashCode不同,在HashMap等散列集合中无法正确存储和查找;重写hashCode需保证一致性。


Q13: 说一下移动语义,为什么它在网络库或者容器里很重要?

【核心解析】 移动语义将临时对象或即将失效对象的资源转移,避免昂贵拷贝;网络库中缓冲区、消息对象、任务对象投递时避免深拷贝;右值引用和移动构造实现资源所有权转移;在vector扩容、函数返回对象、任务入队等场景收益明显


Q14: 智能指针在连接管理里一般怎么用,为什么TcpConnection常配合shared_ptr?

【核心解析】 连接对象生命周期复杂,被连接表、回调、定时器、任务队列临时引用;裸指针易导致连接关闭后异步回调访问野指针;shared_ptr管理生命周期,确保连接在使用期间不被销毁


Q15: 如何在不使用第三个变量的情况下交换两个整型变量a和b的值?

【核心解析】 方法一:使用加减法,a = a + b; b = a - b; a = a - b;方法二:使用异或运算,a = a ^ b; b = a ^ b; a = a ^ b;注意加减法可能溢出,异或仅适用于整数类型。


Q16: Java中多态如何实现?请解释其底层机制。

【核心解析】 多态通过继承、接口和重写实现;底层依赖虚方法表(vtable)或接口方法表;运行时根据对象实际类型动态绑定方法;静态多态通过方法重载实现,编译时确定。


Q17: 智能指针(如C++中的shared_ptr)的原理是什么?如何避免循环引用?

【核心解析】 智能指针通过引用计数管理资源;shared_ptr使用控制块记录引用计数;循环引用导致内存泄漏,可用weak_ptr打破;weak_ptr不增加引用计数,通过lock()获取shared_ptr。


Q18: HashMap的原理是什么?

【核心解析】 数组+链表/红黑树;哈希函数计算索引;put流程:计算hash、定位、插入或覆盖;扩容机制:加载因子0.75、2倍扩容;线程不安全;红黑树化条件:链表长度>=8且数组长度>=64;1.8优化


Q19: C++内存管理、STL容器、智能指针、多线程数据共享、互斥锁和读写锁的区别是什么?

【核心解析】 内存管理:new/delete、malloc/free、RAII;STL容器:vector、list、map等;智能指针:shared_ptr、unique_ptr、weak_ptr;多线程数据共享:互斥锁、条件变量;互斥锁和读写锁:互斥锁独占,读写锁读共享写独占。


Q20: 移动构造和拷贝构造的区别

【核心解析】 拷贝构造:深拷贝或浅拷贝,参数为const左值引用;移动构造:转移资源所有权,参数为右值引用,通常将源对象资源置空;移动构造可避免不必要的拷贝,提高性能;C++11引入移动语义,通过std::move触发;移动后源对象应处于有效但未定义状态。


Q21: 智能指针的构造和使用

【核心解析】 unique_ptr:独占所有权,不能拷贝,只能移动;shared_ptr:共享所有权,引用计数,循环引用需用weak_ptr;weak_ptr:不增加引用计数,用于观察shared_ptr;make_shared和make_unique更安全高效;智能指针自动管理内存,避免内存泄漏。


Q22: 完美转发如何实现

【核心解析】 使用模板和std::forward;万能引用(T&&)可绑定左值和右值;std::forward根据参数类型转发,保持值类别;常用于工厂函数、包装器;避免不必要的拷贝。


Q23: 全局变量和局部变量的选择

【核心解析】 全局变量:生命周期贯穿程序,作用域全局,多线程需同步,易导致耦合;局部变量:生命周期限于作用域,线程安全,内存栈分配;优先使用局部变量,减少全局状态;必要时用单例或依赖注入替代全局变量。


Q24: CMake语法

【核心解析】 CMakeLists.txt基本命令:cmake_minimum_required、project、add_executable、add_library、target_link_libraries;变量设置:set;条件控制:if/endif;循环:foreach;安装:install。


Q25: Linux指令

【核心解析】 文件操作:ls、cd、cp、mv、rm、find;权限:chmod、chown;进程:ps、top、kill;网络:netstat、ss、curl;文本处理:grep、awk、sed;系统信息:uname、df、du。


Q26: Java中常见的集合类有哪些?请介绍ConcurrentHashMap、StringBuilder和StringBuffer。

【核心解析】 常见集合:List、Set、Map;ConcurrentHashMap:分段锁(Java7)或CAS+synchronized(Java8),高并发安全;StringBuilder:非线程安全,效率高;StringBuffer:线程安全,通过synchronized方法保证。


Q27: ConcurrentHashMap的Segment分段锁有什么弊端?

【核心解析】 分段锁粒度较大,并发度受限于段数;内存占用较高;Java8改用CAS+synchronized+红黑树,提高并发性能。


Q28: StringBuffer如何保证线程安全?

【核心解析】 通过synchronized关键字修饰方法(如append、insert等);所有公共方法都加锁,保证原子性;性能较低,适合多线程环境。


Q29: Java基本数据类型和包装类型的区别?

【核心解析】 基本类型:int、double等,存储在栈中;包装类型:Integer、Double等,是对象,存储在堆中;自动装箱/拆箱;包装类型可为null;比较时注意equals和==。


Q30: int a = 2 在内存中如何存储?

【核心解析】 局部变量a存储在虚拟机栈的局部变量表中;基本类型直接存储值;如果是成员变量,存储在堆中对象实例内。


Q31: 请介绍C++中的虚函数机制,包括其实现原理、优缺点以及使用注意事项。

【核心解析】 虚函数是C++实现运行时多态的核心机制;通过基类指针或引用调用虚函数时,实际执行的是对象真实类型的版本;底层依赖虚函数表(vtable)和虚表指针(vptr)实现动态分发;优点包括接口统一、扩展方便;缺点是对象增加一个虚表指针,调用时多一次间接寻址;基类析构函数应声明为虚函数,否则通过基类指针删除派生类对象可能导致未定义行为;可以使用dynamic_cast进行安全向下转型。


Q32: C++中常用的智能指针有哪些?使用时需要注意什么?

【核心解析】 常见智能指针:unique_ptr(独占所有权,开销小)、shared_ptr(共享所有权,引用计数)、weak_ptr(解决循环引用);unique_ptr语义清晰,推荐优先使用;shared_ptr通过引用计数管理生命周期,注意循环引用会导致内存泄漏,需用weak_ptr打破环;不要从同一个裸指针重复构造多个shared_ptr,否则会形成多个控制块导致重复释放;注意线程安全,引用计数操作是原子的,但对象本身不是。


Q33: C++中set能存储自定义类型吗?需要注意什么?

【核心解析】 可以;set底层通常是有序关联容器(如红黑树),需要元素支持严格弱序比较;常见做法是重载 operator<,或在模板参数中传入自定义比较器;比较逻辑不仅决定排序顺序,还决定元素是否相等(若 a < bb < a 均不成立则视为相等);需确保比较操作是严格弱序的(反对称、传递、不可比传递性);若未提供正确比较,set可能无法正确工作。


Q34: 接口和抽象类的区别。

【核心解析】 接口用 interface 定义,抽象类用 abstract class;接口方法默认 public abstract,抽象类可包含具体方法;接口支持多实现,抽象类单继承;接口侧重行为规范,抽象类侧重代码复用。


Q35: vector传递引用和值有什么区别?迭代器失效是什么?vector的底层原理是什么?

【核心解析】 传值会拷贝整个vector,传引用避免拷贝;迭代器失效:插入或删除元素导致迭代器指向无效内存;vector底层是动态数组,支持随机访问,扩容时重新分配内存。


Q36: 进程创建后的结构是什么?多进程、多线程、多协程的区别?为什么要有这么多种?

【核心解析】 进程结构:PCB、代码段、数据段、堆栈;区别:进程资源独立,线程共享进程资源,协程用户态轻量级;不同场景选择不同并发模型。


Q37: 编程题:场景题,处理字符串,补全成员方法。

【核心解析】 考察字符串操作,如分割、拼接、正则匹配;注意边界条件。


Q38: 编程题:使用Stream流进行排序和过滤,填写方法名。

【核心解析】 常用方法:filter、map、sorted、collect、toList;注意方法名正确性。


Q39: String、StringBuilder、StringBuffer的区别是什么?

【核心解析】 String不可变,StringBuilder线程不安全但效率高,StringBuffer线程安全。


Q40: 还有哪些集合是线程安全的?

【核心解析】 Vector、Hashtable、ConcurrentHashMap、CopyOnWriteArrayList、Collections.synchronizedList等。


Q41: Java中静态内部类和匿名内部类的区别是什么?

【核心解析】 静态内部类使用static修饰,不依赖外部类实例,可直接创建;匿名内部类没有类名,必须实现接口或继承类,在创建时定义;静态内部类可以有静态成员,匿名内部类不能有静态成员;匿名内部类常用于事件监听、回调等一次性场景;静态内部类用于逻辑上属于外部类但独立于实例的类。


Q42: Java中LinkedList和ArrayList的区别是什么?

【核心解析】 ArrayList基于动态数组实现,LinkedList基于双向链表实现;ArrayList随机访问快(O(1)),LinkedList随机访问慢(O(n));ArrayList插入删除慢(需移动元素),LinkedList插入删除快(只需修改指针);ArrayList内存连续,LinkedList内存分散;ArrayList适合读多写少,LinkedList适合写多读少。


Q43: 平时写代码会用到AI吗,哪些场景会用?

【核心解析】 代码补全;生成模板代码;调试建议;文档生成;学习新技术;但需验证正确性。


Q44: 请说明final修饰变量与引用对象的区别,以及final修饰方法、类的作用。

【核心解析】 final修饰基本类型变量:值不可变;修饰引用类型变量:引用不可变,但对象内容可变;final修饰方法:不可被重写;final修饰类:不可被继承。


Q45: ArrayList和LinkedList的区别是什么?ArrayList是线程安全的吗?

【核心解析】 ArrayList基于动态数组,LinkedList基于双向链表;ArrayList随机访问快,LinkedList插入删除快;ArrayList不是线程安全的,需使用Collections.synchronizedList或CopyOnWriteArrayList


Q46: HashMap的数据结构是什么?为什么使用红黑树?

【核心解析】 HashMap底层是数组+链表+红黑树;当链表长度超过阈值(默认8)时转换为红黑树,以优化查找性能;红黑树是自平衡二叉查找树,保证最坏情况下的时间复杂度为O(log n)


Q47: ConcurrentHashMap如何保证线程安全?

【核心解析】 JDK 1.7使用分段锁(Segment),JDK 1.8使用CAS+synchronized;对每个桶的头节点加锁,减少锁竞争;支持高并发读写


Q48: synchronized和ReentrantLock的区别是什么?

【核心解析】 synchronized是关键字,自动加解锁;ReentrantLock是API,需手动加解锁;ReentrantLock支持公平锁、可中断、条件变量等高级功能;性能上synchronized已优化,两者接近


Q49: Spring Boot常用注解有哪些?

【核心解析】 @SpringBootApplication、@RestController、@RequestMapping、@Autowired、@Service、@Component、@Configuration、@Bean


Q50: HashMap的底层实现原理是什么?

【核心解析】 基于数组+链表+红黑树;默认初始容量16,负载因子0.75;put过程:计算hash,定位桶,处理冲突;扩容机制:当size>threshold时扩容为2倍;线程不安全


Q51: 请说明HashMap的数据结构,并比较ConcurrentHashMap与HashMap的不同,以及线程安全的替代类。

【核心解析】 HashMap基于数组+链表+红黑树(JDK8+);ConcurrentHashMap使用分段锁或CAS+同步机制保证线程安全;不同点:线程安全、锁粒度、迭代器弱一致性;线程安全替代类:ConcurrentHashMap、Hashtable、Collections.synchronizedMap。


Q52: LinkedList 和 HashMap 的底层实现原理是什么?

【核心解析】 LinkedList 基于双向链表,支持快速插入删除;HashMap 基于数组+链表/红黑树,通过哈希函数定位桶,处理哈希冲突。


Q53: Java集合框架:常见集合类的特点、底层数据结构及适用场景,如ArrayList、LinkedList、HashMap、ConcurrentHashMap。

【核心解析】 ArrayList:基于数组,随机访问快,插入删除慢;LinkedList:基于双向链表,插入删除快,随机访问慢;HashMap:数组+链表+红黑树,非线程安全;ConcurrentHashMap:分段锁或CAS,线程安全;适用场景:根据读写比例和并发需求选择


Q54: 请解释JavaScript中的Promise和闭包的概念及典型应用场景。

【核心解析】 Promise是异步编程的解决方案,用于处理回调地狱,具有三种状态:pending、fulfilled、rejected;闭包是指函数能够访问其外部作用域变量的特性,常用于数据封装和模块化;典型应用:Promise用于异步请求链式调用,闭包用于私有变量和函数工厂。


Q55: 请解释进程与线程的区别,并说明C++11协程的用户态线程是如何实现的。

【核心解析】 进程是资源分配的最小单位,线程是CPU调度的最小单位;进程间独立,线程共享进程资源;协程是用户态轻量级线程,由程序控制切换,无需内核参与;C++11协程通过编译器生成状态机实现,使用co_await、co_yield等关键字。


Q56: Java 接口和抽象类的区别是什么?Java 8 接口支持 default 方法后,抽象类还有存在意义吗?接口无法替代抽象类的点是什么?

【核心解析】 接口只能定义抽象方法和常量(Java 8 后可有 default/static 方法),抽象类可包含成员变量、构造器、非抽象方法;类只能单继承抽象类,但可多实现接口;抽象类用于定义共同状态和行为,接口用于定义能力契约;抽象类可提供部分实现,接口 default 方法不能保存状态;抽象类可定义 protected 成员,接口默认 public。


Q57: Java中对象的引用类型有哪些?它们的特点和区别是什么?

【核心解析】 强引用:不会被GC回收,内存不足时抛出OOM;软引用:内存不足时回收,适用于缓存;弱引用:下次GC时回收,适用于ThreadLocal;虚引用:无法通过get获取对象,用于跟踪对象被回收的状态


Q58: 接口和抽象类有什么区别?

【核心解析】 接口只能定义抽象方法和默认方法(Java 8+),抽象类可包含抽象方法和具体方法;接口支持多实现,抽象类只能单继承;接口成员默认public,抽象类可有各种访问修饰符;接口侧重行为规范,抽象类侧重代码复用


Q59: 反射调用和直接调用在性能上有什么不同?为什么反射性能较差?JIT如何影响反射性能?

【核心解析】 反射性能较差,因为需要动态解析类、方法,进行安全检查;反射调用涉及Method.invoke()的委派和参数装箱;JIT可以内联反射调用,但受限于反射的不可预测性;现代JVM对反射有优化,如方法句柄(MethodHandle)


Q60: Java中接口和抽象类的区别是什么?

【核心解析】 抽象类可以有构造方法、成员变量、非抽象方法;接口只能有抽象方法(Java8后可有default/static方法);类只能单继承抽象类,但可多实现接口;抽象类用于is-a关系,接口用于has-a能力;接口成员默认public static final,抽象类成员可有不同访问修饰符。


Q61: Java反射是什么?你是如何使用它的?

【核心解析】 反射允许在运行时获取类的信息(构造方法、字段、方法)并操作对象;使用Class.forName()、getMethod()、invoke()等;应用:框架(Spring IOC、MyBatis)、动态代理、注解处理;注意性能开销和安全性。


Q62: C++ 智能指针有哪些?

【核心解析】 C++ 智能指针包括 std::unique_ptr(独占所有权)、std::shared_ptr(共享所有权,引用计数)、std::weak_ptr(弱引用,避免循环引用);auto_ptr 已弃用;智能指针自动管理内存,避免内存泄漏。


Q63: 左值右值、虚拟内存、TCP 等基础知识。

【核心解析】 左值可取地址,右值不可;虚拟内存提供地址空间隔离,通过页表映射;TCP 可靠传输,三次握手、四次挥手、流量控制、拥塞控制。


Q64: HashMap的底层原理是什么?

【核心解析】 基于数组+链表+红黑树;哈希函数计算索引;解决哈希冲突:链地址法;扩容机制:负载因子0.75,2倍扩容;线程不安全;允许null键值;JDK8优化:链表转红黑树阈值8


Q65: 说一下你对面向对象的理解,并发和并行的区别,创建线程有几种方式,线程池有几种状态?

【核心解析】 面向对象:封装、继承、多态;并发:多个任务交替执行,并行:同时执行;创建线程:继承Thread、实现Runnable、实现Callable、线程池;线程池状态:RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED


Q66: 说一下什么是反射,什么是动态代理?

【核心解析】 反射:运行时获取类信息并操作对象;动态代理:运行时创建代理对象,增强方法;JDK动态代理基于接口,CGLIB基于子类;应用:AOP、框架底层


Q67: Java中equals和hashCode方法必须同时改写,不能只改写其中一个,原因是什么?

【核心解析】 Hash集合(如HashMap、HashSet)依赖hashCode确定存储位置,equals判断相等性;若只改写equals而hashCode不变,则相等的对象可能哈希到不同桶,导致集合行为异常;反之,只改写hashCode可能导致不同对象被认为相等;必须保证equals相等的对象hashCode相同


Q68: Java更适合做Web场景下的开发,请从面向对象、解释型语言、JVM内存管理、JIT和多线程等方面说明。

【核心解析】 面向对象特性(封装、继承、多态)便于构建复杂业务模型;JVM内存管理(GC)自动回收内存,减少内存泄漏;JIT编译将热点代码编译为机器码,提升性能;多线程支持(synchronized、Lock、线程池)便于处理高并发;丰富的Web框架(Spring Boot)和生态


Q69: Java 中的接口和抽象类有什么区别?

【核心解析】 接口使用 interface 关键字,抽象类使用 abstract class;接口方法默认 public abstract,抽象类可包含非抽象方法;接口支持多实现,抽象类单继承;接口可包含 default 和 static 方法(Java 8+),抽象类可有构造器、成员变量;接口用于定义能力,抽象类用于定义共性。


Q70: String、StringBuilder、StringBuffer 的区别是什么?

【核心解析】 String 不可变,每次修改创建新对象;StringBuilder 可变,线程不安全,效率高;StringBuffer 可变,线程安全(方法同步),效率较低;单线程推荐 StringBuilder,多线程推荐 StringBuffer。


Q71: Java 中哪些注解可以实现依赖注入?

【核心解析】 @Autowired(Spring 提供,按类型注入)、@Resource(JSR-250,按名称注入)、@Inject(JSR-330,需依赖 javax.inject);@Autowired 可配合 @Qualifier 指定名称;@Resource 默认按名称,找不到按类型。


Q72: Java 里的 HashMap 如何扩容的?扩容机制是怎样的?

【核心解析】 默认初始容量 16,负载因子 0.75;当元素个数超过阈值(容量*负载因子)时扩容为原容量两倍;扩容时重新计算哈希,将旧数组元素迁移到新数组;Java 8 引入红黑树优化链表过长(>=8 且容量>=64);扩容过程可能引发死循环(多线程环境),建议使用 ConcurrentHashMap。


Q73: 进程调度和线程调度的效率差异是什么?

【核心解析】 线程切换比进程切换轻量,同一进程内线程切换地址空间不变,代价小;进程切换涉及页表切换、TLB失效、缓存命中下降,开销更大;实际性能瓶颈往往不是切换本身,而是上下文切换导致的缓存抖动、锁竞争和调度延迟;高性能服务常控制线程数或使用事件驱动、协程模型。


Q74: 指针和引用的区别是什么?

【核心解析】 引用是别名,定义时必须绑定对象,语义上默认有效,不能改绑;指针是变量,存地址,可为空,可改指向;引用表达参数一定存在,指针适合表达可能为空或需手动管理所有权;常量引用可绑定右值,指针有多级间接访问,引用不是对象。


Q75: 多态和虚函数底层是怎么工作的?

【核心解析】 运行时多态依赖虚函数机制;类有虚函数时,对象包含虚表指针指向虚函数表;通过基类指针/引用调用虚函数时,先找到实际类型虚表,再间接调用函数地址;代价是对象多一个虚表指针,调用多一次间接寻址,影响对象布局;可进一步讨论虚析构、纯虚函数、对象切片、构造析构阶段调用虚函数的行为。


Q76: C++ 里内存管理方式有哪些?

【核心解析】 自动存储期对象(栈上),生命周期由作用域决定;动态内存管理:new/delete、new[]/delete[];推荐使用容器、智能指针和RAII包装,减少手写裸资源管理;高性能场景可考虑对象池、内存池、jemalloc/tcmalloc等分配器优化。


Q77: C++ Qt 的信号与槽是如何实现的?

【核心解析】 信号与槽是Qt的核心机制;基于元对象系统(MOC);通过预处理器生成代码;使用函数指针或模板实现;支持跨线程信号槽;连接方式(直接、队列、阻塞队列);性能开销。


Q78: 请介绍C++中的智能指针,并说明它们是否线程安全。

【核心解析】 智能指针包括unique_ptr、shared_ptr、weak_ptr;unique_ptr独占所有权,不可拷贝;shared_ptr共享所有权,引用计数;weak_ptr弱引用,解决循环引用;shared_ptr的引用计数操作是原子操作,但指向的对象本身不是线程安全的;unique_ptr和weak_ptr的线程安全需注意。


Q79: volatile有什么特性?可以保证原子性吗?

【核心解析】 保证可见性:写操作立即刷新到主存;禁止指令重排序;不保证原子性,如i++操作非原子;适用于状态标志位。


Q80: 请解释C++虚函数表的实现原理。

【核心解析】 虚函数表(vtable)存储虚函数地址;每个包含虚函数的类有一个vtable;对象通过虚指针(vptr)指向vtable;动态绑定实现多态。


Q81: 请介绍C++智能指针的使用场景与内存管理。

【核心解析】 智能指针包括unique_ptr、shared_ptr、weak_ptr;unique_ptr独占所有权,shared_ptr共享所有权(引用计数),weak_ptr解决循环引用;用于自动管理动态内存,避免内存泄漏。


Q82: 请比较接口和抽象类的区别,并从设计层面说明各自的使用场景。

【核心解析】 接口定义行为规范(多实现),抽象类提供部分实现(单继承);接口侧重能力,抽象类侧重共性;Java 8后接口可有默认方法。


Q83: 请介绍Java单例模式的实现方式,并重点说明双重检查锁的细节。

【核心解析】 常见实现:饿汉式、懒汉式、双重检查锁、静态内部类、枚举;双重检查锁需使用volatile防止指令重排;第一次判空避免加锁,第二次判空保证唯一实例。


Q84: 请讲一下Java常用集合框架的底层数据结构、优缺点及使用场景。

【核心解析】 ArrayList:基于数组,随机访问快,插入删除慢,适合频繁查询;LinkedList:基于双向链表,插入删除快,随机访问慢,适合频繁增删;HashMap:基于数组+链表/红黑树,O(1)查找,非线程安全,适合键值对存储;TreeMap:基于红黑树,有序,适合需要排序的场景;HashSet基于HashMap,TreeSet基于TreeMap。


Q85: Vector的底层实现和扩容机制

【核心解析】 底层是Object数组;线程安全,方法用synchronized修饰;默认初始容量10;扩容时增加一倍(可指定增量);扩容时创建新数组并拷贝;与ArrayList区别:同步、扩容策略;性能较低,推荐使用ArrayList或CopyOnWriteArrayList


Q86: 虚函数的作用

【核心解析】 实现多态;允许子类重写父类方法;通过虚函数表(vtable)动态绑定;C++中虚函数用virtual关键字;Java中普通方法默认虚,final/static/private非虚;作用:基类指针调用派生类方法;提高代码扩展性


Q87: new与malloc的区别

【核心解析】 new是C++运算符,malloc是C函数;new自动计算大小,malloc需手动指定;new返回类型指针,malloc返回void*;new调用构造函数,malloc不调用;new失败抛异常,malloc返回NULL;new可重载,malloc不可;new分配在自由存储区,malloc在堆


Q88: 请解释C++中虚函数与多态的实现原理,包括虚表(vtable)和虚指针(vptr)的机制。

【核心解析】 虚函数通过虚表实现动态绑定;每个包含虚函数的类有一个虚表,存储虚函数地址;每个对象有一个虚指针指向虚表;构造函数中调用虚函数不会发生多态,因为虚指针可能未初始化或指向当前类的虚表。


Q89: 请解释C++中智能指针的原理和常见类型(shared_ptr、unique_ptr、weak_ptr),以及如何避免内存泄漏和野指针。

【核心解析】 智能指针自动管理内存,避免手动delete;shared_ptr通过引用计数共享所有权;unique_ptr独占所有权,不可拷贝;weak_ptr解决循环引用;避免野指针:初始化指针、使用智能指针、delete后置空。


Q90: 请解释C++中static关键字的作用,包括静态成员变量、静态成员函数、局部静态变量等。

【核心解析】 静态成员变量属于类,所有对象共享;静态成员函数只能访问静态成员;局部静态变量在首次初始化后保持值;静态全局变量和函数具有内部链接性。


Q91: 请解释C++中vector的扩容机制,包括容量增长策略和元素移动方式。

【核心解析】 vector以连续内存存储,当容量不足时分配新内存(通常为原容量的1.5或2倍);将旧元素拷贝/移动到新内存;释放旧内存;扩容操作是O(n),但均摊时间复杂度为O(1)。


Q92: 请解释C++中new和malloc的区别,包括内存分配、构造函数调用、异常处理等方面。

【核心解析】 new是运算符,malloc是函数;new分配内存并调用构造函数,malloc只分配内存;new返回类型指针,malloc返回void*;new失败抛出异常,malloc返回NULL;new可重载,malloc不可。


Q93: 请解释C++程序编译流程的各个阶段:预处理、编译、汇编、链接,以及ELF和EXE文件格式的区别。

【核心解析】 预处理:处理宏、头文件包含等;编译:将预处理后的文件转换为汇编代码;汇编:将汇编代码转换为机器码(目标文件);链接:将目标文件和库合并为可执行文件;ELF是Linux下的可执行文件格式,EXE是Windows下的。


Q94: ThreadLocal的作用是什么?

【核心解析】 提供线程局部变量,每个线程拥有独立副本;用于解决线程安全问题,避免共享变量竞争;常用于存储用户会话、数据库连接等线程上下文;内部通过ThreadLocalMap实现,key为弱引用。


Q95: ArrayList和LinkedList的区别?

【核心解析】 ArrayList基于动态数组,LinkedList基于双向链表;ArrayList随机访问快O(1),LinkedList增删快O(1)(已知位置);ArrayList内存连续,LinkedList分散;ArrayList扩容开销大,LinkedList无扩容;ArrayList适合读多写少,LinkedList适合频繁插入删除。


Q96: 解释Java中HashSet的原理。

【核心解析】 基于HashMap实现;存储键值对,值固定为PRESENT;hashCode和equals方法;哈希冲突处理;扩容机制;线程不安全


Q97: 解释Java中Vector的底层原理。

【核心解析】 动态数组实现;扩容机制(默认2倍);线程安全(synchronized);与ArrayList对比;随机访问;迭代器


Q98: 解释Java中sort方法的底层原理。

【核心解析】 TimSort算法;混合排序(归并+插入+快排);稳定性;时间复杂度O(n log n);空间复杂度;优化策略


Q99: C++中,基类指针指向子类对象,子类有一个和基类同名的成员函数,但基类的函数并不是虚函数,最终会调用哪个类的函数?请解释静态绑定和动态绑定的区别,并说明构造函数为什么不能是虚函数。

【核心解析】 调用基类函数,因为非虚函数是静态绑定;静态绑定在编译期确定,动态绑定在运行期确定;构造函数不能是虚函数,因为虚函数表在构造完成后才建立。


Q100: C++中static和const的多种用法和区别是什么?

【核心解析】 static修饰局部变量延长生命周期,修饰全局变量限制作用域,修饰函数限制作用域,修饰类成员表示属于类;const修饰变量表示只读,修饰指针表示指向常量或指针本身常量,修饰成员函数表示不修改对象;static const组合表示静态常量。


Q101: C++中静态初始化是如何实现的?例如声明一个1万长度的数组,只有135个元素给了具体值,这么大的数据是怎么实现初始化的?有哪些机制?在哪个阶段?

【核心解析】 静态初始化在编译期完成,未显式初始化的元素默认初始化为0;编译器生成初始化数据段,在程序加载时由启动代码复制到内存;机制包括.data段和.bss段;阶段在main函数执行前。


Q102: Linux下文件描述符、线程同步、内存分配释放等常见问题。

【核心解析】 文件描述符是非负整数,用于标识打开的文件;线程同步方式包括互斥锁、条件变量、信号量等;内存分配使用new/delete或malloc/free,注意匹配释放。


Q103: 内存泄漏常见排查方法有哪些?

【核心解析】 使用valgrind检测;使用AddressSanitizer;分析堆转储文件;代码审查;使用智能指针。


Q104: ArrayList是线程安全的吗?List里面有哪些是线程安全的?

【核心解析】 ArrayList非线程安全;线程安全List:Vector、Collections.synchronizedList、CopyOnWriteArrayList。


Q105: ConcurrentHashMap如何保证线程安全的?

【核心解析】 分段锁(Java7)、CAS+synchronized(Java8);使用volatile保证可见性;红黑树优化链表。


Q106: final关键字的作用是什么?

【核心解析】 修饰类不可继承;修饰方法不可重写;修饰变量不可变(基本类型值不变,引用类型指向不变)。


Q107: C++智能指针(如unique_ptr、shared_ptr)的原理是什么?为什么需要RAII?引用计数的代价是什么?

【核心解析】 智能指针利用RAII管理资源,自动释放;unique_ptr独占所有权,支持移动;shared_ptr共享所有权,通过引用计数管理,计数线程安全有开销;引用计数导致循环引用问题,需weak_ptr。


Q108: C++虚函数表的工作原理是什么?对象内存布局如何?不同编译器实现有何差异?

【核心解析】 虚函数表(vtable)存储虚函数指针,每个含虚函数的类有一个;对象内存布局包含虚指针(vptr)指向vtable;多继承下可能有多个vptr;不同编译器在布局顺序、虚基类处理上存在差异。