Java试题大全,按这个准备面试问啥都不怕!

Java试题大全,按这个准备面试问啥都不怕!
最新回答
辞慾

2023-03-10 22:52:45

Java试题大全

一、Java基础

  • String类为什么是final的

    线程安全:String类不可变保证了其线程安全,多个线程可以安全地共享同一个String对象。

    安全性:String被广泛用于类加载、网络连接、文件操作等场景,不可变性确保了这些操作的正确性。

    缓存hash值:String的hash值在第一次计算后会被缓存,不可变性使得hash值可以重复使用,提高了性能。

    字符串常量池:String的不可变性使得字符串常量池的实现成为可能,节省了内存空间。

  • HashMap的源码,实现原理,底层结构

    实现原理:HashMap基于哈希表实现,通过哈希函数将键映射到数组的索引位置。

    底层结构:由数组和链表(或红黑树)组成,数组用于存储键值对,链表或红黑树用于解决哈希冲突。

    哈希冲突:当两个键的哈希值相同时,使用链表或红黑树存储这些键值对。

    扩容机制:当元素数量超过阈值时,HashMap会进行扩容,重新计算所有元素的哈希值并分配到新的数组中。

  • ArrayList和LinkedList各自实现和区别

    ArrayList:基于动态数组实现,支持快速随机访问,插入和删除操作在数组末尾效率较高,但在数组中间或开头效率较低。

    LinkedList:基于双向链表实现,插入和删除操作在任何位置效率都较高,但随机访问效率较低。

    区别:ArrayList适合读多写少的场景,LinkedList适合写多读少的场景。

  • Java中的队列都有哪些,有什么区别

    ArrayQueue:基于数组实现的有界队列。

    LinkedList:基于链表实现的无界队列。

    PriorityQueue:基于堆实现的优先级队列。

    ConcurrentLinkedQueue:基于链表实现的无界并发队列。

    ArrayBlockingQueue:基于数组实现的有界阻塞队列。

    LinkedBlockingQueue:基于链表实现的有界阻塞队列。

    区别:主要在于实现方式、有界性、并发性以及是否支持优先级。

  • 反射中,Class.forName和classloader的区别

    Class.forName:不仅加载类,还会执行类的静态初始化块。

    ClassLoader:仅加载类,不执行静态初始化块。

    应用场景:Class.forName常用于数据库驱动加载,ClassLoader常用于自定义类加载器。

  • Java7、Java8的新特性

    Java7:switch语句支持String类型、try-with-resources语句、泛型实例化类型推断、数字字面量下划线支持、NIO 2.0等。

    Java8:Lambda表达式、Stream API、函数式接口、默认方法、Optional类、新的日期时间API等。

  • Java数组和链表两种结构的操作效率

    数组:随机访问效率高,插入和删除操作在数组末尾效率较高,但在数组中间或开头效率较低。

    链表:插入和删除操作在任何位置效率都较高,但随机访问效率较低。

  • Java内存泄露的问题调查定位:jmap,jstack的使用

    jmap:用于生成堆转储快照,可以查看堆内存中的对象分布情况。

    jstack:用于生成线程快照,可以查看线程的调用栈信息,帮助定位死锁或线程阻塞问题。

  • string、stringbuilder、stringbuffer区别

    String:不可变字符串,线程安全。

    StringBuilder:可变字符串,非线程安全,性能较高。

    StringBuffer:可变字符串,线程安全,性能较低。

  • Hashtable和HashMap的区别

    线程安全:Hashtable是线程安全的,HashMap是非线程安全的。

    性能:Hashtable性能较低,HashMap性能较高。

    Null值:Hashtable不允许键或值为null,HashMap允许一个键为null,多个值为null。

  • 异常的结构,运行时异常和非运行时异常,各举个例子

    异常结构:Throwable是所有异常和错误的超类,Exception是异常的超类,RuntimeException是运行时异常的超类。

    运行时异常:如NullPointerException、ArrayIndexOutOfBoundsException等。

    非运行时异常:如IOException、SQLException等。

  • String a= “abc” String b = "abc" String c = new String("abc") String d = "ab" + "c" .他们之间用 == 比较的结果

    a == b:true,因为a和b指向字符串常量池中的同一个对象。

    a == c:false,因为c是通过new关键字创建的新对象,位于堆中。

    a == d:true,因为d在编译时会被优化为"abc",指向字符串常量池中的同一个对象。

  • String 类的常用方法

    length():返回字符串的长度。

    charAt(int index):返回指定索引处的字符。

    substring(int beginIndex):返回从beginIndex开始的子字符串。

    equals(Object obj):比较字符串内容是否相等。

    indexOf(String str):返回指定子字符串的索引位置。

    trim():去除字符串两端的空白字符。

  • Java 的引用类型有哪几种

    强引用:最常见的引用类型,只要强引用存在,对象就不会被垃圾回收。

    软引用:用于描述有用但非必需的对象,内存不足时会被垃圾回收。

    弱引用:用于描述非必需对象,无论内存是否充足,下次垃圾回收时都会被回收。

    虚引用:主要用于跟踪对象被垃圾回收的活动,无法通过虚引用获取对象实例。

  • 抽象类和接口的区别

    定义方式:抽象类使用abstract关键字定义,接口使用interface关键字定义。

    方法实现:抽象类可以包含抽象方法和具体方法,接口只能包含抽象方法(Java8后可以有默认方法和静态方法)。

    变量:抽象类可以包含实例变量,接口只能包含公共静态常量。

    继承:一个类只能继承一个抽象类,但可以实现多个接口。

  • Java的基础类型和字节大小

    byte:1字节

    short:2字节

    int:4字节

    long:8字节

    float:4字节

    double:8字节

    char:2字节

    boolean:1字节(JVM实现可能不同)

  • Hashtable,HashMap,ConcurrentHashMap 底层实现原理与线程安全问题

    Hashtable:使用synchronized关键字保证线程安全,性能较低。

    HashMap:非线程安全,使用数组和链表(或红黑树)实现。

    ConcurrentHashMap:使用分段锁(Java7)或CAS+synchronized(Java8)保证线程安全,性能较高。

  • Hash冲突怎么办?哪些解决散列冲突的方法

    开放定址法:线性探测、二次探测、双重哈希等。

    链地址法:使用链表或红黑树存储哈希冲突的元素。

    再哈希法:使用多个哈希函数计算哈希值。

    建立公共溢出区:将所有哈希冲突的元素存储在公共溢出区中。

  • HashMap冲突很厉害,最差性能,你会怎么解决?从O(n)提升到log(n)咯,用二叉排序树的思路说了一通

    解决思路:当链表长度超过阈值时,将链表转换为红黑树,将查找时间复杂度从O(n)降低到O(log n)。

  • rehash

    定义:当HashMap的元素数量超过阈值时,会进行扩容,重新计算所有元素的哈希值并分配到新的数组中,这个过程称为rehash。

    目的:减少哈希冲突,提高查找效率。

  • hashCode() 与 equals() 生成算法、方法怎么重写

    重写原则:如果两个对象相等(equals方法返回true),则它们的hashCode值必须相等;反之不成立。

    重写步骤

    重写equals方法,确保逻辑正确。

    重写hashCode方法,使用相同的字段计算哈希值。

    确保hashCode方法计算结果一致且分布均匀。

二、Java IO

  • 讲讲IO里面的常见类,字节流、字符流、接口、实现类、方法阻塞

    字节流:InputStream、OutputStream及其子类,如FileInputStream、FileOutputStream等。

    字符流:Reader、Writer及其子类,如FileReader、FileWriter等。

    接口:Closeable、Flushable、Readable、Appendable等。

    方法阻塞:如read方法在读取数据时会阻塞,直到有数据可读或到达文件末尾。

  • 讲讲NIO

    定义:NIO(New IO)是Java提供的非阻塞IO API,支持面向缓冲区、基于通道的IO操作。

    核心组件:Channel、Buffer、Selector。

    特点:非阻塞、高性能、支持异步IO。

  • String 编码UTF-8 和GBK的区别

    UTF-8:变长编码,支持全球所有语言,一个字符可能占用1-4个字节。

    GBK:双字节编码,主要用于中文,一个字符占用2个字节。

  • 什么时候使用字节流、什么时候使用字符流

    字节流:处理二进制数据,如图片、音频、视频等。

    字符流:处理文本数据,如TXT文件、XML文件等。

  • 递归读取文件夹下的文件,代码怎么实现

public void listFiles(File dir) { if (dir.isDirectory()) { File[] files = dir.listFiles(); if (files != null) { for (File file : files) { listFiles(file); } } } else { System.out.println(dir.getAbsolutePath()); }}

三、Java Web

  • session和cookie的区别和联系,session的生命周期,多个服务部署时session管理

    区别:session存储在服务器端,cookie存储在客户端;session用于跟踪用户状态,cookie用于存储用户偏好或身份信息。

    联系:session依赖cookie存储session ID。

    生命周期:session的生命周期由服务器配置决定,默认30分钟不活动后失效。

    多服务部署:使用session复制、session共享(如Redis)或令牌机制管理session。

  • servlet的一些相关问题

    生命周期:init、service、destroy。

    请求处理:doGet、doPost等方法。

    转发与重定向:forward和sendRedirect的区别。

  • webservice相关问题

    定义:WebService是一种跨平台的、基于XML的远程调用技术。

    协议:SOAP、WSDL、UDDI。

    实现:JAX-WS、JAX-RS等。

  • jdbc连接,forname方式的步骤,怎么声明使用一个事务。举例并具体代码

// 加载驱动Class.forName("com.mysql.jdbc.Driver");// 建立连接Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "user", "password");// 关闭自动提交,开启事务conn.setAutoCommit(false);try { // 执行SQL Statement stmt = conn.createStatement(); stmt.executeUpdate("INSERT INTO users (name) VALUES ('Alice')"); stmt.executeUpdate("INSERT INTO users (name) VALUES ('Bob')"); // 提交事务 conn.commit();} catch (SQLException e) { // 回滚事务 conn.rollback();} finally { // 关闭连接 conn.close();}
  • 无框架下配置web.xml的主要配置内容

    servlet配置:servlet、servlet-mapping。

    监听器配置:listener。

    过滤器配置:filter、filter-mapping。

    会话配置:session-config。

    欢迎文件列表:welcome-file-list。

  • jsp和servlet的区别

    JSP:本质上是Servlet,侧重于视图展示,支持HTML标签和JSP标签。

    Servlet:侧重于逻辑处理,生成动态内容。

四、JVM

  • Java的内存模型以及GC算法

    内存模型:程序计数器、虚拟机栈、本地方法栈、堆、方法区。

    GC算法:标记-清除、复制、标记-整理、分代收集。

  • JVM性能调优都做了什么

    堆内存调整:设置合适的堆大小和新生代/老年代比例。

    选择合适的GC算法:根据应用特点选择Serial、Parallel、CMS或G1。

    监控工具:使用jstat、jmap、jstack等工具监控JVM状态。

  • 介绍JVM中7个区域,然后把每个区域可能造成内存的溢出的情况说明

    程序计数器:不会溢出。

    虚拟机栈:栈深度过大导致StackOverflowError。

    本地方法栈:同虚拟机栈。

    :对象过多导致OutOfMemoryError: Java heap space。

    方法区:类过多导致OutOfMemoryError: Metaspace(Java8后)。

    运行时常量池:常量过多导致OutOfMemoryError: Metaspace。

    直接内存:通过ByteBuffer.allocateDirect分配过多内存导致OutOfMemoryError。

  • 介绍GC 和GC Root不正常引用

    GC:垃圾回收机制,自动回收不再使用的对象内存。

    GC Root:作为垃圾回收起点的对象,如虚拟机栈中的引用、方法区中的静态引用等。

    不正常引用:如内存泄漏导致的对象无法被回收。

  • 自己从classload 加载方式,加载机制说开去,从程序运行时数据区,讲到内存分配,讲到String常量池,讲到JVM垃圾回收机制,算法,hotspot

    类加载机制:加载、验证、准备、解析、初始化。

    运行时数据区:程序计数器、虚拟机栈、本地方法栈、堆、方法区。

    内存分配:对象在堆中分配内存,String常量池在方法区(Java8后位于堆中)。

    垃圾回收机制:分代收集,使用不同的GC算法。

    HotSpot:Oracle的JVM实现,支持多种GC算法和优化技术。

  • JVM如何分配直接内存, new 对象如何不分配在堆而是栈上,常量池解析

    直接内存分配:通过ByteBuffer.allocateDirect分配。

    栈上分配:通过逃逸分析确定对象是否可以在栈上分配(JIT优化)。

    常量池解析:字符串常量池在类加载时解析并存储字符串字面量。

  • 数组多大放在 JVM 老年代(不只是设置 PretenureSizeThreshold ,问通常多大,没做过一问便知)

    PretenureSizeThreshold:默认值为0,表示所有对象都先在新生代分配。

    实际大小:通常大于1MB的对象会直接在老年代分配(取决于具体JVM实现和配置)。

  • 老年代中数组的访问方式

    直接访问:通过数组索引直接访问元素。

    系统调用:对于大数组,可能需要通过系统调用访问内存。

  • GC 算法,永久代对象如何 GC , GC 有环怎么处理

    永久代对象GC:通过Full GC回收永久代中的无用类。

    GC有环处理:使用可达性分析算法,从GC Root出发标记所有可达对象,未被标记的对象视为垃圾。

  • 谁会被 GC ,什么时候 GC

    被GC的对象:不再被任何GC Root引用的对象。

    GC时机:当Eden区满时触发Minor GC,当老年代满时触发Full GC。

  • 如果想不被 GC 怎么办

    保持引用:确保对象始终被GC Root引用。

    使用软引用或弱引用:根据需要控制对象的生命周期。

  • 如果想在 GC 中生存 1 次怎么办

    finalize方法:重写finalize方法,在对象被回收前执行一些操作(不推荐使用)。

五、开源框架

  • hibernate和ibatis的区别

    Hibernate:全自动化ORM框架,支持HQL查询,缓存机制完善。

    iBatis:半自动化ORM框架,需要手动编写SQL,灵活性高。

  • 讲讲mybatis的连接池

    内置连接池:MyBatis内置了一个简单的连接池,支持配置最大连接数和最大活跃连接数。

    第三方连接池:支持与DBCP、C3P0、Druid等第三方连接池集成。

  • Spring框架中需要引用哪些jar包,以及这些jar包的用途

    spring-core:核心工具类。

    spring-beans:Bean支持。

    spring-context:上下文支持。

    spring-aop:AOP支持。

    spring-tx:事务支持。

    spring-jdbc:JDBC支持。

    spring-web:Web支持。

    spring-webmvc:MVC支持。

  • SpringMVC的原理

    前端控制器:DispatcherServlet接收请求。

    处理器映射:HandlerMapping找到处理请求的Controller。

    处理器适配器:HandlerAdapter调用Controller方法。

    视图解析:ViewResolver解析视图并渲染响应。

  • SpringMVC注解的意思

    @Controller:标识一个类为Controller。

    @RequestMapping:映射请求URL到处理方法。

    @RequestParam:绑定请求参数到方法参数。

    @ModelAttribute:绑定请求参数到模型对象。

    @ResponseBody:将方法返回值直接写入响应体。

  • Spring中beanFactory和ApplicationContext的联系和区别

    BeanFactory:基础IoC容器,延迟加载Bean。

    ApplicationContext:高级IoC容器,预加载Bean,支持AOP、事件传播等。

    联系:ApplicationContext继承自BeanFactory。

  • Spring注入的几种方式(循环注入)

    构造器注入:通过构造器参数注入依赖。

    Setter注入:通过Setter方法注入依赖。

    字段注入:通过反射直接注入字段(不推荐)。

    循环注入:通过构造器注入会导致循环依赖问题,可通过Setter注入或@Lazy注解解决。

  • Spring如何实现事务管理的

    声明式事务:通过@Transactional注解配置事务。

    编程式事务:通过TransactionTemplate或PlatformTransactionManager手动管理事务。

  • Spring IOC

    定义:控制反转,将对象的创建和管理交给容器。

    实现方式:依赖注入(DI)。

  • Spring AOP的原理

    动态代理:通过JDK动态代理或CGLIB动态代理实现AOP。

    切面编程:将横切关注点(如日志、事务)模块化。

  • Hibernate中的1级和2级缓存的使用方式以及区别原理(Lazy-Load的理解)

    一级缓存:Session级别的缓存,默认开启,用于减少数据库访问。

    二级缓存:SessionFactory级别的缓存,需要手动配置,用于跨Session缓存对象。

    Lazy-Load:延迟加载,只有在真正访问对象时才加载数据,提高性能。

  • Hibernate的原理体系架构,五大核心接口,Hibernate对象的三种状态转换,事务管理

    五大核心接口:Session、SessionFactory、Transaction、Query、Configuration。

    对象状态:临时态、持久态、游离态。

    事务管理:通过Transaction接口管理事务。

六、多线程

  • Java创建线程之后,直接调用start()方法和run()的区别

    start():启动新线程,调用run()方法。

    run():直接在当前线程执行run()方法,不会启动新线程。

  • 常用的线程池模式以及不同线程池的使用场景

    newFixedThreadPool:固定大小线程池,适用于负载较重的服务器。

    newCachedThreadPool:可缓存线程池,适用于负载较轻的服务器。

    newScheduledThreadPool:定时任务线程池,适用于定时任务执行。

    newSingleThreadExecutor:单线程线程池,适用于需要顺序执行的场景。

  • newFixedThreadPool此种线程池如果线程数达到最大值后会怎么办,底层原理

    处理方式:任务会被放入队列等待执行。

    底层原理:使用LinkedBlockingQueue作为任务队列,线程从队列中获取任务执行。

  • 多线程之间通信的同步问题,synchronized锁的是对象,衍伸出和synchronized相关很多的具体问题,例如同一个类不同方法都有synchronized锁,一个对象是否可以同时访问。或者一个类的static构造方法加上synchronized之后的锁的影响

    同步问题:synchronized锁的是对象,确保同一时间只有一个线程可以访问锁定的代码块。

    不同方法:同一个对象的不同synchronized方法不能同时被访问。

    static方法:synchronized static方法锁的是类对象,与实例方法互斥。

  • 了解可重入锁的含义,以及ReentrantLock 和synchronized的区别

    可重入锁:同一个线程可以多次获取同一把锁。

    区别

    ReentrantLock:需要手动释放锁,支持公平锁、超时锁等高级特性。

    synchronized:自动释放锁,使用简单,但功能较少。

  • 同步的数据结构,例如concurrentHashMap的源码理解以及内部实现原理,为什么他是同步的且效率高

    内部实现:Java7使用分段锁,Java8使用CAS+synchronized。

    高效原因:通过减少锁的粒度(如分段锁或桶锁)提高并发性能。

  • AtomicInteger和volatile等线程安全操作的关键字的理解和使用

    AtomicInteger:基于CAS实现的原子整数,保证线程安全。

    volatile:保证变量的可见性,但不保证原子性。

  • 线程间通信,wait和notify

    wait:释放锁并等待其他线程通知。

    notify:唤醒一个等待的线程。

    notifyAll:唤醒所有等待的线程。

  • 定时线程的使用

    Timer:单线程定时任务执行器。

    ScheduledExecutorService:多线程定时任务执行器,推荐使用。

  • 场景:在一个主线程中,要求有大量(很多很多)子线程执行完之后,主线程才执行完成。多种方式,考虑效率

    CountDownLatch:通过计数器等待所有子线程完成。

    CyclicBarrier:通过屏障等待所有子线程到达某一点。

    CompletableFuture:通过异步任务组合等待所有子线程完成。

  • 进程和线程的区别

    进程:资源分配的基本单位,拥有独立的内存空间。

    线程:CPU调度的基本单位,共享进程的内存空间。

  • 什么叫线程安全?举例说明

    定义:当多个线程访问某个类、对象或方法时,不会引起意外的结果。

    例子:Vector是线程安全的,ArrayList是非线程安全的。

  • 线程的几种状态

    新建:线程被创建但未启动。

    可运行:线程正在等待CPU资源。

    运行:线程正在执行。

    阻塞:线程因某种原因暂停执行。

    死亡:线程执行完毕或异常退出。

  • 并发、同步的接口或方法

    并发接口:Callable、Future、Runnable。

    同步方法:synchronized方法、ReentrantLock。

  • HashMap 是否线程安全,为何不安全。 ConcurrentHashMap,线程安全,为何安全。底层实现是怎么样的

    HashMap:非线程安全,多线程下可能导致数据不一致或死循环。

    ConcurrentHashMap:线程安全,通过分段锁(Java7)或CAS+synchronized(Java8)实现。

  • J.U.C下的常见类的使用。 ThreadPool的深入考察; BlockingQueue的使用。(take,poll的区别,put,offer的区别);原子类的实现

    ThreadPool:线程池管理,如ExecutorService、ScheduledExecutorService。

    BlockingQueue:take阻塞直到有元素可取,poll非阻塞;put阻塞直到有空间可放,offer非阻塞。

    原子类:基于CAS实现,如AtomicInteger、AtomicReference。

  • 简单介绍下多线程的情况,从建立一个线程开始。然后怎么控制同步过程,多线程常用的方法和结构

    建立线程:继承Thread类或实现Runnable接口。

    同步控制:使用synchronized、ReentrantLock、CountDownLatch等。

    常用方法:start、join、wait、notify、sleep等。

  • Volatile的理解

    定义:保证变量的可见性,但不保证原子性。

    使用场景:状态标志、一次性发布等。

  • 实现多线程有几种方式,多线程同步怎么做,说说几个线程里常用的方法

    实现方式:继承Thread类、实现Runnable接口、使用Callable和Future。

    同步方式:synchronized、ReentrantLock、Semaphore等。

    常用方法:start、join、wait、notify、sleep等。

七、网络通信

  • HTTP是无状态通信,HTTP的请求方式有哪些,可以自己定义新的请求方式么

    请求方式:GET、POST、PUT、DELETE、HEAD、OPTIONS、TRACE、CONNECT。

    自定义请求方式:理论上可以,但服务器和客户端需支持。

  • Socket通信,以及长连接,分包,连接异常断开的处理

    Socket通信:基于TCP/IP协议的网络通信。

    长连接:保持连接不断开,减少握手开销。

    分包:通过协议头指定数据长度或使用分隔符分包。

    异常处理:通过心跳机制检测连接状态,超时后重连。

  • Socket通信模型的使用,AIO和NIO

    BIO:阻塞式IO,一个线程处理一个连接。

    NIO:非阻塞式IO,一个线程处理多个连接。

    AIO:异步IO,操作系统完成IO操作后通知应用。

  • Socket框架netty的使用,以及NIO的实现原理,为什么是异步非阻塞

    Netty:基于NIO的高性能网络框架,支持异步非阻塞通信。

    NIO原理:通过Selector监听多个Channel的事件,实现一个线程处理多个连接。

    异步非阻塞:IO操作不会阻塞线程,通过回调或Future处理结果。

  • 同步和异步,阻塞和非阻塞

    同步:调用方等待被调用方返回结果。

    异步:调用方不等待被调用方返回结果,通过回调或Future处理结果。

    阻塞:调用方在等待结果时被挂起,无法执行其他操作。

    非阻塞:调用方在等待结果时继续执行其他操作。

  • OSI七层模型,包括TCP,IP的一些基本知识

    七层模型:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。

    TCP/IP模型:网络接口层、网络层、传输层、应用层。

    TCP:面向连接的、可靠的传输协议。

    IP:网络层协议,负责数据包的路由和转发。

  • HTTP中,GET和POST的区别

    GET:请求数据附加在URL后,有长度限制,