JAVA面试问题

1.Java中堆和栈有什么不同?

每个线程都有自己的栈内存,用于存储本地变量,方法参数和栈调用,一个线程中存储的变量对其它线程是不可见的。而堆是所有线程共享的一片公用内存区域。对象都在堆里创建,为了提升效率线程会从堆中弄一个缓存到自己的栈,如果多个线程使用该变量就可能引发问题,这时volatile 变量就可以发挥作用了,它要求线程从主存中读取变量的值。

堆:(对象)

引用类型的变量,其内存分配在堆上或者常量池(字符串常量、基本数据类型常量),需要通过new等方式来创建。

堆内存主要作用是存放运行时创建(new)的对象。

(主要用于存放对象,存取速度慢,可以运行时动态分配内存,生存期不需要提前确定)

栈:(基本数据类型变量、对象的引用变量)

基本数据类型的变量(int、short、long、byte、float、double、boolean、char等)以及对象的引用变量,其内存分配在栈上,变量出了作用域就会自动释放。

2.Spring事务传播行为?

所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:

TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。

TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。

TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。

TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。

TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。

TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

3.Spring的声明式事务管理力度是什么级别?

Spring是方法级别的

spring事务可以分为编程式事务和声明式事务

4.ArrayList和LinkedList的大致区别如下:

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 

2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 

3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

ArrayList,Vector主要区别为以下几点: 

(1):Vector是线程安全的,源码中有很多的synchronized可以看出,而ArrayList不是。导致Vector效率无法和ArrayList相比; 

(2):ArrayList和Vector都采用线性连续存储空间,当存储空间不足的时候,ArrayList默认增加为原来的50%,Vector默认增加为原来的一倍; 

5.HashSet与HashMap的区别:

HashMap:实现了Map接口,存储键值对,调用put()向map中添加元素,HashMap使用键(Key)计算Hashcode,HashMap相对于HashSet较快,因为它是使用唯一的键获取对象

HashSet:实现Set接口,仅存储对象,调用add()方法向Set中添加元素,HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false,HashSet较HashMap来说比较慢

6.HashMap和Hashtable的区别:

HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。主要的区别有:线程安全性,同步(synchronization),以及速度。

HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。

HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。

另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。

由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。

HashMap不能保证随着时间的推移Map中的元素次序是不变的。

7.线程安全是什么?线程不安全是什么?

线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。(Vector,HashTable) 

线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。(ArrayList,LinkedList,HashMap等)


8.Eureka和zookeeper的区别?


Eureka:AP

zookeeper:CP

CAP理论:一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项。

1,做分布式下的服务发现还是使用eureka更好,也就是AP特性的分布式协调工具(zookeeper因为网络故障就无法返回可用的主机)

2,zookeeper技术更加成熟,资料更多

3,Eureka。是spring cloud之下一个专门负责微服务服务注册和发现的组件,Eureka就是为了服务发现而设计的

4,Zookeeper。是用来保证分布式一致性的一个软件。不是为了服务发现注册而设计的,只不过它的特性也可以被二次开发成服务发现注册中心罢了

9.SpringCloud都有哪些组件?

 Spring Cloud为微服务架构开发涉及的配置管理,服务治理,熔断机制,智能路由,微代理,控制总线,一次性token,全局一致性锁,leader选举,分布式session,集群状态管理等操作提供了一种简单的开发方式。

    组件列:

Spring Cloud Config:配置管理工具,支持使用Git存储配置内容,支持应用配置的外部化存储,支持客户端配置信息刷新、加解密配置内容等

Spring Cloud Bus:事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与Spring Cloud Config联合实现热部署。

Spring Cloud Netflix:针对多种Netflix组件提供的开发工具包,其中包括Eureka、Hystrix、Zuul、Archaius等。

                      Netflix Eureka:一个基于rest服务的服务治理组件,包括服务注册中心、服务注册与服务发现机制的实现,实现了云端负载均衡和中间层服务器的故障转移。

                      Netflix Hystrix:容错管理工具,实现断路器模式,通过控制服务的节点,从而对延迟和故障提供更强大的容错能力。

                      Netflix Ribbon:客户端负载均衡的服务调用组件。

                      Netflix Feign:基于Ribbon和Hystrix的声明式服务调用组件。

                      Netflix Zuul:微服务网关,提供动态路由,访问过滤等服务。

                      Netflix Archaius:配置管理API,包含一系列配置管理API,提供动态类型化属性、线程安全配置操作、轮询框架、回调机制等功能。

Spring Cloud for Cloud Foundry:通过Oauth2协议绑定服务到CloudFoundry,CloudFoundry是VMware推出的开源PaaS云平台。

Spring Cloud Sleuth:日志收集工具包,封装了Dapper,Zipkin和HTrace操作。

Spring Cloud Data Flow:大数据操作工具,通过命令行方式操作数据流。

Spring Cloud Security:安全工具包,为你的应用程序添加安全控制,主要是指OAuth2。

Spring Cloud Consul:封装了Consul操作,consul是一个服务发现与配置工具,与Docker容器可以无缝集成。

Spring Cloud Zookeeper:操作Zookeeper的工具包,用于使用zookeeper方式的服务注册和发现。

Spring Cloud Stream:数据流操作开发包,封装了与Redis,Rabbit、Kafka等发送接收消息。

Spring Cloud CLI:基于 Spring Boot CLI,可以让你以命令行方式快速建立云组件

10.String、StringBuffer、StringBuilder的区别?

String:字符串常量,字符串长度不变,是被声明程final的,一次赋值不可改变

    StringBuffer:字符串变量,线程安全,如果需要频繁的对字符串内容进行修改,处于效率考虑最好使用StringBuffer。StringBuffer,在任意时间点上都包含特定的字符序列,但通过方法调用改变长度和内容

    StringBuilder:字符串变量,非线程安全。StringBuilder对象被当做一个包含字符序列的变长数组,是在JDK1.5后新增的,可用于字符串缓冲区被单线程使用时使用

11.什么是java序列化,如何实现java序列化?

 java对象的序列化是指将一个java对象写入IO流中,于此对应的是,对象的反序列化则是从IO流中恢复的Java对象。如果要让某个对象支持反序列化机制,必须让它的类是可序列化,则需要实现Serializable接口或者Externalizable接口


12.同步和异步、阻塞和非阻塞?

同步:当一个同步调用发出后,调用者要一直等待返回消息通知后,才能进行后续执行

    异步:当一个异步过程调用发出后,调用者不能立刻得到返回消息。在调用结束后,通过消息回调来通知调用者是否成功

    阻塞:阻塞调用是指调用结果返回之前,当前线程会被挂起,一直处于等待消息通知,不能够执行其他业务,函数只有在得到结果后才会返回

    非阻塞:非阻塞和阻塞的概念相对应,指再不能立刻得到借过钱,该函数不会阻塞当前线程,而会立刻返回


    同步和异步的重点在于消息通知的方式,也就是调用结果通知的方式

    阻塞和非阻塞的重点是当前线程等待消息返回的行为

    分类:同步阻塞、同步非阻塞、异步阻塞、异步非阻塞

13.创建线程的方式?

1)、继承Thread,由子类重写run方法,由run方法体来完后曾线程需要做的事

    2)、实现了Runnable接口,由run方法体来完后曾线程需要做的事

    3)、通过Callable和FutrueTask创建线程。创建Callable的实现类,实现call()方法,该call()方法作为线程执行体,并有返回值

    创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。

14.多线程安全问题?


当一个线程执行多条语句时,并运算同一个数据时,在执行过程中,其他线程参与进来,并操作这个数据,导致了错误数据的产生

    涉及到两个因素

        1、多个线程在操作共享数据

        2、有多条数据对共享数据进行运算

    解决方案:

        只要将操作共享数据的语句在某一个时段让一个线程执行完,在执行过程中,其他线程不能进来执行就可以解决--------使用同步代码块

15.sleep和wait的区别?

wait:可以指定时间也可以不指定时间,不指定时间,只能由对应的notify或者notifyall来唤醒

    sleep:必须指定时间,时间到自动从冻结状态转成运行状态(临时阻塞状态)

    wait:线程会释放执行权,而且线程会释放锁

    sleep:线程会释放执行权,但不释放锁

16.lock和synchronize的区别?

lock不是java内置的,synchronize是java的关键字,lock是一个类,通过这个类可以实现同步访问

    Lock和Synchronize的最大不同:采用Synchronize不需要用户去手动加锁,当Synchronize方法或者代码块执行完成后,系统会自动让线程释放对锁的占用,而lock则必须要用户手动释放锁,如果没有自动释放锁,会出现死锁的现象


17.final、finally、finalize区别?

final是最终的意思,可以用于修饰类、成员变量、成员方法

        它修饰的类不能被继承,修饰的变量是常量,修饰方法不能被重写

    finally:是一场处理里面的关键字

        它其中的代码永远会被执行,特殊情况:在执行前jvm退出

    finalize是Object类中的一个方法

        它用于垃圾回收器调用方式

18.HashSet是如何保证元素唯一性的呢?

如果两元素的hashCode值不同,则不会调用equals方法

    如果两元素的hashCode值相同,则继续判断equals是否返回true;

    hashCode和equals方法虽然定义在自定义对象类里面,但不是我们手动调用而是往           HashSet集合里面存储元素的时候,集合底层自己调用hashCode和equals它自己      拿对象去判断,自己判断两元素是否是同一个元素。

19.动态代理和静态代理

若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理

代理类在程序运行时创建的代理方式被成为 动态代理。 也就是说,这种情况下,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。相比于静态代理, 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类的函数

推荐阅读更多精彩内容

  • pdf下载地址:Java面试宝典 第一章内容介绍 20 第二章JavaSE基础 21 一、Java面向对象 21 ...
    王震阳阅读 73,107评论 25 504
  • Java中如何实现代理机制(JDK、CGLIB) JDK动态代理:代理类和目标类实现了共同的接口,用到Invoca...
    Y了个J阅读 1,539评论 1 12
  • Java继承关系初始化顺序 父类的静态变量-->父类的静态代码块-->子类的静态变量-->子类的静态代码快-->父...
    第六象限阅读 943评论 0 10
  • Java 面试中的重要话题 除了你看到的惊人的问题数量,我也尽量保证质量。我不止一次分享各个重要主题中的问题,也确...
    hahaYXXXJ阅读 2,207评论 0 38
  • Java 面试随着时间的改变而改变。在过去的日子里,当你知道 String 和 StringBuilder 的区别...
    Java小铺阅读 8,877评论 0 327