Java基础知识面试总结

目录

String 类能不能被继承?为什么?

final修饰类,修饰方法,修饰变量有什么特点?

 #{} 和 ${} 的区别?

Equals和==区别

java有哪些集合类型?集合类的特点

HashMap和Hashtable的区别

hashmap的底层结构和put方法以及hash计算

ArrayList,Vector, LinkedList的存储性能和特性

重载和重写的区别?

有那些注解

3.java配置类相关注解

HashMap和HashSet Collection 底层不同

接口和抽象类的区别是什么?

常用jar包

常用的接口

如何复制一个对象

array list去重方法

ArrayList 如何保证线程安全

什么是延迟加载(懒加载)

查看进程命令

乐观锁和悲观锁

mycat的分库分表

pom.xml里面的SNSPSHOT的作用

Filter与interceptor的区别(过滤器和拦截器的区别)

@Autowired和@Resource到底有什么区别

推荐构造器注入原因

ResultMap和ResultType区别

双亲委派

JVM内存模型

BIO与NIO、AIO的区别

Java常见的数据结构

多态的实现途径

事务的隔离级别

事务的四个特性(ACID)

事务的传播机制

微服务间的数据一致性问题

maven依赖版本冲突怎么处理

微服务间调用方式

传递时间

动态代理和静态代理

 Jdk1.8特性

maven常用命令

分布式锁,进程锁,线程锁的区别

分布式解决跨域问题

几种常见的长连接实现方案

Object类的常用方法

String 类能不能被继承?为什么?

String因为被final修饰所以不能被继承,而为什么要用final修饰,主要原因为:

1.保证线程安全,不可变对象始终是线程安全的;

2.速度快:final 类无法被继承,这使得 JIT 在处理字符串时可以永远不需要检查被覆盖的方法

final修饰类,修饰方法,修饰变量有什么特点?

1、final修饰的类不可以被继承,但可以继承其他的类。

2、final修饰的方法(使用final修饰方法的原因有两个。1.是把方法锁定,以防任何继承类修改它的含义;2.是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升),子类可以继承但是不能重写。

3、子类重写父类的非final方法可以加上final。

4、被final修饰的基本数据类型或者String类型的变量可以看作是常量,赋值后不能改变。

5、被final修饰的引用数据类型变量的引用内存地址值不能改变,可以改变引用数据类型变量的属性值。

6、被final修饰的普通成员变量必须在对象创建完成前进行赋值,可以直接赋值,如果没有直接赋值则需要用构造方法进行赋值,如果有多个构造方法则多个构造方法都要为其赋值,但是不能用set方法赋值。

7、被final修饰的静态成员变量必须要直接赋值或者静态代码块赋值,否则编译不通过。

8、final修饰的成员变量会在编译阶段赋默认值,final固定的是成员变量的手动赋值不是内存中的默认值

 #{} 和 ${} 的区别?

#{}是预编译处理,${}是字符串替换;

#{}会将{}内的内容替换成? ,这样防止SQL注入;

${}是字符串拼接,将{}内的内容直接替换到SQL语句中;

Equals和==区别

(1)==针对基础数据类型比较的是值,针对引用数据类型比较的是引用地址;

(2)重写equals()方法必须重新hashcode方法比较的是值

equals方法深入解析_equals比较的是地址还是值_小狐狸Rosie的博客-CSDN博客

java有哪些集合类型?集合类的特点

set(集,无序、不能重复)、list(列表,有序、可重复)、map(键值对)

Collection:list(ArrayList、LinkedList、Vector),set(HashSet、TreeSet、LinkedHashSet)  Map:TreeMap、HashMap、HashTa;

集合类的特点:集合类这种框架是高性能的;集合类允许不同类型的集合以相同的方式和高度互操作方式工作;集合类容易扩展和修改

HashMap和Hashtable的区别

相同点:都实现了Map接口,都是键值对,负载因子0.75,相同方法如put,remove

  • 不同点:HashMap可以存放 null   Hashtable不能存放null
  • HashMap不是线程安全的类   Hashtable是线程安全的类;
  • HashMap添加元素使用的是自定义hash算法,Hashtable使用的是key的hashCode
  • HsahMap在数组+链表的结构中引入了红黑树,Hashtable没有红黑树
  • HashMap初始容量为16,Hashtable初始容量为11
  • HsahMap扩容是当前容量翻倍,Hashtable是当前容量翻倍+1
  • 遍历的机制HashMap有一个叫keyset还有一个叫Entryset的两个方法,得到的结果都是Iterator(迭代器)。
  • 而Hashtable有一个叫elements的方法,他的结果是Enumeration,同时Hashtable也能得到key和Entry,所以Hashtable的遍历方式多了一个机制
  • HsahMap只有containsKey和containsValue但是没有contains
  1. hashmap的底层结构和put方法以及hash计算

HashMap的底层有数组 + 链表(红黑树)组成,数组的大小可以在构造方法时设置,默认大小为16,数组中每一个元素就是一个链表,jdk7之前链表中的元素采用头插法插入元素,jdk8之后采用尾插法插入元素,负载因子默认值为0.75,当数组总元素数大于数组长度 * 0.75,数组长度扩容为两倍,没有红黑树下,添加元素后链表的长度超过了8扩容两倍变成32,当达到最大值64时,再加入元素,满足了链表树化条件(1:数组长度达到64, 2:该链表长度达到了8),该链表会转换为红黑树。

根据Node中的hash字段,计算所在的槽位(slot)下标

当当前的位置没有元素时,便将方法传进来的key和value封装为一个node对象,放入这个位置

put过程: 根据Node中的hash字段,计算所在的槽位(slot)下标

当前的位置没有元素时,便将方法传进来的key和value封装为一个node对象,放入这个位置,如果当前位置不为空,并且当前位置里面的node节点还没有链化,比较该位置下的node对象的key与当前put对象的key是否完全相等;如果相等的话,直接替换value;如果不相等的话,采用尾插法在存在的node节点后面进行插入。

如果当前位置不为空,并且当前位置里面的node节点已经链化,迭代查找node,看链表上元素的key,与当前传来的key是否完全一致,一致的话,replace。put之后,还需要检查当前链表的长度,有没有达到树化阈值8。若达到阈值,就调用一个树化方法,具体的树化操作都在这个树化方法里面完成

1、尽可能的减少元素位置的移动。

2、使元素均匀的散布hashmap中,减少hash碰撞

HashMap的存储_hashmap存储_?abc!的博客-CSDN博客

关于HashMap扩容机制_hashmap的扩容机制_祝枝繁的博客-CSDN博客

说一下HashSet和HashMap的底层实现及HashMap的put操作过程_hashset put_余飞军的博客-CSDN博客

  1. ArrayList,Vector, LinkedList的存储性能和特性
  • ArrayList和Vector两者都继承抽象类AbstractList,Vector是线程安全的,ArrayList非线程安全的,

  • Vector扩容是1倍,arraylist是0.5倍

    ArrayList 是数组结构,所以定位很快,但是插入和删除很慢

    LinkedList 是双向链表结构,所以插入和删除很快,但是定位很慢

  • 重载和重写的区别?

1.定义不同---重载是定义相同的方法名,参数不同;重写是子类重写父类的方法。

2.范围不同---重载是在一个类中,重写是子类与父类之间的。

3.多态不同---重载是编译时的多态性,重写是运行时的多态性。

4.返回不同---重载对返回类型没有要求,而重写要求返回类型,有兼容的返回类型。

5.参数不同---重载的参数个数、参数类型、参数顺序可以不同,而重写父子方法参数必须相同。

6.修饰不同---重载对访问修饰没有特殊要求,重写访问修饰符的限制一定要大于被重写方法的访问修饰符

有那些注解

1.声明bean的注解

@Component 组件,没有明确的角色;@Service 在业务逻辑层使用(service层)

@Repository 在数据访问层使用(dao层);@Controller 在展现层使用,控制器的声明

2.注入bean的注解

@Autowired:由Spring提供;@Inject:由JSR-330提供;@Resource:由JSR-250提供

都可以注解在set方法和属性上,推荐注解在属性上(一目了然,少写代码)

3.java配置类相关注解

@Configuration 声明当前类为配置类,相当于xml形式的Spring配置(类上)

@Bean 注解在方法上,声明当前方法的返回值为一个bean,替代xml中的方式(方法上),其中内部组合了@Component注解,表明这个类是一个bean(类上)

@ComponentScan 用于对Component进行扫描,相当于xml中的(类上)

@WishlyConfiguration 为@Configuration与@ComponentScan的组合注解,可以替代这两个注解

4.切面(AOP)相关注解

Spring支持AspectJ的注解式切面编程。

@Aspect 声明一个切面(类上);@After 在方法执行之后执行(方法上)

@Before 在方法执行之前执行(方法上) ;@Around 在方法执行之前与之后执行(方法上

HashMap和HashSet Collection 底层不同

Arraylist ,LinkedList,Hashmap,HashSet,TreeSet,TreeMap,PriorityQueue线程不安全的

接口和抽象类的区别是什么?
  • 接口的所有方法在接口中不能有实现(Java 8 开始接口方法可以有默认实现),而抽象类可以有非抽象的方法。
  • 接口中除了 static、final 变量,不能有其他变量,而抽象类中则不一定。
  • 一个类可以实现多个接口,但只能实现一个抽象类。接口自己本身可以通过 extends 关键字扩展多个接口。
  • 接口方法默认修饰符是 public,抽象方法可以有 public、protected 和 default 这些修饰符(抽象方法就是为了被重写所以不能使用 private 关键字修饰!)。
  • 从设计层面来说,抽象是对类的抽象,是一种模板设计,而接口是对行为的抽象,是一种行为的规范。

接口可以继承接口吗?接口、抽象类、实体类的关系_接口继承接口_GEGEGEHUI的博客-CSDN博客

常用jar包

如spring、oracle驱动、mysql驱动、mybatis、 hibernate、struts、c3p0、cglib、dbcp、dom4j、jstl等

常用的接口

1.java.lang.String:用于创建/操作不可变的字符串文字。

2.java.lang.System :System类的使用取决于你工作的项目类型,你可能没有在项目中使用过它,但它仍然是受欢迎的Java类之一,这是一个不能被实例化的工具类。

这个类的主要用途是访问标准输入、输出、环境变量等等。

3.java.lang.Exception :Throwable是所有错误和异常的超类,所有异常情况的处理都属于Exception类。

NullPointerException在所有的异常中是最受欢迎的,而Exception异常是在所有异常层次结构的顶部。

4.java.util.ArrayList:一个实现数组的数据结构的类。这个类实现了List接口,是最受欢迎的Java集合类的成员,Arr ayList和Vector之间的差异是初学者常见的问题之一,它也经常在java面试中被问到。

5.ava.util.HashMap:一个实现键值对数据结构的类,这个类实现了Map接口,类似比较ArrayList与Vector,Hash Map与Hashtable也是经常拿来比较的。

它也是一个受欢迎的集合类,作为一个属性-值的容器,经常用在应用程序多个层之间的数据传递。

6.java.lang.Object:所有Java类的根类,每一个Java类都是Object类的一个子类,经常使用在平台/框架上。它包含了一些重要方法,比如:equals, hashcode, clone, toString等等。它自从Java诞生的第一天开始可用。

7.java.lang.Thread :线程是一个单一执行的序列,多个线程可以共同存在,共享资源,我们可以扩展Thread类,并创建自己的线程。

当然,使用Runnable也是另一种选择,是否使用这个类取决于你的应用程序的需要,一个普通的应用程序是完全没有必要使用线程的。

8.java.lang.Class :这是一个直接继承Object类的子类,这个类没有构造函数,它们的对象是被Java虚拟机通过类加载器加载的。

我们大多数人可能没有直接使用过它,但我认为它是一个重要的做反射的类。

9.java.util.Date :这是用来处理日期的类,有时候,我们觉得这个类应该加入更多的实用方法,就像每个企业级应用程序都会创建一个日期的实用工具单元。

它自JDK 1.0开始引入,后来在JDK1.1中发生巨大变化,弃用了一大堆的方法。

10.java.util.Iterator :这是一个接口,它很受欢迎,用来替换枚举,这是一个简单易用的单元,它用Iterable同步工作

如何复制一个对象

A:浅复制(浅克隆): 浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。

B:深复制(深克隆):深复制把要复制的对象所引用的对象都复制了一遍。

Java中对象的克隆,可以利用Object类的clone()方法。必须要遵循下面三点

  • 在派生类中覆盖基类的clone()方法,并声明为public【Object类中的clone()方法为protected的】。
  • 在派生类的clone()方法中,调用super.clone()。
  • 在派生类中实现Cloneable接口。 Object类里的clone方法是浅复制(浅克隆)
  • BeanUtils.copyProperties(被复制,目标复制)方法
array list去重方法

1.通过LinkedHashSet来解决,LinkedHashSet是有序不可重复的,可以把ArrayList传入LinkedHashSet中

2.使用Java8的新特性stream的distinct()方法来实现

3.使用contains()方法去重

4.利用HashSet(无序唯一)的特性

ArrayList 如何保证线程安全
  • 使用 Collections.synchronizedList() 
  • 使用new CopyOnWriteArrayList<E>()
  • 自定义myArrayList继承自Arraylist
  • 使用显式锁(如 ReentrantLock)
什么是延迟加载(懒加载)

延迟加载又叫懒加载是在关联查询时,也就是说先加载主信息,在需要的时候,再去加载从信息。在mybatis中,resultMap标签 的association标签和collection标签具有延迟加载的功能

查看进程命令
  • 查看被占用的端口的进程,netstat -tunpl |grep 端口号
  • 查看进程的详细信息,ps -ef|grep 进程ID
乐观锁和悲观锁

       出现并发的情况时,需要保证在并发情况下数据的准确性,以此确保当前用户和其他用户一起操作时,所得到的结果和他单独操作时的结果是一样的否则会导致脏读、幻读和不可重复读,这时就用到了乐观锁悲观锁;

       1,悲观锁:借助数据库锁机制,在修改数据之前先锁定,再修改;悲观锁:主要分为共享锁(读锁,简称 S 锁,多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改)和排他锁(写锁,简称 X 锁,不能与其他锁并存,如果一个事务获取了一个数据行的排 他锁,其他事务就不能再获取该行的其他锁,可对数据进行修和读取)

       实现:传统的关系型数据库使用这种锁机制,比如行锁、表锁、读锁、写锁等,都是在操作之前先上锁;Java 里面的同步 synchronized 关键字的实现

       2,乐观锁:乐观锁假设数据一般情况不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果冲突,则返回给用户异常信息,让用户决定如何去做。乐观锁适用于读多写少的场景,这样可以提高程序的吞吐量,是为了避免数据库幻读、业务处理时间过长等原因引起数据处理错误的一种机制,

实现:1.CAS 实现,2.版本号控制

mycat的分库分表

分库分表实战-- Mycat实战_mycat分库分表_Captain Leo的博客-CSDN博客

pom.xml里面的SNSPSHOT的作用

1.标识这个jar是一个不稳定的jar,是一个标识版本的作用。

2.使用了SNAPSHOT之后,maven会经常去私服或是中央仓库中拉取最新 的这个jar的版本;而没有SNAPSHOT的jar,则会从本地仓库中查找,本地不存在,才去中央仓库中拉取。

3.更新频率:需要在pom.xml文件中进行配置。 updatePolicy: always代表经常性的去拉取最新的jar,daily代表每天拉取一次,interval:分钟;nerver:和正式版本一致,不会去拉取最新的jar

Filter与interceptor的区别(过滤器和拦截器的区别)

① 拦截器是基于java反射机制的,而过滤器是基于函数回调的。

②  过滤器依赖与servlet容器,而拦截器不依赖与servlet容器。

③  拦截器只能对Action请求起作用,而过滤器则可以对几乎所有请求起作用。

④  拦截器可以访问Action上下文、值栈里的对象,而过滤器不能。

⑤  在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时被调用一次

@Autowired和@Resource到底有什么区别

来源不同:@Autowired 来自 Spring 框架,而 @Resource 来自于JSR-250;

依赖查找的顺序不同:@Autowired 先根据类型再根据名称查询,而 @Resource 先根据名称再根据类型查询;

支持的参数不同:@Autowired 只支持设置 1 个参数,而 @Resource 支持设置 7 个参数;

依赖注入的用法支持不同:@Autowired 既支持构造方法注入,又支持属性注入和 Setter 注入,而 @Resource 只支持属性注入和 Setter 注入;

编译器 IDEA 的提示不同:当注入 Mapper 对象时,使用 @Autowired 注解编译器会提示错误,而使用 @Resource 注解则不会提示错误

@Autowired遇到多个同继承类时可能会出问题,建议带个@Qualifier指定下名称

Spring中构造方法调用优先级为:带@Autowired的有参构造方法 > 不带@Autowired的有参构造方法  > 无参构造方法

@Autowired和@Resource到底有什么区别_一堆土豆33的博客-CSDN博客

依赖注入三种优缺点:java八股系列——依赖注入的方式_java依赖注入的三种方式_耶瞳的博客-CSDN博客

推荐构造器注入原因
  • 依赖不可变:这个好理解,通过构造方法注入依赖,在对象创建的时候就要注入依赖,一旦对象创建成功,以后就只能使用注入的依赖而无法修改了,这就是依赖不可变(通过 set 方法注入将来还能通过 set 方法修改)。
  • 依赖不为空:通过构造方法注入的时候,会自动检查注入的对象是否为空,如果为空,则注入失败;如果不为空,才会注入成功。
  • 完全初始化:由于获取到了依赖对象(这个依赖对象是初始化之后的),并且调用了要初始化组件的构造方法,因此最终拿到的就是完全初始化的对象了
ResultMap和ResultType区别

1.对象不同

(1)resultMap:查询出的列名和pojo(java的普通对象)的属性名不一致,通过resultMap和pojo做一个映射关系。

(2)resultType:使用resultType进行输出映射

2.描述不同:

(1)resultMap:resultMap对于一对一表连接的处理方式通常为在主表的pojo中添加嵌套另一个表的pojo

(2)resultType:resultType无法查询结果映射到pojo对象的pojo属性中,根据对结构集查询遍历的需要选择使用resultType还是resultMap。

3.类型适用不同:

(1)resultMap:mybatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap。

(2)resultType:resultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用,但是resultType跟resultMap不能同时存在。

双亲委派

启动类加载器(Bootstrap Class Loader)扩展类(Extension)应用类(Application)

https://blog.csdn.net/axiaobaoa/article/details/125011774

JVM内存模型

线程私有:程序计数器,Java虚拟机栈,本地方法栈

共享:方法区(运行时常量池,已被虚拟机加载的类信息) Java堆(创建的对象)

https://blog.csdn.net/weixin_46487176/article/details/123415542

BIO与NIO、AIO的区别

BIO(同步并阻塞):用户进程在发起一个IO操作以后,必须等待IO操作完成,用户进程才能运行。JAVA传统的IO模型!

NIO(同步非阻塞):用户进程发起一个IO操作以后边可返回做其它事情,但进程要时不时的询问IO操作是否就绪,导致CPU资源浪费。

服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

AIO(异步非阻塞):用户进程发起一个IO操作立即返回,等IO读写入操作由内核完成后,应用程序会得到通知,目前Java中还没有支持此种IO模型。

Java常见的数据结构

数组、链表、队列、栈(堆栈)、堆、树、图、哈希表

https://blog.csdn.net/qq_58415646/article/details/126366794

多态的实现途径

同一行为的不同表现形式:重写、重载、接口实现

https://blog.csdn.net/qq_44682003/article/details/103289940

事务的隔离级别

读未提交: 所有事务都可以看到其他未提交事务的执行结果

读已提交(大多数据库的默认隔离级别): 一个事务只能看见已经提交事务所做的改变

可重读(mysql默认): 确保同一事务的多个实例在并发读取数据时,看到同样的数据行

可串行化: 在每个读的数据行上加上共享锁

事务的四个特性(ACID)

原子性: 一个事务要么全部提交成功,要么全部失败回滚

一致性: 一个事务在执行之前和执行之后,数据库都必须处于一致性状态

隔离性: 一个事务的执行不能不被其他事务干扰

持久性: 一旦事务提交,那么它对数据库中的对应数据的状态的变更是永久保存的

事务的传播机制

https://blog.csdn.net/blackball1998/article/details/118228986

微服务间的数据一致性问题

2PC(两阶段提交)、3PC(三阶段提交);

TCC方案;本地消息表;可靠消息最终一致性方案;最大努力通知方案

https://blog.csdn.net/qq_35165000/article/details/111407301

maven依赖版本冲突怎么处理

1.使用 exclusions 排除依赖;2.通常在父工程对依赖的版本统一管理

微服务间调用方式

https://blog.csdn.net/qq_45632311/article/details/127446415

传递时间

@DateTimeFormat 指定时间格式;@RequestParam 传递单一参数;@ResponseBody 分装成对象

动态代理和静态代理

 Jdk1.8特性

1、Lamdba表达式  2、函数式接口  3、方法引用和构造引用

4、Stream API  5、接口中的默认方法和静态方法 6、新时间日期API

https://blog.csdn.net/weixin_40294256/article/details/126338618

maven常用命令

parent:引入父级pom文件。

groupId:公司名称、组织名称、项目开发者,配置时生成路径也是由此生成(包名,如com.XXX)。
artifactId:项目通用名称。version:对应项目版本号。
packaging:打包后的类型。如war、jar、maven-plugin、ejb、pom、ear、par、rar

exclusions:排除管理(写在dependency中)。exclusion:具体要排除的依赖项。
repositories:仓库管理。
repository:具体仓库(有id、name、url子元素)。
properties:自定义标签管理(可在其内自定义标签名、值,用法同于el表达式:${标签名}得到其值),常用于集中定义依赖版本号

dependencies:依赖,jar包管理。
dependency:具体的依赖项。
dependencyManagement:依赖,jar包管理https://blog.csdn.net/zhijingzhi/article/details/125116162

分布式锁,进程锁,线程锁的区别

https://www.zhihu.com/question/602489550?utm_id=0

分布式解决跨域问题

使用jsonp解决跨域问题 (不推荐 因为只能支持get请求 不支持post请求)

使用HttpClient进行转发(不推荐, 因为效率非常低,会发送两次请求)

设置响应头允许跨域(可以推荐,适合于小公司快速解决问题)

使用nginx搭建api网关接口(强烈推荐)因为保证域名和端口都一致

使用Zuul微服务搭建API网关(强烈推荐)SpringCloud

https://blog.csdn.net/weixin_40918067/article/details/117399692

几种常见的长连接实现方案

最简单的做法是启动一个计时器,周期性轮询,2. 使用长轮询3. 浏览器基于 WebSocket,4.SSE 与 WebSocket 作用相似,都是建立浏览器与服务器之间的通信渠道,然后服务器向浏览器推送消息

https://blog.csdn.net/nanxijms/article/details/128002670

Object类的常用方法

toStringequalshashCodeclonegetClasswaitnotifynotifyAll

https://blog.csdn.net/qq_19801061/article/details/120994530

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值