53常见初级面试题总结

Java基础

Java程序的运行原理?

  • 一般运行一个Java程序的时候会点击运行按钮,按运行按钮的时候发生了什么呢?
  • .java文件被执行编译生成.class文件,被JVM识别和加载,编译生成的.class文件在target目录
  • 启动:在idea的下面Run可以看到 有个拼了很长的字符串,在里面可以找到target目录,JVM的运行只和这些字节码有关
  • 跨平台性
    • 怎么能让同样的一份代码与不同的系统进行通信
    • 每一个平台上面都自己的JVM实现,JVM负责把统一的字节码翻译成底层的系统调用

JDK/JRE有什么区别?

  • JDK = JRE + javac
    • JDK包含了JRE,同时还包含了编译java源码的编译器javac,还包含了很多java程序调试和分析的工具
  • JDK:Java Development Kit java(开发工具包)
  • JRE:Java Runtime Environmen (java运行时环境)
  • 如果需要运行java程序,只需安装JRE。如果需要编写java程序,需要安装JDK。

Java的基础类型有哪些? char/byte/

  • String是基本数据类型么?

Java的参数传递是传值还是传引用?

  • Java世界中的一切对象都是指针(地址)
  • 函数调用永远是传值

StringBuffer/StringBuilder 的区别/线程安全性?

  • 如果没有额外声明,所有的类默认都是线程不安全的
  • StringBuilder更快,但是线程不安全,更加常用
  • StringBuffer稍慢,但是线程安全

Object中有哪些方法?

String中有哪些方法?

面向对象

==/equals有什么区别?

  • == 解读
    • 基本类型:比较的是值是否相同;
    • 引用类型:比较的是引用是否相同;
  • equals 解读
    • equals 本质上就是 ==,只不过 String 和 Integer 等重写了 equals 方法,把它变成了值比较
  • == 对于基本类型来说是值比较,对于引用类型来说是比较的是引用;而 equals 默认情况下是引
    用比较,只是很多类重新了 equals 方法,比如 String、Integer 等把它变成了值比较,所以一般情况下
    equals 比较的是值是否相等。

深拷贝/浅拷贝有什么区别?

  • 浅克隆:当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有
    复制。
  • 深克隆:除了对象本身被复制外,对象所包含的所有成员变量也将复制

接口和抽象类有什么区别/联系?

  • Interface:定义功能,只能包含方法(实现),不能包含成员 变量,可以被实现若干次
  • Abstract class:定义抽象的骨架实现,可以包含抽象方法或 者具体实现,也可以包含成员变量,只能沿着一条路径继承
  • 实现数量:类可以实现很多个接口;但是只能继承一个抽象类。
  • 访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符。

什么时候用接口/抽象类?

  • 明确想不想类里面有成员变量,有成员变量只能用抽象类
  • 如果没有成员变量,两个都可以用,接口更灵活,用抽象类被限制继承体系

final的作用是什么?

  • 是修饰符,如果修饰类,此类不能被继承;如果修饰方法和变量,则表示此方法和此变量不能在
    被改变,只能使用。

override和overload有什么区别?

  • 重载: 发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和
    访问修饰符可以不同,发生在编译时。
  • 重写: 发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围
    小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为 private 则子类就不能重写该方法。

集合框架

HashMap 原理?

  • 扩容/并发问题

List/Set/Map 区别

List、Set、Map 的区别主要体现在两个方面:元素是否有序、是否允许元素重复。
三者之间的区别,如下表:
1、List、Set都是继承自Collection接口,Map则不是
2、List特点:元素有放入顺序,元素可重复 ,Set特点:元素无放入顺序,元素不可重复,重复元素会
覆盖掉,(注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位
置其实是固定的,加入Set 的Object必须定义equals()方法 ,另外list支持for循环,也就是通过下标来
遍历,也可以用迭代器,但是set只能用迭代,因为他无序,无法用下标来取得想要的值。)
3、Set和List对比:
Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素
位置改变。
4、Map适合储存键值对的数据
5、线程安全集合类与非线程安全集合类 :
LinkedList、ArrayList、HashSet是非线程安全的,Vector是线程安全的;
HashMap是非线程安全的,HashTable是线程安全的;
StringBuilder是非线程安全的,StringBuffer是线程安全的。

HashMap 和HashTable 区别?

  • 存储:HashMap 运行 key 和 value 为 null,而 Hashtable 不允许。
    线程安全:Hashtable 是线程安全的,而 HashMap 是非线程安全的。
    推荐使用:在 Hashtable 的类注释可以看到,Hashtable 是保留类不建议使用,推荐在单线程环境下
    使用 HashMap 替代,如果需要多线程使用则用 ConcurrentHashMap 替代。

ConcurrentHashMap 原理?

  • JDK1.7 首先将数据分为一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数
    据时,其他段的数据也能被其他线程访问。
  • JDK1.8 ConcurrentHashMap 取消了 Segment 分段锁,采用 CAS 和 synchronized 来保证并发安全。数据
    结构跟 HashMap1.8 的结构类似,数组+链表/红黑二叉树。
    synchronized 只锁定当前链表或红黑二叉树的首节点,这样只要 hash 不冲突,就不会产生并发,效
    率又提升 N 倍。

HashSet原理

  • HashSet 是基于 HashMap 实现的,HashSet 底层使用 HashMap 来保存所有元素,因此 HashSet 的
    实现比较简单,相关 HashSet 的操作,基本上都是直接调用底层 HashMap 的相关方法来完成
  • HashMap key的集合拿出来就是一个Set

TreeSet 原理?

  • 元素有序,插入/删除高效
  • 红黑树(自平衡的排序二叉树。)

equals/hashCode区别/何时使用?

hashCode 决定一个元素在哈希表被丢到哪个桶中去,但是有可能两个对象的hashCode是一样的,这时候怎么判断这个对象是不是我想找的对象呢,这时候用equals

hashcode是系统用来快速检索对象而使用

equals方法本意是用来判断引用的对象是否一致

如果重写了equals方法,那么一定要重写hashCode

使用和重写这两个方法时的约定

  1. 如果两个对象通过equals比较的结果为true, 那么它们的hashCode也必须一样
  2. 如果两个对象的hashCode相等,那么这两个对象不一定相等(即equals不一定返回true)

ArrayList/LinkedList 区别?

  • 数据结构实现:ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。

  • 随机访问效率:ArrayList 比 LinkedList 在随机访问的时候效率要高,因为 LinkedList 是线性的数据存
    储方式,所以需要移动指针从前往后依次查找。

  • 增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高,因为 ArrayList
    增删操作要影响数组内的其他数据的下标。

ArrayList的实现用的是数组,LinkedList是基于链表,ArrayList适合查找,LinkedList适合增删

哪些集合类是线程安全的?

  • HashTable/ConcurrentHashSet

如何保证一个集合类不被修改?

  • Collections.unmodifiableXXX
  • Guava 的ImmutableXXX

ArrayList/Vector 区别

  • 基于数组的自动扩容实现
  • Vector线程安全,但是慢,被废弃了 ;ArrayList不安全,但是效率高

说一些常见的List/Set/Map实现?

  • List
    • ArrayList
    • LinkedList
  • Set
    • HashSet
    • TreeSet
    • LinkedHashSet
  • Map
    • HashMap
    • LinkedHashMap
    • TreeMap
    • ConcurrentHashMap

Collection 和C ollections 有什么区别?

  • X是类名的话,Xs就是与之相关的工具方法集合。

Java的异常体系结构?

Throwable 任何异常/错误的超类 checked

  • Exception 异常,可以从异常状态中恢复

    • RuntimeException 预料之外的异常,通常代表一个bug,unchecked
    • 其他Exception 预料之中的异常,代表编程中预期的异常状态,checked
  • Error 无法恢复的异常状态 unchecked

什么是 checked/unchecked/runtime exception?

受检查的异常(checked) 必须要用 throws 语句在方法或者是构造函数上声明。

不受检查的异常(unchecked) 不需要在方法或者是构造函数上声明。

  • CheckException发生在编译阶段,必须要使用try catch (或者throws )否则译不通过。

  • UncheckedException发生在运行期,具有不确定性,主要是由于程序的逻辑问题所引起的,难以排查,我们一 般都需要纵观全局才能够发现这类的异常错误,所以在程序设计中需要认真考虑,好好写代码,尽量处理异常m,即使产生了异常,也能尽量保证程序朝着有利方向友展。

  • RuntimeException 是UncheckedException 的一个别名

  • try/catch/finally 的执行顺序?

    • try中任何可以被抛出的东西(异常或者Error)的语句,会阻止try中抛异常后面的语句执行,然后JVM寻找匹配的catch块
    • try中没有抛出异常,则catch语句不执行,如果有finally语句,则接着执行finally语句
    • 不管有木有出现异常,finally块中代码都会执行;
    • 当try...catch中有return的话,finally后会执行try...catch中的return,然后不再执行后续语句
    • finally前有return、finally块中也有return,先执行前面的return,保存下来,再执行finally的return,覆盖之前的结果,并返回。
  • catch 中return了 ,finally 还会执行么?

    • finally 一定会执行,即使是 catch 中 return 了,catch 中的 return 会等 finally 中的代码执行完之后,
      才会执行
    • finally中return了,会发生什么事情? 非常不建议在finally里面写
  • throw/throws 的区别

    • throw 关键字用来在程序中明确的抛出异常
    • throws 语句用来表明方法不能处理的异常
  • final/finally/finalize 的区别

    • final:是修饰符,如果修饰类,此类不能被继承;如果修饰方法和变量,则表示此方法和此变量不能在被改变,只能使用。
    • finally:是 try{} catch{} finally{} 最后一部分,表示不论发生任何情况都会执行,finally 部分可以省略,但如果 finally 部分存在,则一定会执行 finally 里面的代码。
    • finalize: 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法。不推荐调用。

计算机体系原理

  • 进程和线程的区别?

    • 进程占用独享的隔离的内存,文件等资源
    • 同一个进程内的线程共享内存/文件等资源
    • 一个程序下至少有一个进程,一个进程下至少有一个线程,一个进程下也可以有多个线程来增加程序的
      执行速度。
    • 进程是系统进行资源分配和调度的一个独立单位,最小的资源管理单位。线程是进程的一个实体,
      是 CPU 调度和分派的基本单位,它是比进程更小的能独立运行的基本单位,最小的 CPU 执行单元。
  • 进程和线程是如何调度的?

  • 大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式

    • 轮转调度 最简单且最公平的方法,给每个进程分配一个时间片。当时间片耗尽时,进程会下CPU并加入到就绪队列的队尾。问题的关键是选择合适的时间片。

    • 在一个进程中,当一个线程任务执行几毫秒后,会由操作系统的内核(负责管理各个任务)进行调度,通过硬件的计数器中断处理器,让该线程强制暂停并将该线程的寄存器放入内存中,通过查看线程列表决定接下来执行哪一个线程,并从内存中恢复该线程的寄存器,最后恢复该线程的执行,从而去执行下一个任务。

    上述过程中,任务执行的那一小段时间叫做时间片,任务正在执行时的状态叫运行状态,被暂停的线程任务状态叫做就绪状态,意为等待下一个属于它的时间片的到来。

    • 线程的调度

    • 线程的调度,取决于支持的是内核级线程还是用户级线程
      对于用户级线程,内核不知道线程的存在,就给了进程很大的自主权。内核只是调度进程,进程中的调度程序选择哪个线程来运行。
      对于内核级线程,线程的调度就交给了系统完成。

Java中的线程和操作系统线程是什么关系?

  • JVM的线程和OS的线程是一一对应的

  • OS辅助调度线程

  • 因此,Java的线程模型饱受诟病

  • 是不是有了协程一切并发问题就不存在了呢?

    • 协程解决的是让线程跑起来更快,切换更灵活
    • 并发问题还会存在,并不解决多线程里 死锁/竞争/临界条件等
  • 协程,英文Coroutines,是一种基于线程之上,但又比线程更加轻量级的存在,这种由程序员自己写程序来管理的轻量级线程叫做『用户空间线程』,具有对内核来说不可见的特性。

    • 特点:线程的切换由操作系统负责调度,协程由用户自己进行调度,因此减少了上下文切换,提高了效率。

计算机网络

tcp/udp的区别?

  • TCP:稳定可靠,纠错/重新发送,比较慢
    • 保证交付
    • 对质量要求很高的场景(文件传输,发送或接收邮件,远程登录等)
  • UDP:快,质量低
    • 尽最大可能交付
    • 对质量要求不高(即时通信,qq聊天,在线视频,网络语音通话等)

TCP协议的三次握手和四次挥手?

  • 三次握手

    (1)第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SEND状态,等待服务器B确认。

    (2)第二次握手:服务器B收到SYN包,必须确认客户A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态。

    (3)第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手。

  • 四次挥手

    (1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。

    (2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。

    (3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A。

    (4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。

从浏览器发出请求到服务器接收到请求发生了什么?

  1. 客户端浏览器通过 DNS 解析到 www.baidu.com 的 IP 地址为 220.181.0.1,
    通过这个 ip 地址找到客户端到服务器的路径,客户端浏览器发起一个 http 会话
    到 220.181.0.1,然后通过 TCP 进行封装数据包,输入到网络层。
  2. 在客户端的传输层,把 HTTP 会话请求分成报文段,添加源和目的端口,
    如服务器端用 80 端口监听客户端的请求,客户端由系统随机选择一个端口,如
    5000,与客户端进行交换,服务器把相应的请求返回给客户端的 5000 端口。然
    后使用 ip 层的 ip 地址查找目的端。
  3. 客户端的网络层不用关心应用层和传输层的东西,主要做的是通过查找路
    由表确定如何到达服务器,期间可能经过多个路由器。
  4. 客户端的链路层,包通过链路层发送到路由器,通过邻居协议查找给定
    的 ip 地址和 MAC 地址,然后发送 ARP 请求查找目的地址,如果得到回应后就可
    以使用 ARP 的请求应答交换的 ip 数据包现在就可以传输了,然后发送 Ip 数据包
    到达服务器的地址。

算法与数据结构

集合类中常见的数据结构

  • ArrayList:数组,随机查找是常熟时间
  • LinkedList:双链表,可当做队列和栈
  • HashSet/HashMap:哈希表
  • TreeSet/TreeMap:红黑树
  • ConcurrentHashMap:分段+哈希表
  • LinkedHashMap:链表+哈希表

链表和二叉查找树的时间复杂度区别

  • ArrayList:寻址O(1)/更新O(n)/二分查找O(lgn)
  • LinkList:寻址O(n)/更新O(1)/查找o(n)
  • 哈希表:都是O(1)
  • 红黑树:都是O(lgn)
  • 二叉查找树:都是O(lgn)

队列和栈分别是什么?

  • 队列:先进先出
    • 应用场景:对于一个多叉树(常见是二叉树)树的层次遍历,最好能手写
  • 栈:后进先出
    • 应用场景:方法栈

Web

常见的http状态码?

  • 2XX一切正常/3XX跳转/4XX客户端异常/5XX服务端异常
  • 200/201/301/302/403/404/502/503/504

GET/POST有什么区别?

  • GET获取资源/POST发送数据
  • GET查询/获取资源,POST用于登录,修改数据
  • GET是幂等的(多次发送和一次发送的结果完全相同)

GET使用URL或Cookie传参,而POST将数据放在BODY中;

GET的URL会有长度上的限制,POST的数据可以非常大;

POST比GET安全,因为数据在地址栏上不可见

Cookie和Session有什么区别?

  • Cookie:随HTTP请求一起发送的一小段标识用户身份的信息

  • Session :放在服务端的,用于通过Cookie和用户身份对应关系来鉴权的数据

    不同点:
    1、无论客户端做怎样的设置,session 都能够正常工作。当客户端禁用 cookie 时将无
    法使用 cookie。
    2、在存储的数据量方面:session 能够存储任意的 java 对象,cookie 只能存储 String
    类型的对象。

什么是跨域?如何解决跨域?

  • JSONP
  • CORS
  • nginx转发(反向代理)

类型与反射

什么是反射?

  • 反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都
    能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语
    言的反射机制。
  • 运行时行为,动态调用

*动态代理的原理是什么?**

  • 动态生成字节码完成一些功能拓展
  • JDK动态代理:方便,手限制(只能代理接口)
  • 字节码增强:不受限制,但是麻烦

动态代理的应用有 spring aop、hibernate 数据查询、测试框架的后端 mock、rpc,Java注解对象获取
等。

反射为什么性能较差?

  • JDK无法预测被调用的方法,因此无法实施优化

什么是序列化?

  • 将Java对象编程字节流的过程叫序列化 serialize
  • 将字节流编程Java对象的过程叫做反序列化 deserialize
  • 可读:JSON/XML
  • 不可读:Java自带的序列化

Spring

什么是loC容器,为什么需要loC

  • IoC控制反转,不需要手工控制各种对象的创建和依赖
  • 由容器帮你完成

AOP与AOP原理

  • 面向一个特定的切面编程,使得重复的逻辑可以在一起编写,方便维护,减少重复。

Bean的生命周期

  • Bean从零开始:从指定的配置文件中加载BeanDefinition,然后Spring容器根据该定义开始进行Bean的装配工作

  • Spring维护了一套完整的生命周期,每个Bean都可以自定义在生命周期任何一个阶段所完成的工作

Spring Boot相对于Spring MVC有哪些改进?

  • 自动化配置:
    • Spring MVC - 通过XML配置,手动指定
    • SpringBoot - 通过注解或者自动化扫描
  • 自带Servlet容器,可以直接启动
    • Spring MVC - 不自带Servlet容器,需要额外配置
    • Spring Boot - 直接打成jar包,可以直接启动
  • Spring Boot对于微服务和快速开发更为友好
    • 优点:大大简化了开发配置的难度
    • 缺点:有很多潜在的默认约定,是的开发者更难深入了解其中的细节
点赞

发表回复

电子邮件地址不会被公开。必填项已用 * 标注