201902-Java面试总结

最近两周都在面试,很多技术点都知道,但是很少实战应用,面试的时候描述就自然模糊不清,所以现在就两周面试个人情况总结如下(其实还是个人java基础知识需要巩固理解学习,加油ing):

  • java Object的方法有哪些?
  • 1.clone方法:保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。主要是JAVA里除了8种基本类型传参数是值传递,其他的类对象传参数都是引用传递,我们有时候不希望在方法里将参数改变,这时就需要在类中复写clone方法。

    2.getClass方法:final方法,获得运行时类型。

    3.toString方法:该方法用得比较多,一般子类都有覆盖。(虽然Object提供了toString的实现,但它返回的是类名+@+哈希码值的无符号16进制表示=>getClass().getName() + '@' + Integer.toHexString(hashCode()) =>通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。所以,建议所有子类都重写此方法。)

    4.finalize方法:该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。

    5.equals方法:该方法是非常重要的一个方法。一般equals和==是不一样的,但是在Object中两者是一样的。子类一般都要重写这个方法。

    6.hashCode方法:该方法用于哈希查找,可以减少在查找中使用equals的次数,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。一般必须满足obj1.equals(obj2)==true。可以推出obj1.hash- Code()==obj2.hashCode(),但是hashCode相等不一定就满足equals。不过为了提高效率,应该尽量使上面两个条件接近等价。如果不重写hashcode(),在HashSet中添加两个equals的对象,会将两个对象都加入进去。

  • 7.wait方法:wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。

    8.notify方法:该方法唤醒在该对象上等待的某个线程。

    9.notifyAll方法:该方法唤醒在该对象上等待的所有线程。

  • java的反射机制是什么?原理是什么?

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

延伸参考:https://blog.csdn.net/Appleyk/article/details/77879073

  • java Interface接口和Abstract抽象类的区别?它们分别使用的场景?

抽象类与接口都用于抽象,但抽象类(单继承)可以有自己的部分实现,而接口(多继承)则完全是一个标识;

接口的好处是将实现(细节)与表现(动作)分离;

  1. 抽象类的成员可以具有访问级别,接口的成员全部public级别
  2. 抽象类可以包含字段,接口不可以
  3. 抽象类可以实现接口,接口不能继承抽象类
  4. 抽象类的成员可以具有具体实现,接口不行
  5. 抽象的子类可以选择性实现其基类的抽象方法,接口的子类必须实现
  6. 接口是抽象类的一种特例!
  • java 悲观锁和乐观锁是什么?java中有哪些锁?

乐观锁:乐观并发控制(又名”乐观锁”,Optimistic Concurrency Control,缩写”OCC”)是一种并发控制的方法。它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的 那部分数据。在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回 滚。乐观事务控制最早是由孔祥重(H.T.Kung)教授提出。

实现:乐观锁一般会使用版本号机制或CAS(Compare-and-Swap,即比较并替换)算法实现。

悲观锁:悲观并发控制(又名”悲观锁”,Pessimistic Concurrency Control,缩写”PCC”)是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数据。如果一个事务执行的操作读某行数据应用了 锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。

实现:Java中synchronizedReentrantLock等独占锁就是悲观锁思想的实现。

两种锁的使用场景:两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下(多读场景),即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果是多写的情况,一般会经常产生冲突,这就会导致上层应用会不断的进行retry,这样反倒是降低了性能,所以一般多写的场景下用悲观锁就比较合适。

延伸参考:https://www.cnblogs.com/qlqwjy/p/7798266.html

java的锁有哪些?

          【1】公平锁和非公平锁。 
          公平锁:是指按照申请锁的顺序来获取锁, 
          非公平锁:线程获取锁的顺序不一定按照申请锁的顺序来的。

          //默认是不公平锁,传入true为公平锁,否则为非公平锁
          ReentrantLock reentrantLock =  new ReetrantLock();

          【2】共享锁和独享锁 
          独享锁:一次只能被一个线程所访问 
          共享锁:线程可以被多个线程所持有。 
          ReadWriteLock 读锁是共享锁,写锁是独享锁。 
          【3】乐观锁和悲观锁。 
          乐观锁:对于一个数据的操作并发,是不会发生修改的。在更新数据的时候,会尝试采用更新,不断重入的方式,更新数据。 
          悲观锁:对于同一个数据的并发操作,是一定会发生修改的。因此对于同一个数据的并发操作,悲观锁采用加锁的形式。悲观锁认为,不加锁的操作一定会出问题, 
          【4】分段锁:其实是一种锁的设计,并不是具体的一种锁,对于ConcurrentHashMap而言,其并发的实现就是通过分段锁的形式来实现高效的并发操作。其思想就是让锁的粒度变小。 
          【5】这三种锁是指锁的状态,并且是针对Synchronized

          偏向锁:是指一段同步代码一直被一个线程所访问,那么该线程会自动获取锁。降低获取锁的代价 
          轻量级锁 :指当锁是偏向锁的时候,被另一个线程所访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,提高性能。
          重量级锁 :指当锁为轻量级锁的时候,另一个线程虽然是自旋,但自旋不会一直持续下去,当自旋一定次数的时候,还没有获取到锁,就会进入阻塞,该锁膨胀为重量级锁。重量级锁会让其他申请的线程进入阻塞,性能降低。
          【6】自旋锁:指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环会消耗CPU。

延伸阅读:http://www.cnblogs.com/lxmyhappy/p/7380073.html

  • java事务处理,有哪些事务?

java的事务处理,如果对数据库进行多次操作,每一次的执行或步骤都是一个事务.如果数据库操作在某一步没有执行或出现异常而导致事务失败,这样有的事务被执行有的就没有被执行,从而就有了事务的回滚,取消先前的操作..... 

Java事务的类型有三种:JDBC事务、JTA(JavaTransaction API)事务、容器事务。

1、JDBC事务:控制的局限性在一个数据库连接内,但是其使用简单。

2、JTA事务:功能强大,事务可以跨越多个数据库或多个DAO,使用也比较复杂。

3、容器事务:主要指的是J2EE应用服务器提供的事务管理,局限于EJB应用使用。

JDBC 事务是用 Connection 对象控制的。JDBCConnection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交。 java.sql.Connection 提供了以下控制事务的方法:public void setAutoCommit(boolean),public boolean getAutoCommit(),public void commit(),public void rollback();使用 JDBC 事务界定时,您可以将多个 SQL 语句结合到一个事务中。JDBC 事务的一个缺点是事务的范围局限于一个数据库连接。一个 JDBC 事务不能跨越多个数据库

延伸阅读:https://www.cnblogs.com/wang-Java-begining/p/9978230.html

https://www.cnblogs.com/Bonker/p/5417967.html

https://jingyan.baidu.com/article/414eccf65aa5896b421f0a52.html  (百度经验-简单)

  • java数据库事务的原则(特性)有哪些?(ACID原则)

数据库事务正确执行的四个原则:A (Atomicity)原子性、C (Consistency) 一致性、I(Isolation)隔离性、D(Durability)持久性

1、A (Atomicity) 原子性 :事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚(要么成功,要么失败重来)。 比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元;2)存入100元至B账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。

2、C (Consistency) 一致性 :数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。 例如现有完整性约束a存款+b存款=2000,如果一个事务改变了a存款,那么必须得改变b存款,使得事务结束后依然满足a存款+b存款=2000,否则事务失败。

3、I (Isolation) 隔离性:指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。 比如现在有个交易是从A账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的。

即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。(串行化)

4、D (Durability) 持久性 :指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。

  • @transaction注解的参数有哪些,作用是什么?
  1. 控制事务传播----propagation属性
  2. 控制事务隔离级别----属性isolation
  3. 只可读/可读写
  4. 遇到哪些异常会回滚和不回滚----rollbackFor和noRollbackFor属性
  5. @Transactianal注解有一些属性,见Spring-Framework-Reference Table17.3 Transactional-settings
@Transactional(propagation=Propagation.REQUIRED)           //控制事务传播。默认是Propagation.REQUIRED
@Transactional(isolation=Isolation.DEFAULT)                //控制事务隔离级别。默认跟数据库的默认隔离级别相同
@Transactional(readOnly=false)                             //控制事务可读写还是只可读。默认可读写
@Transactional(timeout=30)                                 //控制事务的超时时间,单位秒。默认跟数据库的事务控制系统相同,又说是30秒
@Transactional(rollbackFor=RuntimeException.class)         //控制事务遇到哪些异常才会回滚。默认是RuntimeException
@Transactional(rollbackForClassName=RuntimeException)      //同上
@Transactional(noRollbackFor=NullPointerException.class)   //控制事务遇到哪些异常不会回滚。默认遇到非RuntimeException不会回滚
@Transactional(noRollbackForClassName=NullPointerException)//同上

延伸阅读:https://www.cnblogs.com/alice-cj/p/10417097.html  (very good) 

https://www.cnblogs.com/sonng/p/6591319.html   (good)

  • java有哪些常见 的设计模式?(23种)
  1. 创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
  2. 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
  3. 行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式(责任链模式)、访问者模式。
  4. 单例模式有哪些?

单例模式可以分为懒汉式和饿汉式:

    1)懒汉式单例模式:在类加载时不初始化。

    2)饿汉式单例模式:在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快。

懒汉式,线程安全;饿汉式,线程不安全;使用静态内部类 | 枚举方式 | 双重校验锁,线程安全【推荐】

延伸阅读:https://blog.csdn.net/a214024475/article/details/53188472

https://wangle.iteye.com/blog/196972https://wangle.iteye.com/blog/196972

https://blog.csdn.net/qq_21439971/article/details/53740109    (单例模式)

  • spring的核心是什么,特性有哪些?AOP,IOC底层实现的原理是什么?

spring是一个轻型容器(light-weight Container),其核心是Bean工厂(Bean Factory),用以构造我们所需要的M(Model)

两个特性IoC(Inversion of Control 控制反转)/ DI (Dependency Injection依赖注入)面向切面编程(aspect-oriented programming,AOP)

IOC(控制反转): 就是把要在程序中实例化的对象配置到文件中,在程序中不用new来产生,而是让容器通过配置文件返回一个给你,好处就是当需要更改业务逻辑时,方便替换对接口的不同实现类。通俗理解:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做。针对一个接口,我们可能会写多个实现类,如果在代码中、程序中对实现类的对象进行创建,当想更换实现类时(使用其他的实现类),就需要对代码进行更改。

AOP(面向切面编程):通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来。基本实现就是对相关的方法进行拦截,添加所需的处理动作。

Spring有两种不同的容器:

Bean工厂(org.springframework.beans.factory.BeanFactory)是最简单的容器(是Spring基本的IOC容器),提供了基础的依赖注入支持

应用上下文(org.springframework.context.ApplicationContext)建立在Bean工厂基础之上,提供了系统构架服务

参考阅读:https://blog.csdn.net/yks0527/article/details/54093490

  • 常见的排序算法有哪些?复杂度O(n)的排序算法?

201902-Java面试总结_第1张图片

/**
*冒泡排序
*将序列中所有元素两两比较,将最大的放在最后面。
*将剩余序列中所有元素两两比较,将最大的放在最后面。
*重复第二步,直到只剩下一个数。
*/
public void bubbleSort(int []a){
           int len=a.length;
           for(int i=0;ia[j+1]){
                       int temp=a[j];
                       a[j]=a[j+1];
                       a[j+1]=temp;
                   }
               }
           }
       }

延伸阅读:https://www.cnblogs.com/guoyaohua/p/8600214.html

  • Solr,mongoDB,redis,zookeeper,Hadoop是什么框架?分别适合什么场景使用?

Solr:是一个独立的企业级搜索应用服务器,是一款非常优秀的全文搜索引擎,它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引;也可以通过Http Get操作提出查找请求,并得到XML格式的返回结果。它的主要特性包括:高效、灵活的缓存功能,垂直搜索功能,高亮显示搜索结果,通过索引复制来提高可用性,提供一套强大Data Schema来定义字段,类型和设置文本分析,提供基于Web的管理界面等。

MongoDB是一个基于分布式文件存储的数据库。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。它的特点是高性能、易部署、易使用,存储数据非常方便。主要功能特性有:*面向集合存储,易存储对象类型的数据。*模式自由。*支持动态查询。*支持完全索引,包含内部对象。*支持查询。*支持复制和故障恢复。*使用高效的二进制数据存储,包括大型对象(如视频等)。*自动处理碎片,以支持云计算层次的扩展性。*支持RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。*文件存储格式为BSON(一种JSON的扩展)。*可通过网络访问。所谓“面向集合”(Collection-Oriented),意思是数据被分组存储在数据集中,被称为一个集合(Collection)。MongoDB已经在多个站点部署,主要适用场景:1)网站实时数据处理。它非常适合实时的插入、更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。2)缓存。由于性能很高,它适合作为信息基础设施的缓存层。在系统重启之后,由它搭建的持久化缓存层可以避免下层的数据源过载。3)高伸缩性的场景。非常适合由数十或数百台服务器组成的数据库,它的路线图中已经包含对MapReduce引擎的内置支持。不适用场景:1)要求高度事务性的系统。2)传统的商业智能应用。3)复杂的跨文档(表)级联查询。

Redis:是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。redis使用了两种文件格式:全量数据和增量请求。适用场景:1)配合关系型数据库做高速缓存,;)缓存高频次访问的数据,降低数据库io;3)分布式架构,做session共享;4)可以持久化特定数据;5)利用zset类型可以存储排行榜;6)利用list的自然时间排序存储最新n个数据;数据高并发的读写,海量数据的读写,对扩展性要求高的数据;不适场景:需要事务支持(非关系型数据库)基于sql结构化查询储存,关系复杂。参考延伸:https://www.cnblogs.com/xiaoxi/p/7007695.html

ZooKeeper:是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。

Hadoop:实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数据提供了存储,而MapReduce则为海量的数据提供了计算。

Hadoop是一个能够让用户轻松架构和使用的分布式计算平台。用户可以轻松地在Hadoop上开发和运行处理海量数据的应用程序。它主要有以下几个优点:

  1. 高可靠性。Hadoop按位存储和处理数据的能力值得人们信赖。
  2. 高扩展性。Hadoop是在可用的计算机集簇间分配数据并完成计算任务的,这些集簇可以方便地扩展到数以千计的节点中。
  3. 高效性。Hadoop能够在节点之间动态地移动数据,并保证各个节点的动态平衡,因此处理速度非常快。
  4. 高容错性。Hadoop能够自动保存数据的多个副本,并且能够自动将失败的任务重新分配。
  5. 低成本。与一体机、商用数据仓库以及QlikView、Yonghong Z-Suite等数据集市相比,hadoop是开源的,项目的软件成本因此会大大降低。

  • 索引的数据结构是什么?

B-树(B-tree),散列(Hash),k-d 树(k-d tree),点四叉树(Point Quadtree)

1.什么是索引:索引是建立在表的一列或多个列上的辅助对象,目的是加快访问表中的数据;
  Oracle存储索引的数据结构是B*树(平衡树),位图索引也是如此,只不过是叶子节点不同B*数索引;
  索引由根节点、分支节点和叶子节点组成,上级索引块包含下级索引块的索引数据,叶节点包含索引数据和确定行实际位置的rowid。

2.使用索引的目的:1)加快查询速度;2)减少I/O操作;3)消除磁盘排序(索引能加快排序速度)

3.何时使用索引:查询返回的记录数   排序表<40%     ,对非排序表 <7%, 表的碎片较多(频繁增加、删除)

4.索引的种类:非唯一索引(最常用),唯一索引,位图索引,局部有前缀分区索引,局部无前缀分区索引,全局有前缀分区索引
,散列分区索引,基于函数的索引

参考阅读:https://blog.csdn.net/w1014074794/article/details/48810805

https://www.cnblogs.com/liuning8023/archive/2012/11/15/2728536.html

  • spring boot 自动配置的原理是什么?什么场景适合用spring boot?

SpringBoot 自动配置主要通过 @EnableAutoConfiguration@Conditional@EnableConfigurationProperties 或者 @ConfigurationProperties 等几个注解来进行自动配置完成的。

@EnableAutoConfiguration 开启自动配置,主要作用就是调用 Spring-Core 包里的 loadFactoryNames(),将 autoconfig 包里的已经写好的自动配置加载进来。

@Conditional 条件注解,通过判断类路径下有没有相应配置的 jar 包来确定是否加载和自动配置这个类。

@EnableConfigurationProperties 的作用就是,给自动配置提供具体的配置参数,只需要写在 application.properties 中,就可以通过映射写入配置类的 POJO 属性中。

在微服务概念兴起的今天,很多公司转型使用微服务作为架构。在技术选型上Spring Cloud 是非常好的选择,它提供了一站式的分布式系统解决方案,而Spring Cloud中的每个组件都是基于Spring Boot构建的,Spring Boot提供J2EE一站式解决方案,具有以下优点:

  1. 快速创建独立运行的Spring项目以及与主流框架集成
  2. 使用嵌入式的Servlet容器,应用无需打成WAR包
  3. starters自动依赖与版本控制
  4. 大量的自动配置,简化开发,也可修改默认值
  5. 无需配置XML,无代码生成,开箱即用
  6. 准生产环境的运行时应用监控
  7. 与云计算的天然集成

参考阅读:https://www.cnblogs.com/leihuazhe/p/7743479.html

https://www.cnblogs.com/jiadp/p/9276826.html

  • spring cloud是什么?它的作用和底层实现原理是什么?什么场景适合用spring cloud?

spring cloud 是基于spring boot实现的微服务架构开发工具,他为微服务中设计的配置管理、服务治理、断路器、智能路由、微代理、控制总线、全局锁、决策精选、分布式会话和集群状态管理等操作提供了一套简单的开发方式。 

参考延伸:https://www.cnblogs.com/sessionbest/p/9396728.html   (图解)

https://blog.csdn.net/Shinlyzsljay/article/details/79162270

https://blog.csdn.net/lchq1995/article/details/84234958

201902-Java面试总结_第2张图片

Ribbon:客户端负载均衡,重试机制。

Hystrix:客户端容错保护,服务熔断、请求缓存、请求合并、依赖隔离。

Feign:声明式服务调用,本质上就是Ribbon+Hystrix(优化代码,避免直接使用RestTemplate的混乱)

Bus:消息总线,配合Config仓库修改的一种Stream实现,独自启动不需要依赖其它组件。

Eureka:服务注册中心,特性有失效剔除、服务保护。

DashboardHystrix:仪表盘,监控集群模式和单点模式,其中集群模式需要收集器Turbine配合。

Zuul:API服务网关,功能有路由分发和过滤。

还有其它服务空间,包括configuration等等

 延伸阅读:https://www.iteye.com/news/32734    (从架构演进的角度聊聊 Spring Cloud 都做了些什么?)

  • java json遍历的算法?
/*Java遍历JSON,Iterator迭代器遍历取值*/
public static void main(String[] args) {
        String s = "{'A':{'a':'1' ,'aa':'11'},'B':{'b':'2' ,'bb':'22'}}" ;
        JSONObject jsonObject1=JSONObject.fromObject(s);
        Iterator iterator1 =jsonObject1.keys();
        while(iterator1.hasNext()){
            String key1 = iterator1.next();
            String value1 = jsonObject1.getString(key1);
            System.out.println(key1);
            JSONObject jsonObject2=JSONObject.fromObject(value1);
            Iterator iterator2 =jsonObject2.keys();
            while(iterator2.hasNext()){
                String key2 = iterator2.next();
                String value2 = jsonObject2.getString(key2);
                System.out.println(" - "+key2);
                System.out.println(" -- "+value2);
            }
        }
    }

201902-Java面试总结_第3张图片

延伸参考:https://blog.csdn.net/qq_35893120/article/details/84288551

  • java集合类
  1. ArrayList与LinkedList的区别

ArrayList:底层以数组的方式实现

LinkedList:底层采用双链表的方式实现,都实现了List接口

延伸链接:https://blog.csdn.net/bjzhuhehe/article/details/72230559

HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。主要的区别有:线程安全性,同步(synchronization),以及速度。HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。

HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。

数组:存储区间连续,占用内存严重,寻址容易,插入删除困难; 

链表:存储区间离散,占用内存比较宽松,寻址困难,插入删除容易;

201902-Java面试总结_第4张图片

  • java遍历Map的方式有哪些?(四种遍历map的方式)
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
 

public class MapT {
    public static void main(String[] args) {
        Map map=new HashMap<>();
        map.put(1,"第一个");
        map.put(2,"第二个");
        map.put(3,"第三个");
        map.put(4,"第四个");
 
        //第一种:先得到key的值 然后通过key值得到value值
        Set set=map.keySet();//这里的泛型是key值得泛型
        for(Integer integer:set){
            System.out.println(integer+"->"+map.get(integer));//key->value
        }
 
        //第二种:通过Map.values()遍历所有的value但是不能遍历key
        for(String s:map.values()){
            System.out.println(s);
        }
 
        //第三种:通过Map.entrySet使用迭代器iterator遍历key和value
        Iterator> iterable=map.entrySet().iterator();
        while(iterable.hasNext()){
            Map.Entryentry=iterable.next();
            System.out.println(entry.getKey()+"->"+entry.getValue());
        }
 
        //第四种:直接通过Map.entrySet遍历key和value
        //最常见
        for(Map.Entry entry:map.entrySet()){
            System.out.println(entry.getKey()+"->"+entry.getValue());
        }
 
 
        //注:Map.Entry方法解释
        //Map.Entry是Map声明的一个内部接口,此接口为泛型,定义为Entry。它表示Map中的一个实体(一个key-value对)
    }
}

 

 

你可能感兴趣的:(面试类,Java)