当前位置:   article > 正文

Java基础_使用arraylist和linkedlist保存小组成员的信息(包括名字、手机号),让用户从控制台

使用arraylist和linkedlist保存小组成员的信息(包括名字、手机号),让用户从控制台

java基础

1.如何理解java面向对象

​ 我的理解是:面向对象是向现实世界模型的自然延伸,这是一种”万物皆对象”的编程思想。在现实生活中的任何物体都可以归为一类事物,而每一个个体都是一类事物的实例。每个对象都具有各自的状态特征(也可以称为属性)及行为特征(方法),java就是通过对象之间行为的交互来解决问题的。

​ 面向对象就是把构成问题的事物分解成一个个对象,建立对象不是为了实现一个步骤,而是为了描述某个事物在解决问题中的行为。

​ 类是面向对象中的一个很重要的概念,因为类是很多个具有相同属性和行为特征的对象所抽象出来的,对象是类的一个实例。

​ 类具有三个特性:封装、继承和多态。

  • 封装:是将一类事物的属性和行为抽象成一个类,一般是使其属性私有化,行为公开化,提高了数据的隐秘性的同时,使代码模块化。这么做的好处是:
    • 将变化隔离。
    • 便于使用。
    • 提高代码复用性。
    • 提高安全性。
    封装原则:
    • 将不需要对外提供的内容都隐藏起来。
    • 把属性都隐藏,提供公共方法对其访问。

  • 继承:子类可以继承父类的属性和方法,并对其进行拓展。

  • 多态:同一种类型的对象执行同一个方法时可以表现出不同的行为特征。通过继承的上下转型、接口的回调以及方法的重写和重载可以实现多态。

  • 面向过程:

    优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、 嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。

    缺点:没有面向对象易维护、易复用、易扩展

    面向对象:

    优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出 低耦合的系统,使系统更加灵活、更加易于维护

    2.请你谈谈Java中是如何支持正则表达式操作的?

Java中的String类提供了支持正则表达式操作的方法,包括:matches()、replaceAll()、replaceFirst()、split()。

3.int和Integer有什么区别(数据类型)

Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。
Java 为每个原始类型提供了包装类型:
- 原始类型: boolean,char,byte,short,int,long,float,double
- 包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

String 不属于基础类型,而 String 属于对象。

55.Java有哪些数据类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aDwRsfGX-1630242198250)(java基础.assets/image-20210402103108828.png)]

76.什么是链表

  • 链表是可以将物理地址上不连续的数据连接起来,通过指针来对物理地址进行操作,实现增删改查等功能。
  • 链表大致分为单链表和双向链表
      1. 单链表:每个节点包含两部分,一部分存放数据变量的data,另一部分是指向下一节点的next指针
      2. 双向链表:除了包含单链表的部分,还增加的pre前一个节点的指针
  • 链表的优点
    • 插入删除速度快(因为有next指针指向其下一个节点,通过改变指针的指向可以方便的增加删除元素)
    • 内存利用率高,不会浪费内存(可以使用内存中细小的不连续空间(大于node节点的大小),并且在需要空间的时候才创建空间)
    • 大小没有固定,拓展很灵活。
  • 链表的缺点
    • 不能随机查找,必须从第一个开始遍历,查找效率低

4.数组和链表

数组的特点

  • 在内存中,数组是一块连续的区域。 拿上面的看电影来说,这几个人在电影院必须坐在一起。

  • 数组需要预留空间,在使用前要先申请占内存的大小,可能会浪费内存空间。 比如看电影时,为了保证10个人能坐在一起,必须提前订好10个连续的位置。这样的好处就是能保证10个人可以在一起。但是这样的缺点是,如果来的人不够10个,那么剩下的位置就浪费了。如果临时有多来了个人,那么10个就不够用了,这时可能需要将第11个位置上的人挪走,或者是他们11个人重新去找一个11连坐的位置,效率都很低。如果没有找到符合要求的作为,那么就没法坐了。

  • 插入数据和删除数据效率低,插入数据时,这个位置后面的数据在内存中都要向后移。删除数据时,这个数据后面的数据都要往前移动。 比如原来去了5个人,然后后来又去了一个人要坐在第三个位置上,那么第三个到第五个都要往后移动一个位子,将第三个位置留给新来的人。 当这个人走了的时候,因为他们要连在一起的,所以他后面几个人要往前移动一个位置,把这个空位补上。

  • 随机读取效率很高。因为数组是连续的,知道每一个数据的内存地址,可以直接找到给地址的数据。

  • 并且不利于扩展,数组定义的空间不够时要重新定义数组。

    链表的特点

    • 在内存中可以存在任何地方,不要求连续。 在电影院几个人可以随便坐。
    • 每一个数据都保存了下一个数据的内存地址,通过这个地址找到下一个数据。 第一个人知道第二个人的座位号,第二个人知道第三个人的座位号……
    • 增加数据和删除数据很容易。 再来个人可以随便坐,比如来了个人要做到第三个位置,那他只需要把自己的位置告诉第二个人,然后问第二个人拿到原来第三个人的位置就行了。其他人都不用动。
    • 查找数据时效率低,因为不具有随机访问性,所以访问某个位置的数据都要从第一个数据开始访问,然后根据第一个数据保存的下一个数据的地址找到第二个数据,以此类推。 要找到第三个人,必须从第一个人开始问起。
    • 不指定大小,扩展方便。链表大小不用定义,数据随意增删。

    各自的优缺点

    数组的优点
    随机访问性强
    查找速度快

    数组的缺点
    插入和删除效率低
    可能浪费内存
    内存空间要求高,必须有足够的连续内存空间。
    数组大小固定,不能动态拓展

    链表的优点
    插入删除速度快
    内存利用率高,不会浪费内存
    大小没有固定,拓展很灵活。

    链表的缺点
    不能随机查找,必须从第一个开始遍历,查找效率低

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sCxGOhTf-1630242198255)(java基础.assets/image-20210810112536289.png)]

42.Java 容器都有哪些?

Java 容器分为 Collection 和 Map 两大类,其下又有很多子类,如下所示:

Collection

List

ArrayList

LinkedList

Vector

Stack

Set

HashSet

LinkedHashSet

TreeSet

Map

HashMap

LinkedHashMap

TreeMap

ConcurrentHashMap

Hashtable

19.Java集合类基本接口有哪些

Collection:代表一组对象,每一个对象都是它的子元素。
Set:不包含重复元素的Collection。
List:有顺序的collection,并且可以包含重复元素。
Map:可以把键(key)映射到值(value)的对象,键不能重复。

12.List、Map、Set

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XoqyD1xA-1630242198257)(java基础.assets/image-20210406105223065.png)]

Java 容器分为 Collection 和 Map 两大类,Collection集合的子接口有Set、List、Queue三种子接口。我们比较常用的是Set、List,Map接口不是collection的子接口。

Collection集合主要有List和Set两大接口
List:一个有序(元素存入集合的顺序和取出的顺序一致)容器,元素可以重复,可以插 入多个null元素,元素都有索引。常用的实现类有 ArrayList、LinkedList 和 Vector。
Set:一个无序(存入和取出顺序有可能不一致)容器,不可以存储重复元素,只允许存 入一个null元素,必须保证元素唯一性。Set 接口常用实现类是 HashSet、LinkedHashSet 以及TreeSet。
Map是一个键值对集合,存储键、值和之间的映射。 Key无序,唯一;value 不要求有序,允许重复。Map没有继承于Collection接口,从Map集合中检索元素时,只要给出键对象,就会返回对应的值对象。
Map 的常用实现类:HashMap、TreeMap、HashTable、LinkedHashMap、
ConcurrentHashMap

13.ArrayList、Vector、LinkedList

ArrayList 和Vector都是使用数组方式存储数据,Vector是线程安全的容器,但性能上较ArrayList差。

LinkedList使用双向链表实现存储(将内存中零散的内存单元通过附加的引用关联起来,形成一个可以按序号索引的线性结构,这种链式存储方式与数组的连续存储方式相比,内存的利用率更高)

ArrayList 和 LinkedList 的区别

  • 数据结构实现:ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。
  • 随机访问效率:ArrayList 比 LinkedList 在随机访问的时候效率要高,因为 LinkedList 是线性的数据存储方式,所以需要移动指针从前往后依次查找。
  • 增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高,因为ArrayList 增删操作要影响数组内的其他数据的下标。
  • 内存空间占用:LinkedList 比 ArrayList 更占内存,因为 LinkedList 的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素。
  • 线程安全:ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全;
    综合来说,在需要频繁读取集合中的元素时,更推荐使用 ArrayList,而在插入和删除操作较多时,更推荐使用 LinkedList。
  • LinkedList 的双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。

ArrayList 和 Vector 的区别

  • 这两个类都实现了 List 接口(List 接口继承了 Collection 接口),他们都是有序集合

    • 线程安全:Vector 使用了 Synchronized 来实现线程同步,是线程安全的,而 ArrayList 是非线程安全的。

    • 性能:ArrayList 在性能方面要优于 Vector。

    • 扩容:ArrayList 和 Vector 都会根据实际的需要动态的调整容量,只不过在 Vector 扩容每次会增加 1 倍,而 ArrayList 只会增加 50%。

  • Vector类的所有方法都是同步的。可以由两个线程安全地访问一个Vector对象、但是一个线程访问Vector的话代码要在同步操作上耗费大量的时间

  • Arraylist不是同步的,所以在不需要保证线程安全时时建议使用Arraylist。

14.List、Set、Map是否继承自Collection接口

List 接口对Collection进行了简单的扩充,它的具体实现类常用的有ArrayList和LinkedList。你可以将任何东西放到一个List容器中,并在需要时从中取出。ArrayList从其命名中可以看出它是一种类似数组的形式进行存储,因此它的随机访问速度极快,而LinkedList的内部实现是链表,它适合于在链表中间需要频繁进行插入和删除操作。在具体应用时可以根据需要自由选择。前面说的Iterator只能对容器进行向前遍历,而 ListIterator则继承了Iterator的思想,并提供了对List进行双向遍历的方法。

Set接口也是 Collection的一种扩展,而与List不同的时,在Set中的对象元素不能重复,也就是说你不能把同样的东西两次放入同一个Set容器中。它的常用具体实现有HashSet和TreeSet类。HashSet能快速定位一个元素,但是你放到HashSet中的对象需要实现hashCode()方法,它使用了前面说过的哈希码的算法。而TreeSet则将放入其中的元素按序存放,这就要求你放入其中的对象是可排序的,这就用到了集合框架提供的另外两个实用类Comparable和Comparator。一个类是可排序的,它就应该实现Comparable接口。有时多个类具有相同的排序算法,那就不需要在每分别重复定义相同的排序算法,只要实现Comparator接口即可。集合框架中还有两个很实用的公用类:Collections和 Arrays。Collections提供了对一个Collection容器进行诸如排序、复制、查找和填充等一些非常有用的方法,Arrays则是对一个数组进行类似的操作。

Map是一种把键对象和值对象进行关联的容器,而一个值对象又可以是一个Map,依次类推,这样就可形成一个多级映射。对于键对象来说,像Set一样,一个Map容器中的键对象不允许重复,这是为了保持查找结果的一致性;如果有两个键对象一样,那你想得到那个键对象所对应的值对象时就有问题了,可能你得到的并不是你想的那个值对象,结果会造成混乱,所以键的唯一性很重要,也是符合集合的性质的。当然在使用过程中,某个键所对应的值对象可能会发生变化,这时会按照最后一次修改的值对象与键对应。对于值对象则没有唯一性的要求。你可以将任意多个键都映射到一个值对象上,这不会发生任何问题(不过对你的使用却可能会造成不便,你不知道你得到的到底是那一个键所对应的值对象)。Map有两种比较常用的实现: HashMap和TreeMap。HashMap也用到了哈希码的算法,以便快速查找一个键,TreeMap则是对键按序存放,因此它便有一些扩展的方法,比如firstKey(),lastKey()等,你还可以从TreeMap中指定一个范围以取得其子Map。键和值的关联很简单,用pub (Object key,Object value)方法即可将一个键与一个值对象相关联。用get(Object key)可得到与此key对象所对应的值对象。

15.Collection 和 Collections

Collection是集合类的上级接口,继承与他的接口主要有Set 和List.
Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。Collections. sort(list)。

16.ArrayList和LinkedList

ArrayList采用数组数组实现的,查找效率比LinkedList高。LinkedList采用双向链表实现的,插入和删除的效率比ArrayList要高。一直在list的尾部添加元素,LinkedList效率要高。

4.Array和ArrayList

Array和ArrayList的不同点:
Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
Array大小是固定的,ArrayList的大小是动态变化的。
ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。

65.什么是集合

集合就是一个放数据的容器,准确的说是放数据对象引用的容器
集合类存放的都是对象的引用,而不是对象的本身
集合类型主要有3种:set(集)、list(列表)和map(映射)。

66.集合的特点

集合的特点主要有如下两点:
集合用于存储对象的容器,对象是用来封装数据,对象多了也需要存储集中式管理。
和数组对比对象的大小不确定。因为集合是可变长度的。数组需要提前定义大小

67. 集合和数组的区别

数组是固定长度的;集合可变长度的。
数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型。
数组存储的元素必须是同一个数据类型;集合存储的对象可以是不同数据类型。

68.使用集合框架的好处

  1. 容量自增长;
  2. 提供了高性能的数据结构和算法,使编码更轻松,提高了程序速度和质量;
  3. 可以方便地扩展或改写集合,提高代码复用性和可操作性。
  4. 通过使用JDK自带的集合类,可以降低代码维护和学习新API成本。

69.集合框架底层数据结构

Collection

List
Arraylist: Object数组
Vector: Object数组
LinkedList: 双向循环链表

Set
HashSet(无序,唯一):基于 HashMap 实现的,底层采用 HashMap 来保存元素
LinkedHashSet: LinkedHashSet 继承与 HashSet,并且其内部是通过LinkedHashMap 来实现的。有点类似于我们之前说的LinkedHashMap 其内部是基于 Hashmap 实现一样,不过还是有一点点区别的。
TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树。)

Map
HashMap: JDK1.8之前HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突).JDK1.8以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间
LinkedHashMap:LinkedHashMap 继承自 HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。
HashTable: 数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的
TreeMap: 红黑树(自平衡的排序二叉树)

70.遍历一个 List 有哪些不同的方式?每种方法的实现原理是什么?Java 中 List遍历的最佳实践是什么?

遍历方式有以下几种:

​ for 循环遍历,基于计数器。在集合外部维护一个计数器,然后依次读取每一个位置的元素,当读取到最后一个元素后停止。

​ 迭代器遍历,Iterator。Iterator 是面向对象的一个设计模式,目的是屏蔽不同数据集合的特点,统一遍历集合的接口。Java 在 Collections 中支持了 Iterator 模式。

​ foreach 循环遍历。foreach 内部也是采用了 Iterator 的方式实现,使用时不需要显式声明Iterator 或计数器。优点是代码简洁,不易出错;缺点是只能做简单的遍历,不能在遍历过程中操作数据集合,例如删除、替换。

最佳实践:Java Collections 框架中提供了一个 RandomAccess 接口,用来标记 List 实现是否支持 Random Access。
如果一个数据集合实现了该接口,就意味着它支持 Random Access,按位置读取元素的 时间复杂度为 O(1),如ArrayList。

​ 如果没有实现该接口,表示不支持 Random Access,如LinkedList。

推荐的做法就是,支持 Random Access 的列表可用 for 循环遍历,否则建议用 Iterator 或
foreach 遍历

71.说一下 ArrayList 的优缺点

ArrayList的优点如下:
ArrayList 底层以数组实现,是一种随机访问模式。ArrayList 实现了 RandomAccess 接口,因此查找的时候非常快。

​ ArrayList 在顺序添加一个元素的时候非常方便。

ArrayList 的缺点如下:
删除元素的时候,需要做一次元素复制操作。如果要复制的元素很多,那么就会比较耗费性能。
插入元素的时候,也需要做一次元素复制操作,缺点同上。
ArrayList 比较适合顺序添加、随机访问的场景。

72. 插入数据时,ArrayList、LinkedList、Vector谁速度较快?阐述ArrayList、Vector、LinkedList 的存储性能和特性?

  • ArrayList和Vector 底层的实现都是使用数组方式存储数据。数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢。
  • Vector 中的方法由于加了 synchronized 修饰,因此 Vector 是线程安全容器,但性能上较ArrayList差。
  • LinkedList 使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但插入数据时只需要记录当前项的前后项即可,所以 LinkedList 插入速度较快。

73.多线程场景下如何使用 ArrayList

ArrayList 不是线程安全的,如果遇到多线程场景,可以通过 Collections 的 synchronizedList 方法将其转换成线程安全的容器后再使用。例如像下面这样:

List<String> synchronizedList = Collections.synchronizedList(list); 
synchronizedList.add("aaa"); 
synchronizedList.add("bbb"); 

for (int i = 0; i < synchronizedList.size(); i++) { 
	System.out.println(synchronizedList.get(i)); 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

74.HashSet如何检查重复?HashSet是如何保证数据不可重复的?

  • 向HashSet 中add ()元素时,判断元素是否存在的依据,不仅要比较hash值,同时还要结合equles 方法比较。
  • HashSet 中的add ()方法会使用HashMap 的put()方法。
  • HashMap 的 key 是唯一的,由源码可以看出 HashSet 添加进去的值就是作为HashMap 的key,并且在HashMap中如果K/V相同时,会用新的V覆盖掉旧的V,然后返回旧的V。所以不会重复(HashMap 比较key是否相等是先比较hashcode 再比较equals )。

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

数组转 List:使用 Arrays. asList(array) 进行转换。

List 转数组:使用 List 自带的 toArray() 方法。

47.在 Queue 中 poll()和 remove()有什么区别?

相同点:都是返回第一个元素,并在队列中删除返回的对象。

不同点:如果没有元素 poll()会返回 null,而 remove()会直接抛出 NoSuchElementException 异常。

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

Vector、Hashtable、Stack 都是线程安全的,而像 HashMap 则是非线程安全的,不过在 JDK 1.5 之后随着 Java. util. concurrent 并发包的出现,它们也有了自己对应的线程安全类,比如 HashMap 对应的线程安全类就是 ConcurrentHashMap。

49. 迭代器 Iterator 是什么?

Iterator 接口提供遍历任何 Collection 的接口。我们可以从一个 Collection 中使用迭代器方法来获取迭代器实例。迭代器取代了 Java 集合框架中的 Enumeration,迭代器允许调用者在迭代过程中移除元素。

18.Iterator和ListIterator

Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。

50.Iterator 怎么使用?有什么特点?

Iterator 使用代码如下:

List list = new ArrayList<>();

Iterator it = list. iterator();

while(it. hasNext()){

String obj = it. next();

System. out. println(obj);

}

Iterator 的特点是更加安全,因为它可以确保,在当前遍历的集合元素被更改的时候,就会抛出ConcurrentModificationException 异常。

51.怎么确保一个集合不能被修改?

可以使用 Collections. unmodifiableCollection(Collection c) 方法来创建一个只读集合,这样改变集合的任何操作都会抛出 Java. lang. UnsupportedOperationException 异常。

75.什么是Hash算法

  • 哈希算法是指把任意长度的二进制映射为固定长度的较小的二进制值,这个较小的二进制值叫做哈希值。

43.如何决定使用 HashMap 还是 TreeMap?

对于在 Map 中插入、删除、定位一个元素这类操作,HashMap 是最好的选择,因为相对而言 HashMap 的插入会更快,但如果你要对一个 key 集合进行有序的遍历,那 TreeMap 是更好的选择。

17.HashMap和Hashtable

HashMap和Hashtable都实现了Map接口

HashMap 不是线程安全的

HashMap 是 map 接口的实现类,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值。HashMap 允许 null key 和 null value,而 HashTable 不允许。

HashTable 是线程安全 Collection。

HashMap 是 HashTable 的轻量级实现,他们都完成了Map 接口,主要区别在于 HashMap 允许 null key 和 null value,由于非线程安全,效率上可能高于 Hashtable。

区别如下:
  • HashMap允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许。
  • HashMap 把 Hashtable 的 contains 方法去掉了,改成 containsValue 和 containsKey。因为 contains 方法容易让人引起误解。
  • HashTable 继承自 Dictionary 类,而 HashMap 是 Java1.2 引进的 Map interface 的一个实现。
  • HashTable 的方法是 Synchronize 的,而 HashMap 不是,在多个线程访问 Hashtable 时,不需要自己为它的方法实现同步,而 HashMap 就必须为之提供外同步。
  • Hashtable 和 HashMap 采用的 hash/rehash 算法都大概一样,所以性能不会有很大的差异。

44.HashMap 的实现原理?

HashMap 基于 Hash 算法实现的,我们通过 put(key,value)存储,get(key)来获取。当传入 key 时,HashMap 会根据 key. hashCode() 计算出 hash 值,根据 hash 值将 value 保存在 bucket 里。当计算出的 hash 值相同时,我们称之为 hash 冲突,HashMap 的做法是用链表和红黑树存储相同 hash 值的value。当 hash 冲突的个数比较少时,使用链表否则使用红黑树。

45.HashSet 的实现原理?

HashSet 是基于 HashMap 实现的,HashSet 底层使用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,相关 HashSet 的操作,基本上都是直接调用底层 HashMap 的相关方法来完成,HashSet 不允许重复的值。

6.Lamda表达式的优缺点。

​ 优点:1. 简洁。2. 非常容易并行计算。3. 可能代表未来的编程趋势。

​ 缺点:1. 若不用并行计算,很多时候计算速度没有比传统的 for 循环快。(并行计算有时需要预热才显示出效率优势)2. 不容易调试。3. 若其他程序员没有学 过 lambda 表达式,代码不容易让其他语言的程序员看懂。

7.“”比较的是什么? 和 equals 的区别是什么

”对比两个对象基于内存引用,如果两个对象的引用完全相同(指向同一个对象)时,“”操作将返回true,否则返回false。“==”如果两边是基本类型,就是比较数值是否相等。

== 对于基本类型来说是值比较,对于引用类型来说是比较的是引用;

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

64.创建一个对象用什么关键字?对象实例与对象引用有何不同?

new关键字,new创建对象实例(对象实例在堆内存中)

对象引用指向对象实例(对象引用存放 在栈内存中)。一个对象引用可以指向0个或1个对象(一根绳子可以不系气球,也可以系一个气 球);一个对象可以有n个引用指向它(可以用n条绳子系住一个气球)

10.final, finally, finalize的区别。

​ final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
​ finally是异常处理语句结构的一部分,表示总是执行。
​ finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。

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

不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类,

32.this与super的区别

super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super. 成员函数据名(实参)

this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)

super()和this()类似,区别是,super()在子类中调用父类的构造方法,this()在本类内调用本类的其它构造方法。

super()和this()均需放在构造方法内第一行。尽管可以用this调用一个构造器,但却不能调用两个。

this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。

this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。

从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。

57.Math.round(11.5) 等于多少?

Math.round(11.5)的返回值是 12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加 0.5 然后进行下取整。

59.访问修饰符 public,private,protected,以及不写(默认)时的区别

private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

default (即缺省,什么也不写,不使用任何关键字): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。

protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。

public : 对所有类可见。使用对象:类、接口、变量、方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5qFGFdv2-1630242198260)(java基础.assets/image-20210402103943417.png)]

60.&和&&的区别

&运算符有两种用法:(1)按位与;(2)逻辑与。

&&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端 的布尔值都是true 整个表达式的值才是 true。&&之所以称为短路运算,是因为如果&&左边的表达式的值是 false,右边的表达式会被直接短路掉,不会进行运算。

61.static

被static修饰的变量或者方法是独立于该类的任何对象,也就是说,这些变量和方法不属于任何一个实例对象,而是被类的实例对象所共享。

1、静态只能访问静态。

2、非静态既可以访问非静态的,也可以访问静态的。

62.break ,continue ,return 的区别及作用

break 跳出总上一层循环,不再执行循环(结束当前的循环体)

continue 跳出本次循环,继续执行下次循环(结束正在执行的循环 进入下一个循环条件)

return 程序返回,不再执行下面的代码(结束当前的方法 直接返回)

39.Java 中 IO 流分为几种?区别

按功能来分:输入流(input)、输出流(output)。

按类型来分:字节流和字符流。

字节流和字符流的区别是:字节流按 8 位传输以字节为单位输入输出数据,字符流按 16 位传输以字符

为单位输入输出数据。

40.BIO、NIO、AIO 有什么区别?

BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。

NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。

AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。

54.Java和C++的区别

都是面向对象的语言,都支持封装、继承和多态

Java不提供指针来直接访问内存,程序内存更加安全

Java的类是单继承的,C++支持多重继承;虽然Java的类不可以多继承,但是接口可以多继承。Java有自动内存管理机制,不需要程序员手动释放无用内存

31.SDK,JDK和JRE和JVM的区别

  • SDK是Software Development Kit的缩写,中文意思是“软件开发工具包”

SDK是一系列程序接口,文档,开发工具的集合,sdk不是一个开发工具,也不是一个程序。一个完整的SDK应该包括以下内容:

(1)接口文件和库文件;

(2)帮助文档;

(3)开发示例;

(4)实用工具。

接口文件和库文件就是API,将底层的代码进行封装保护,提供给用户一个调用底层代码的接口;

帮助文档解释接口文件和库文件功能,以及介绍相关的开发工具,操作示例等等;

开发示例就是做出来的一个DEMO展示,也要包括源代码;

实用工具是用来协助用户进行二次开发的工具,比如二次开发向导、API 搜索工具、软件打包工具等。

有过java编程经历的都知道,要运行java需要在电脑上安装jdk。jdk就是java SDK

  • 看Java官方的图片,Jdk中包括了Jre,Jre中包括了JVM

JDK :

​ JDK是Java Development Kit的缩写,是Java的开发工具包,主要包含了各种类库和工具,当然也包含了另外一个JRE.

​ Jdk还包括了一些Jre之外的东西 ,就是这些东西帮我们编译Java代码的。所以安装了JDK,就无需再单独安装JRE了。其中的开发工具:编译工具(javac.exe), 打包工具(jar.exe)等

​ JDK是Java的开发工具,它不仅提供了Java程序运行所需的JRE,还提供了一系列的编译,运行等工具,如javac,java,javaw等。JRE只是Java程序的运行环境,它最核心的内容就是JVM(Java虚拟机)及核心类库。

JRE :

​ JRE是Java Runtime Environment的缩写,是Java程序的运行环境。既然是运行,当然要包含JVM,也就是所谓的Java虚拟机,还有所以的Java类库的class文件,都在lib目录下,并且都打包成了jar。

​ Jre大部分都是 C 和 C++ 语言编写的,他是我们在编译java时所需要的基础的类库 Java Runtime Environment包括Java虚拟机和Java程序所需的核心类库等。核心类库主要是java.lang 包:包含了运行Java程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、线 程、异常处理类等,系统缺省加载这个包

如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可。

**Jvm:**在倒数第二层 由他可以在(最后一层的)各种平台上运行 Java Virtual Machine是Java虚拟机,Java程序需要运行在虚拟机上,不同的平台有自己的虚拟机,因此Java语言可以实现跨平台。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U0iSL02v-1630242198262)(java基础.assets/image-20210402100547734.png)]

32.JDK中常用的包有哪些

java.lang:这个是系统的基础类;

java.io:这里面是所有输入输出有关的类,比如文件操作等;

java.nio:为了完善 io 包中的功能,提高 io 包中性能而写的一个新包;

java.net:这里面是与网络有关的类;

java.util:这个是系统辅助类,特别是集合类;

java.sql:这个是数据库操作的类.

11.Java是否支持多继承?

​ Java中类不支持多继承,只支持单继承(即一个类只有一个父类)。 但是java中的接口支持多继承,,即一个子接口可以有多个父接口。(接口的作用是用来扩展对象的功能,一个子接口继承多个父接口,说明子接口扩展了多个功能,当类实现接口时,类就扩展了相应的功能)。

33.什么是跨平台性?原理是什么

所谓跨平台性,是指java语言编写的程序,一次编译后,可以在多个系统平台上运行。

实现原理:Java程序是通过java虚拟机在系统平台上运行的,只要该系统可以安装相应的java虚拟 机,该系统就可以运行java程序。

52.Java语言有哪些特点

简单易学(Java语言的语法与C语言和C++语言很接近) 面向对象(封装,继承,多态)

平台无关性(Java虚拟机实现平台无关性)

支持网络编程并且很方便(Java语言诞生本身就是为简化网络编程设计的) 支持多线程(多线程机制使应用程序在同一时间并行执行多项任)

健壮性(Java语言的强类型机制、异常处理、垃圾的自动收集等) 安全性好

53.什么是Java程序的主类?应用程序和小程序的主类有何不同?

一个程序中可以有多个类,但只能有一个类是主类。在Java应用程序中,这个主类是指包含main() 方法的类。而在Java小程序中,这个主类是一个继承自系统类JApplet或Applet的子类。应用程序的主类不一定要求是public类,但小程序的主类要求必须是public类。主类是Java程序执行的入口点。

58.Java语言采用何种编码方案?有何特点

Java语言采用Unicode编码标准,Unicode(标准码),它为每个字符制订了一个唯一的数值,因此在任何的语言,平台,程序都可以放心的使用。

21.线程的基本状态以及状态之间的关系

其中Running表示运行状态,

Runnable表示就绪状态(万事俱备,只欠CPU),

Blocked表示阻塞状态,阻塞状态又有多种情况,可能是因为调用wait()方法进入等待池,也可能是执行同步方法或同步代码块进入等锁池,或者是调用了sleep()方法或join()方法等待休眠或其他线程结束,或是因为发生了I/O中断。

29.生产者消费者模式

生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据。

41.Files 的常用方法

Files. exists():检测文件路径是否存在。

Files. createFile():创建文件。

Files. createDirectory():创建文件夹。

Files. delete():删除一个文件或目录。

Files. copy():复制文件。

Files. move():移动文件。

Files. size():查看文件个数。

Files. read():读取文件。

Files. write():写入文件

52.什么是字节码?采用字节码的最大好处是什么

字节码:Java源代码经过虚拟机编译器编译后产生的文件(即扩展为.class的文件),它不面向任 何特定的处理器,只面向虚拟机。

采用字节码的好处:

Java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留 了解释型语言可移植的特点。所以Java程序运行时比较高效,而且,由于字节码并不专对一种特定 的机器,因此,Java程序无须重新编译便可在多种不同的计算机上运行。

先看下java中的编译器和解释器

Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟机器。这台虚拟的机 器在任何平台上都提供给编译程序一个的共同的接口。编译程序只需要面向虚拟机,生成虚拟机能 够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行。在Java中,这种供虚 拟机理解的代码叫做字节码(即扩展为.class的文件),它不面向任何特定的处理器,只面向虚拟 机。每一种平台的解释器是不同的,但是实现的虚拟机是相同的。Java源程序经过编译器编译后变 成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,解释器将其翻 译成特定机器上的机器码,然后在特定的机器上运行,这就是上面提到的Java的特点的编译与解释 并存的解释。

Java源代码---->编译器---->jvm可执行的Java字节码(即虚拟指令)---->jvm---->jvm中解释器 >机器可执行的二进制机器码 >程序运行。

56.switch 是否能作用在byte上

在 Java 5 以前,switch(expr)中,expr 只能是 byte、short、char、int。从 Java5 开始,Java 中引入了枚举类型,expr 也可以是 enum 类型,从 Java 7 开始,expr 还可以是字符串(String), 但是长整型(long)在目前所有的版本中都是不可以的。

77.什么是红黑树

  • 红黑树是一种特殊的二叉查找树。红黑树的每个结点上都有存储位表示结点的颜色,可以是红(Red)或黑(Black)。
  • 红黑树的每个结点是黑色或者红色。当是不管怎么样他的根结点是黑色。每个叶子结点(叶子结点代表终结、结尾的节点)也是黑色 [注意:这里叶子结点,是指为空(NIL或NULL)的叶子结点!]。
  • 如果一个结点是红色的,则它的子结点必须是黑色的。
  • 每个结点到叶子结点NIL所经过的黑色结点的个数一样的。[确保没有一条路径会比其他路径长出俩倍,所以红黑树是相对接近平衡的二叉树的!]
  • 红黑树的基本操作是添加、删除。在对红黑树进行添加或删除之后,都会用到旋转方法。为什么呢?道理很简单,添加或删除红黑树中的结点之后,红黑树的结构就发生了变化,可能不满足上面三条性质,也就不再是一颗红黑树了,而是一颗普通的树。而通过旋转和变色,可以使这颗树重新成为红黑树。简单点说,旋转和变色的目的是让树保持红黑树的特性。

变量与方法

66.成员变量与局部变量的区别有哪些

变量:在程序执行的过程中,在某个范围内其值可以发生改变的量。从本质上讲,变量其实是内存 中的一小块区域

成员变量:方法外部,类内部定义的变量局部变量:类的方法中的变量。

成员变量和局部变量的区别

作用域

成员变量:针对整个类有效。

局部变量:只在某个范围内有效。(一般指的就是方法,语句体内)

存储位置

成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。

局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中。当方法调用完,或者语 句结束后,就自动释放。

生命周期

成员变量:随着对象的创建而存在,随着对象的消失而消失局部变量:当方法调用完,或者语句结束后,就自动释放。

初始值

成员变量:有默认初始值。

局部变量:没有默认初始值,使用前必须赋值

67.在Java中定义一个不做事且没有参数的构造方法的作用

Java程序在执行子类的构造方法之前,如果没有用super()来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用super()来调用父类中特定的构造方法,则编译时将发生错误,因为Java程序在父类中找不到没有参数的构造方法可供执行。解决办法是在父类里加上一个不做事且没有参数的构造方法。

68.在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是

帮助子类做初始化工作。

69. 一个类的构造方法的作用是什么?若一个类没有声明构造方法,改程序能正确执行吗?为什么

主要作用是完成对类对象的初始化工作。可以执行。因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法。

70.构造方法有哪些特性

名字与类名相同;

没有返回值,但不能用void声明构造函数;

生成类的对象时自动执行,无需调用

71.静态变量和实例变量区别

静态变量: 静态变量由于不属于任何实例对象,属于类的,所以在内存中只会有一份,在类的加载过程中,JVM只为静态变量分配一次内存空间。

实例变量: 每次创建对象,都会为每个对象分配成员变量内存空间,实例变量是属于实例对象的,在内存中,创建几次对象,就有几份成员变量.

72.静态变量与普通变量区别

static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。

还有一点就是static成员变量的初始化顺序按照定义的顺序进行初始化。

73.静态方法和实例方法有何不同

在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。

静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制。

74.非静态类不能访问静态类

static修饰的类为静态类,静态类在加载的时候就分配了内存,直到该类被卸载内存才会被撤销。既然实实在在地存在于内存中,就可以被访问而不用先创建对象才能引用。而对于非静态类需要先创建了对象才能被引用,没创建在内存中就没有空间,也就不存在,不存在的东西当然访问不了存在的东西。

New 一个对象的时候,并不是先在堆中为对象开辟内存空间,而是先将类中的静态方法(带有static修饰的静态函数)的代码加载到一个叫做方法区的地方,然后 再在堆内存中创建对象。所以说静态方法会随着类的加载而被加载。当你new一个对象时,该对象存在于对内存中,this关键字一般指该对象,但是如果没有 new对象,而是通过类名调用该类的静态方法也可以。

静态方法是属于类的,动态方法属于实例对象,在类加载的时候就会分配内存,可以 通过类名直接去访问,非静态成员(变量和方法)属于类的对象,所以只有在对象实例化之后才存在,然后通过类的对象去访问。
在一个类的静态成员中去访问非静态成员之所以会出错是因为在类的非静态成员不存在的时候静态成员就已经存在了,访问一个内存中不存在的东西当然会出错。

那类是什么时候被加载呢?在需要调用的时候被加载。

如果静态方法能调用动态方法的话,那如果别人通过类名调用静态方法时实例对象可能并不存在,但是方法内又调用了对象的方法,由于对象不存在,所以动态方法也不存在,程序肯定报错,所以java直接在编译阶段检查这种错误,避免运行时异常

75.什么是方法的返回值?返回值的作用是什么

方法的返回值是指我们获取到的某个方法体中的代码执行后产生的结果!(前提是该方法可能产生结果)。返回值的作用:接收出结果,使得它可以用于其他的操作!

8.构造函数,构造函数重载,复制构造函数?

​ 当新对象被创建的时候,构造函数会被调用。每一个类都有构造函数。在程序员没有给类提供构造函数的情况下,Java编译器会为这个类创建一个默认的构造函数。
​ Java中构造函数重载和方法重载很相似。可以为一个类创建多个构造函数。每一个构造函数必须有它自己唯一的参数列表。
​ Java不支持像C++中那样的复制构造函数,这个不同点是因为如果你不自己写构造函数的情况下,Java不会创建默认的复制构造函数。

9.方法重写(Overriding)和方法重载(Overloading)

方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被”屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。

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

普通类不能包含抽象方法,抽象类可以包含抽象方法。

抽象类不能直接实例化,普通类可以直接实例化。

36.抽象类必须要有抽象方法吗?普通类区别?

不需要,抽象类不一定非要有抽象方法。

普通类不能包含抽象方法,抽象类可以包含抽象方法。抽象类不能直接实例化,普通类可以直接实例化。

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

默认方法实现:抽象类可以有默认的方法实现;接口不能有默认的方法实现。

实现:抽象类的子类使用 extends 来继承;接口必须使用 implements 来实现接口。

构造函数:抽象类可以有构造函数;接口不能有。

main 方法:抽象类可以有 main 方法,并且我们能运行它;接口不能有 main 方法。

实现数量:类可以实现很多个接口;但是只能继承一个抽象类。

访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符。

参数抽象类接口
声明抽象类使用abstract关键字声明接口使用interface关键字声明
实现子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明 的方法的实现子类使用implements关键字来实现接口。它需要提供接口中所有声明的方法的实现
构造器抽象类可以有构造器接口不能有构造器
访问修饰符抽象类中的方法可以是任意访问修饰符接口方法默认修饰符是public。并且不 允 许 定 义 为 private 或 者 protected
多继承一个类最多只能继承一个抽象类一个类可以实现多个接口
字段声明抽象类的字段声明可以是任意的接口的字段默认都是 static 和 final的

内部类

76. 什么是内部类

在Java中,可以将一个类的定义放在另外一个类的定义内部,这就是内部类。内部类本身就是类的一个属性,与其他属性定义方式一致。

77.内部类的分类有哪些

内部类可以分为四种:成员内部类、局部内部类、匿名内部类和静态内部类

静态内部类

定义在类内部的静态类,就是静态内部类。

静态内部类可以访问外部类所有的静态变量,而不可访问外部类的非静态变量;静态内部类的创建方式, new 外部类.静态内部类()

成员内部类

定义在类内部,成员位置上的非静态类,就是成员内部类。

成员内部类可以访问外部类所有的变量和方法,包括静态和非静态,私有和公有。成员内部类依赖于外部类的实例,它的创建方式 外部类实例.new 内部类() ,

局部内部类

定义在方法中的内部类,就是局部内部类。

定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法。局部内部类的创建方式,在对应方法内, new 内部类() ,

匿名内部类

匿名内部类就是没有名字的内部类,日常开发中使用的比较多。

除了没有名字,匿名内部类还有以下特点:

​ 匿名内部类必须继承一个抽象类或者实现一个接口。

​ 匿名内部类不能定义任何静态成员和静态方法。

​ 当所在的方法的形参需要被匿名内部类使用时,必须声明为 final。

​ 匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。

匿名内部类创建方式:

new 类/接口{ 

​			//匿名内部类实现部分 

​		}
  • 1
  • 2
  • 3
  • 4
  • 5

78.内部类的优点

一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据!

内部类不为同一包的其他类所见,具有很好的封装性;

内部类有效实现了“多重继承”,优化 java 单继承的缺陷。

匿名内部类可以很方便的定义回调。

79.内部类有哪些应用场景

  1. 一些多算法场合

  2. 解决一些非面向对象的语句块。

  3. 适当使用内部类,使得代码更加灵活和富有扩展性。

  4. 当某个类除了它的外部类,不再被其他的类使用时。

80.hashCode与 equals (重要)

hashCode()介绍

hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode()函数。

散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象)

为什么要有 hashCode

当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashcode 值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用 equals()方法来检查hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。(摘自我的Java启蒙书《Head first java》第二版)。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。

hashCode()与equals()的相关规定

如果两个对象相等,则hashcode一定也是相同的

两个对象相等,对两个对象分别调用equals方法都返回true

两个对象有相同的hashcode值,它们也不一定是相等的

值传递

81.当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递

是值传递。Java 语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的

82.为什么Java中只有值传递

首先回顾一下在程序设计语言中有关将参数传递给方法(或函数)的一些专业术语。按值调用(call by value)表示方法接收的是调用者提供的值,而按引用调用(call by reference)表示方法接收的是调用者提供的变量地址。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。 它用来描述各种程序设计语言(不只是Java)中方法参数传递方式。

Java程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,也就是说,方法不能修改传递给它的任何参数变量的内容。

83.值传递和引用传递有什么区别

值传递:指的是在方法调用时,传递的参数是按值的拷贝传递,传递的是值的拷贝,也就是说传递后就互不相关了。

引用传递:指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)

IO流

1.java 中 IO 流分为几种?

按照流的流向分,可以分为输入流和输出流;
按照操作单元划分,可以划分为字节流和字符流;
按照流的角色划分为节点流和处理流。

InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。
OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。

按操作方式分类结构图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZjohzCcL-1630242198263)(java基础.assets/image-20210402165325383.png)]

按操作对象分类结构图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2DXLSna7-1630242198264)(java基础.assets/image-20210402165404097.png)]

2.Files的常用方法都有哪些?

Files. exists():检测文件路径是否存在。
Files. createFile():创建文件。
Files. createDirectory():创建文件夹。
Files. delete():删除一个文件或目录。
Files. copy():复制文件。
Files. move():移动文件。
Files. size():查看文件个数。
Files. read():读取文件。
Files. write():写入文件。

String相关

1.字符型常量和字符串常量的区别

  1. 形式上: 字符常量是单引号引起的一个字符 字符串常量是双引号引起的若干个字符
  2. 含义上: 字符常量相当于一个整形值(ASCII值),可以参加表达式运算 字符串常量代表一个地址值(该字符串在内存中存放位置)
  3. 占内存大小 字符常量只占一个字节 字符串常量占若干个字节(至少一个字符结束标志)

2.什么是字符串常量池?

字符串常量池位于堆内存中,专门用来存储字符串常量,可以提高内存的使用率,避免开辟多块空间存储相同的字符串,在创建字符串时 JVM 会首先检查字符串常量池,如果该字符串已经存在池中,则返回它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用。

3.String有哪些特性

不变性:String 是只读字符串,是一个典型的 immutable 对象,对它进行任何操作,其实都是创建一个新的对象,再把引用指向该对象。不变模式的主要作用在于当一个对象需要被多线程共享并频繁访问时,可以保证数据的一致性。
常量池优化:String 对象创建之后,会在字符串常量池中进行缓存,如果下次创建同样的对象时,会直接返回缓存的引用。
**final:**使用 final 来定义 String 类,表示 String 类不能被继承,提高了系统的安全性。

4.String为什么是不可变的吗

简单来说就是String类利用了final修饰的char类型数组存储字符

5.是否可以继承 String 类

String 类是 final 类,不可以被继承。

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

不一样,因为内存的分配方式不一样。String str="i"的方式,java 虚拟机会将其分配到常量池中;而 String str=new String(“i”) 则会被分到堆内存中。

7.数组有没有 length()方法?String 有没有 length()方法

数组没有 length()方法 ,有 length 的属性。String 有 length()方法。JavaScript中,获得字符串的长度是通过 length 属性得到的,这一点容易和 Java 混淆。

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

不一样,因为内存的分配方式不一样。String str="i"的方式,Java 虚拟机会将其分配到常量池中;而String str=new String(“i”) 则会被分到堆内存中。

34.Java 中操作字符串的类?String、StringBuffer

操作字符串的类有:String、StringBuffer、StringBuilder。

String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会生成新的 String 对象,然后将指针指向新的 String 对象,而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。

StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,但 StringBuilder 的性能却高于 StringBuffer,所以在单线程环境下推荐使用StringBuilder,多线程环境下推荐使用 StringBuffer。

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

indexOf():返回指定字符的索引。

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

replace():字符串替换。

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

split():分割字符串,返回一个分割后的字符串数组。

getBytes():返回字符串的 byte 类型数组。

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

toLowerCase():将字符串转成小写字母。

toUpperCase():将字符串转成大写字符。

substring():截取字符串。

equals():字符串比较。

反射

1.什么是反射?

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

静态编译和动态编译
静态编译:在编译时确定类型,绑定对象
动态编译:运行时确定类型,绑定对象

2.什么是 Java 序列化?什么情况下需要序列化?

Java 序列化是为了保存各种对象在内存中的状态,并且可以把保存的对象状态再读出来。

以下情况需要使用 Java 序列化:

想把的内存中的对象状态保存到一个文件中或者数据库中时候;

想用套接字在网络上传送对象的时候;

想通过 RMI(远程方法调用)传输对象的时候。

3.动态代理是什么?有哪些应用?

动态代理是运行时动态生成代理类。

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

4.怎么实现动态代理?

JDK 原生动态代理和 cglib 动态代理。JDK 原生动态代理是基于接口实现的,而 cglib 是基于继承当前类的子类实现的。

5.反射机制优缺点

优点: 运行期类型的判断,动态加载类,提高代码灵活度。
缺点: 性能瓶颈:反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的java代码要慢很多。

6.Java获取反射的三种方法

1.通过new对象实现反射机制

2.通过路径实现反射机制

3.通过类名实现反射机制

对象拷贝

1.为什么要使用克隆?

克隆的对象可能包含一些已经修改过的属性,而 new 出来的对象的属性都还是初始化时候的值,所以当需要一个新的对象来保存当前对象的“状态”就靠克隆方法了。

2.如何实现对象克隆?

实现 Cloneable 接口并重写 Object 类中的 clone() 方法。

实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。

3.深拷贝和浅拷贝区别是什么?

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

深克隆:除了对象本身被复制外,对象所包含的所有成员变量也将复制。Java Web

Java Web

1.JSP 和 servlet 有什么区别?

JSP 是 servlet 技术的扩展,本质上就是 servlet 的简易方式。servlet 和 JSP 最主要的不同点在于,servlet 的应用逻辑是在 Java 文件中,并且完全从表示层中的 html 里分离开来,而 JSP 的情况是 Java 和 html 可以组合成一个扩展名为 JSP 的文件。JSP 侧重于视图,servlet 主要用于控制逻辑。

2.JSP 有哪些内置对象?作用分别是什么?

JSP 有 9 大内置对象:

request:封装客户端的请求,其中包含来自 get 或 post 请求的参数;

response:封装服务器对客户端的响应;

pageContext:通过该对象可以获取其他对象;

session:封装用户会话的对象;

application:封装服务器运行环境的对象;

out:输出服务器响应的输出流对象;

config:Web 应用的配置对象;

page:JSP 页面本身(相当于 Java 程序中的 this);

exception:封装页面抛出异常的对象。

3.说一下 JSP 的 4 种作用域?

page:代表与一个页面相关的对象和属性。

request:代表与客户端发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个 Web 组件;需要在页面显示的临时数据可以置于此作用域。

session:代表与某个用户与服务器建立的一次会话相关的对象和属性。跟某个用户相关的数据应该放在用户自己的 session 中。

application:代表与整个 Web 应用程序相关的对象和属性,它实质上是跨越整个 Web 应用程序,包括多个页面、请求和会话的一个全局作用域。

4.session 和 cookie 有什么区别?

存储位置不同:session 存储在服务器端;cookie 存储在浏览器端。

安全性不同:cookie 安全性一般,在浏览器存储,可以被伪造和修改。

容量和个数限制:cookie 有容量限制,每个站点下的 cookie 也有个数限制。

存储的多样性:session 可以存储在 Redis 中、数据库中、应用程序中;而 cookie 只能存储在浏览器中。

5. 说一下 session 的工作原理?

session 的工作原理是客户端登录完成之后,服务器会创建对应的 session,session 创建完之后,会把session 的 id 发送给客户端,客户端再存储到浏览器中。这样客户端每次访问服务器时,都会带着sessionid,服务器拿到 sessionid 之后,在内存找到与之对应的 session 这样就可以正常工作了。

6.如果客户端禁止cookie 能实现session 还能用吗?

可以用,session 只是依赖 cookie 存储 sessionid,如果 cookie 被禁用了,可以使用 url 中添加sessionid 的方式保证 session 能正常使用

7.spring mvc 和 struts 的区别是什么?

拦截级别:struts2 是类级别的拦截;spring mvc 是方法级别的拦截。

数据独立性:spring mvc 的方法之间基本上独立的,独享 request 和 response 数据,请求数据通过参数获取,处理结果通过 ModelMap 交回给框架,方法之间不共享变量;而 struts2 虽然方法之间也是独立的,但其所有 action 变量是共享的,这不会影响程序运行,却给我们编码和读程序时带来了一定的麻烦。

拦截机制:struts2 有以自己的 interceptor 机制,spring mvc 用的是独立的 aop 方式,这样导致

struts2 的配置文件量比 spring mvc 大。

对 ajax 的支持:spring mvc 集成了 ajax,所有 ajax 使用很方便,只需要一个注解 @ResponseBody 就可以实现了;而 struts2 一般需要安装插件或者自己写代码才行。

8.如何避免 SQL 注入?

使用预处理 PreparedStatement。

使用正则表达式过滤掉字符中的特殊字符。

9.什么是 XSS 攻击,如何避免?

XSS 攻击:即跨站脚本攻击,它是 Web 程序中常见的漏洞。原理是攻击者往 Web 页面里插入恶意的脚本代码(css 代码、Javascript 代码等),当用户浏览该页面时,嵌入其中的脚本代码会被执行,从而达到恶意攻击用户的目的,如盗取用户 cookie、破坏页面结构、重定向到其他网站等。

预防 XSS 的核心是必须对输入的数据做过滤处理。

10.什么是 CSRF 攻击,如何避免?

CSRF:Cross-Site Request Forgery(中文:跨站请求伪造),可以理解为攻击者盗用了你的身份,以你的名义发送恶意请求,比如:以你名义发送邮件、发消息、购买商品,虚拟货币转账等。

防御手段:

验证请求来源地址;

关键操作添加验证码;

在请求地址添加 token 并验证.

异常

1.throw 和 throws 的区别?

throw:是真实抛出一个异常。

throws:是声明可能会抛出一个异常。

2.final、finally、finalize 有什么区别?

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

finally:是 try{} catch{} finally{} 最后一部分,表示不论发生任何情况都会执行,finally 部分可以省略,但如果 finally 部分存在,则一定会执行 finally 里面的代码。

finalize: 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法。

3.try-catch-finally 中哪个部分可以省略?

try-catch-finally 其中 catch 和 finally 都可以被省略,但是不能同时省略,也就是说有 try 的时候,必须后面跟一个 catch 或者 finally。

4.try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?

finally 一定会执行,即使是 catch 中 return 了,catch 中的 return 会等 finally 中的代码执行完之后,才会执行。

5.常见的异常类有哪些?

NullPointerException 空指针异常

ClassNotFoundException 指定类不存在

NumberFormatException 字符串转换为数字异常

IndexOutOfBoundsException 数组下标越界异常

ClassCastException 数据类型转换异常

FileNotFoundException 文件未找到异常

NoSuchMethodException 方法不存在异常

IOException IO 异常

SocketException Socket 异常

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/792597
推荐阅读
相关标签
  

闽ICP备14008679号