归纳知识总结与面试题(2020-11-22起持续更新)

1 篇文章 0 订阅
1 篇文章 0 订阅

归纳知识总结与面试题型(2020-11-22起 持续更新)

1.Java

一、Java 基础

1. jre与jdk的区别

  • jre:Java Runtime Environment 的简称,是运行环境,安装jre会自带JVM虚拟机,java源码需要使用虚拟机才能运行在windows或者Linux系统上运行
  • jdk:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境 下载jdk时也包含jre。
  • 分析:具体来说需要运行java代码jre就行了,而需要开发编写java程序,只需jdk就够了

2.equals与==的区别

Student s=new Student("a", 18); 
Student s1=new Student("a", 18);
System.out.println(System.identityHashCode(s)); //打印内存地址2018699554
System.out.println(System.identityHashCode(s1));//打印内存地址1311053135
System.out.println(s==s1);//false
---------------------------------------------------------------------
//每个类的内存地址都是随机变化的 但每个对象的内存地址不可能一样
//如果要判断对象是否一样就需要在Student类里重写equals方法了 
//我们使用的是开发工具的快捷生成 方法体重还是使用==判断值的
public class Student {
		private String name;
		private int num;
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Student other = (Student) obj;
			if (name == null) {
				if (other.name != null)
					return false;
			} else if (!name.equals(other.name))
				return false;
			if (num != other.num)
				return false;
			return true;
		}	
}
  • == 解读:基本类型:比较的是值是否相同;引用类型:比较的是引用是否相同;
  • equals:是Object类下的方法,在object类里比较的是内存地址,是==,而String类里重写了equal方法,里面比较的是值的内容,如果需要比较对象里的值时,需要重写equals方法
  • 总结== 对于基本类型来说是值比较,对于引用类型来说是比较的是引用;而 equals 默认情况下是引用比较,只是很多类重新了 equals 方法,比如 String、Integer 等把它变成了值比较,所以一般情况下 equals 比较的是值是否相等。

3. 两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?

1 答案是不对,两个对象的 hashCode()相同,equals()不一定 true。
因为我们可以重写ehashCode的规则使其内存地址样,也可以重写equals,改变 比较的方法,因为在散列表中,hashCode()相等即两个键值对的哈希值相等,然而哈希值相等,并不一定能得出键值对相等。

4. final 在 java 中有什么作用?

  1. 被final修饰的类 不能被其他类继承
  2. 被final修饰的变量只能赋值初始值一次,如果没有赋值初识值,编译器则报错;
  3. 被final修饰的方法不能被子类重写
  4. 总结:final是常量的意思,被修饰是变量、方法、类是不能被修改的;

5. java 中的 Math.round(-1.5) 等于多少?

等于 -1,因为在数轴上取值时,中间值(0.5)向右取整,所以正 0.5 是往上取整,负 0.5 是直接舍弃。

6. String 属于基础的数据类型吗?

String不是基本数据类型,基本数据类型有:byte int short lang double float boolean char 属于java中的基本数据类型,String是不可变的引用数据类型.
注意:String是java.lang包下的一个类,底层是Cahr[] value数组是被final修饰的

7. java 中操作字符串都有哪些类?它们之间有什么区别?

  1. java中操作字符串的类有String,StringBuffer,StringBuilder三大类
  2. String与StringBuffer,StringBuilder的区别:首先String是不可变字符串 底层是一个被final修饰的Object数组,所以是不可变的,每次创建一个String对象会在常量池创建出来,然后将指针重新指向他,如:“a”+“ab”=“aab”,字符串常量池会创建这三个不一样的对象.
  3. StringBuffer与StringBuilder是可变字符串,在抽象类 AbstractStringBuilder底层也是char[] value,但没有被final修饰
//通过反射拿到抽象类char数组的源码 
	StringBuffer buff=new StringBuffer("123");
		Class c=buff.getClass();
		Class superC= c.getSuperclass();
		Field f=  superC.getDeclaredField("value");
		f.setAccessible(true);
		char[] vlaue=(char[]) f.get(buff);
		System.out.println(vlaue);//123[][][][][][][][][]... 这里是初识容量16;
		
  1. StringBuffer与StringBuilder的区别:1.他们都是可变字符串,StringBuffer底层的方法大部分是用synchronize关键字修饰的,是线程安全的,StringBuilder是非线程安全的 2.StringBuffer的toString是带缓冲的,而StringBuilder的toString是直接取对象.
  2. 总结:String:适用于少量的字符串操作的情况,StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况,StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

8. String str="i"与 String str=new String(“i”)一样吗?

内存地址的分配会不一样
如图:
在这里插入图片描述
解析:
String str=“i”;str是直接指向常量池 而String str=new String(“i”);
str是先指向堆内存,str先保存的是堆内存的地址,然后推里在指向常量池
;

9. 如何将字符串反转?

使用StringBuffer和StringBuilder的reverse()方法.注:String没有reverse()方法

		StringBuffer t=new StringBuffer("123456789");
		t=t. reverse() ;
		System.out.println(t);//987654321

10.String 类的常用方法都有那些?

  1. equals()比较String的值
  2. indexOf()传入字符串,找到该字符串返回该字符所在位置,未找到返回-1
  3. charAt():返回指定索引处的字符。
  4. replace():字符串替换。
  5. trim():去除字符串两端空白。
  6. split():分割字符串,返回一个分割后的字符串数组。
  7. getBytes():返回字符串的 byte 类型数组。
  8. length():返回字符串长度。
  9. toLowerCase():将字符串转成小写字母。
  10. toUpperCase():将字符串转成大写字符。
  11. substring():截取字符串。

11.String,StringBuffer,StringBuilder在经过方法时会改变自身吗?

String调用方法时不会改变自身,StringBuffer与Stringbuilder调用append时会改变自身

12. 抽象类必须要有抽象方法吗?

抽象类里不一定有抽象方法,但有抽象方法的类,一定是抽象类或接口

13.普通类和抽象类有哪些区别?

1.普通类里不能有抽象方法而抽象类可以有
2.抽象可不能实例化(不能直接实例化,直接实例化需要重写抽象方法),而实例类可以实例化

14.抽象类能使用 final 修饰吗?

抽象类是不能被final修饰的,抽象类其实就是让其子类继承的,被final修饰后就抽象类就没有任何意义了!
而且编译器这时也会报错!

15. 接口和抽象类有什么区别?

  1. 构造方法:抽象类可以有构造方法供子类使用,接口中不能有构造方法
  2. 抽象方法:抽象类可以有抽象方法也可以有成员方法,接口只能有抽象方法JDK8新增default修饰的默认方法可以写方法体,还有static修饰的也有方法体,JDK9新增private修饰的私有方法可以写方法体,供接口本类使用
  3. 声明方式:抽象类使用abstract声明,接口使用interface声明
  4. 实现数量:继承抽象类的类只能单继承使用extends,而实现接口的类可以多实现使用implement(为弥补单继承减少程序的灵活性)
  5. main方法:抽象类可以有main方法,接口不能有main方法

16. java 中 IO 流分为几种?

线上IO流继承关系图 在java.IO包下
在这里插入图片描述
在这里插入图片描述
根据数据的流向分为:输入流输出流

  • 输入流 :把数据从其他设备上读取到内存中的流。
  • 输出流 :把数据从内存 中写出到其他设备上的流。

格局数据的类型分为:字节流字符流

  • 字节流 :以字节为单位,读写数据的流。(byte)
  • 字符流 :以字符为单位,读写数据的流。(char)
    流分为:文件流,缓冲流,转换流,打印流,对象流,File 类

二、集合

17. java 容器都有哪些?

直接上集合继承图
在这里插入图片描述
在这里插入图片描述

Java容器的集合有:

  1. List接口下的ArrayList,LinkedList,Vector
  2. set接口下的HashSet,TreeSet
  3. map接口下的HashMap,TreeMap,Properties

18. Collection 和 Collections 有什么区别?

Collection接口在java.util报下,是单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是java.util.Listjava.util.Set。其中,List的特点是元素有序、元素可重复。Set的特点是元素无序,而且不可重复。List接口的主要实现类
Collections是java.util包下的,他是集合的工具类,常用的方法有:

  1. boolean addAll(Collection c, T… elements)一次性添加多个元素
  2. void shuffle(List<?> list)打乱集合顺序。
  3. void sort(List list)`:将集合中元素按照默认规则排序。

19. List、Set、Map 之间的区别是什么?

  • List
    1. 可以允许重复的对象。
    2. 可以插入多个null元素。
    3. 是一个有序容器,保持了每个元素的插入顺序,输出的顺序就是插入的顺序。
    4. 常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。

  • Set:
    1. 不允许重复对象
    2. 无序容器,你无法保证每个元素的存储顺序,TreeSet通过 Comparator 或者 Comparable 维护了一个排序顺序。
    3. 只允许一个 null 元素
    4. Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。

  • Map:
    1. Map不是collection的子接口或者实现类。Map是一个接口。
    2. Map 的 每个 Entry 都持有两个对象,也就是一个键一个值,Map 可能会持有相同的值对象但键对象必须是唯一的。
    3. TreeMap 也通过 Comparator 或者 Comparable 维护了一个排序顺序。
    4. Map 里你可以拥有随意个 null 值但最多只能有一个 null 键。
    5. Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap最常用)

20. 说一下 HashMap 的实现原理?

JDK1.8之前,HashMap是用哈希表底层采用数组+链表实现 即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。
在这里插入图片描述
在这里插入图片描述
简述上图操作:当我使用HashMap的put存入key value值时,首先判断该集合大小是否需要扩容,在将该值的key值通过Object类的hashCode()方法得到hash值,然后判断数组是否有值,如果没有元素直接插入,如果有元素进行equals判断hash值,若找到该hash值,就放入该数组进入链表结构,如果链表结构没有元素直接插入,如果有元素进行equals判断key的值,如果key值重复就覆盖value值,没有该key值就添加入链表末尾,若链表长度大于8就转换为红黑树结构,当小于6时在次转换为链表结构

21. 说一下 HashSet 的实现原理?

HashSet底层调用了HashMap,实际上是存入到了hashMap的key部分.
查看HashSet源码,其操作底层都是通过调用HashMap方法实现的,HashSet会将元素存储在HashMap的key集合中,然后为value赋一个static空对象PRESENT。
在这里插入图片描述
在这里插入图片描述

22. ArrayList 和 LinkedList 的区别是什么?

  • ArrayList:
    1. 数据结构:采用数组
    2. 查询快增删改慢
  • LinkedList:
    1. 数据结构:双向链表
    2. 查询慢,增删改快

备注:只是数据结构不同

23. (了解)hash冲突是什么?它的解决方法有几种?

博主之前看面试视频时,偶尔看过这类面试官提问?现在给大家介绍下
在同一个hash数组的链表里,你们都以为hash值是一样的对吧?但同一个链表里的hash值可能不一样,也有可能一样,这是因为通过hash算法%(取模)得到的,不一定所有的hash值都是唯一的。但最后转换的数组下标一定是相同的。

结论:hash值相同时是一定在同一个链表上,但由于hash算法转换后的数组下标有可能相同,此时发生了hash碰撞.

  解决方案:
  1.开放定址法(线性探测再散列,二次探测再散列,伪随机探测再散列)
  2.再哈希法(重新计算直到不发生冲突)
  3.链地址法(Java hashmap就是这么做的)
  4.建立一个公共溢出区(就是把冲突的都放在另一个地方,不在表里面)

24. 如何实现数组和 List之间的转换?

  • List转换成为数组:调用ArrayList的toArray方法。
  • 数组转换成为List:调用Arrays的asList方法。

25. Array 和 ArrayList 有何区别?

  • Array:数组的大小是固定的,只能存储基本数据类型与引用数据类型.
  • ArrayList:list集合的大小是可以指定的,当容量满时,会自动扩容1.5倍,只能存储引用数据类型,功能比 Array更丰富;如(contain(),remove()…)

26. ArrayList怎么转换转换线程安全的?

  1. 使用Vector代替,底层的大部分方法都是使用synchronize修饰
    在这里插入图片描述

  2. 使用CopyOnWriteArrayList,读写分离,写入时复制
    在这里插入图片描述
    解析:CopyOnWriteArrayList是Java并发包中提供的一个并发容器,它是个线程安全且读操作无锁的ArrayList,写操作则通过创建底层数组的新副本来实现,是一种读写分离的并发策略。使用这种策略的还有CopyOnWriteSet,另外还有mysql的MVVC也是使用的这种原理

  3. Collections.synchronizedList(new ArrayList<>()) 通过调用该方法将ArrayLsit中的方法加上synchronize关键字

分析:以上解决方法推荐第二种或者第三种

27. 迭代器 Iterator 是什么?

迭代器是一种术语:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。

28. 迭代器 Iterator 与增强循环 foreach

我们知道iterator与foreach都能遍历数组与集合但他们的变量方式的效率上的各有有事,foreach的底层使用了iterator

从数据结构角度分析,for循环适合访问顺序结构,可以根据下标快速获取指定元素.而Iterator 适合访问链式结构,因为迭代器是通过next()和Pre()来定位的.可以访问没有顺序的集合.

而使用 Iterator 的好处在于可以使用相同方式去遍历集合中元素,而不用考虑集合类的内部实现(只要它实现了 java.lang.Iterable 接口),如果使用 Iterator 来遍历集合中元素,一旦不再使用 List 转而使用 Set 来组织数据,那遍历元素的代码不用做任何修改,如果使用 for 来遍历,那所有遍历此集合的算法都得做相应调整,因为List有序,Set无序,结构不同,他们的访问算法也不一样.

三、多线程

29. 并行、并发、串行有什么区别?

先上图:
在这里插入图片描述

  • 串行:有n个任务,由一个线程按顺序排队执行。由于任务、方法都在一个线程执行所以不存在线程不安全情况,也就不存在临界区的问题。
  • 并发:多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行。
  • 并行:单位时间内,多个处理器或多核处理器同时处理多个任务,是真正意义上的“同时进行”。



2.Mybatis,Spring,SpringMVC三大框架

一、Mybatis

30. #与$的区别?

1. #使用 ?在sql语句中做站位的, 使用PreparedStatement执行sql,效率高
2. #能够避免sql注入,更安全。
3. $不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低
4. $有sql注入的风险,缺乏安全性。
5. $:可以替换表名或者列名

二 、Spring

31. @AutoWired与@Rrsouce的区别?

  1. @AutoWired 是spring包下的,默认按照类型自动注入,若需要使用名称自动注入 需要使用@Qualifier(" 变量名称")的方式
  2. @Rrsouce 是jdk包下的,默认使用类名自动注入,若类名未找到,则使用类型注入
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值