java中级面试题

  HashMap,LinkedHashMap,TreeMap的区别

1.        HashMap,LinkedHashMap,TreeMap都属于Map。

2.        Map的主要作用是用于存储键(key)值(value)对,根据键得到值,因此不允许键重复,但允许值重复。

3.        HashMap是一个最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有最快的访问速度。HashMap最多只允许一条记录的键为Null;允许多条记录的值为Null;HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用Collections的synchronizedMap方法使HashMap具有同步的能力。

4.        LinkedHashMap也是一个HashMap,但是内部维持了一个双向链表,可以保持顺序;

5.        TreeMap不仅可以保持顺序,而且可以用于排序;

 

  ArrayList和LinkedList的区别

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

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

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

 概述一下SpringMVC的工作原理

1.        客户端发出一个HTTP请求给web服务器,web服务器对HTTP请求进行解析,如果匹配DispatcherServlet的请求映射路径(在web.xml中指定,或者使用注解),web容器将请求转交给dispatcherServelet。

2.        DispacherServelet接受到这个请求之后根据请求的信息(包括URL、Http方法、请求报文头和请求参数Cookie等)以及HandleMapping的配置找到处理请求的处理器Haddler。

3.        DispatcherServlet根据HandlerMapping找到对应的Handler,将处理权交给Handler(Handler将具体的处理进行封装),再由具体的HandlerAdapter对Handler进行具体的调用。

4.        Handler对数据处理完成以后将返回一个ModelAndView()对象给DispatcherServlet。

5.        Handler返回的ModelAndView()只是一个逻辑视图并不是一个正式的视图,DispatcherSevlet通过ViewResolver将逻辑视图转化为真正的视图View。

6.        Dispatcher通过model解析出ModelAndView()中的参数进行解析最终展现出完整的view并返回给客户端。

 

spring里面的aop的原理是什么

BeanFactory 和ApplicationContext的区别

BeanFactoryApplicationContext都是接口,并且ApplicationContextBeanFactory的子接口。

 

BeanFactorySpring中最底层的接口,提供了最简单的容器的功能,只提供了实例化对象和拿对象的功能。而ApplicationContextSpring的一个更高级的容器,提供了更多的有用的功能。 

 

ApplicationContext提供的额外的功能:国际化的功能、消息发送、响应机制、统一加载资源的功能、强大的事件机制、对Web应用的支持等等。

 

加载方式的区别:BeanFactory采用的是延迟加载的形式来注入BeanApplicationContext则相反的,它是在Ioc启动时就一次性创建所有的Bean,好处是可以马上发现Spring配置文件中的错误,坏处是造成浪费。

 如何实现HashMap顺序存储

LinkedHashMap里面有一个模拟的“双向循环链表”,用来保存entry的插入顺序,我也可以采用这种方法来在插入的时候保存key和value的有序。这里暂定名为OrderedHashMap,主要代码是从LinkedHashMap抄过来的,它也维护着两个模拟“双向循环链表”:keyHeader和valueHeader,保持key或value由小到大的顺序。当有个元素put进来后,除把它存在散列桶中外,还要在keyHeader按key的大小插入,也要在valueHeader上按value的顺序插入。想要输出的话,可以从这两个“头指针”向前或向后来迭代得到key或value有序的entry。(可以实现key和value,正序逆序的输出,只对数值型比较,如果不是数值型的话,如HashMap般正常处理)

 

 HashMap、HashTable和ConcurrentHashMap的区别

HashMap和HashTable的区别一种比较简单的回答是:

1.                  HashMap是非线程安全的,HashTable是线程安全的,内部的方法基本都经过synchronized修饰。

2.                  因为同步、哈希性能等原因,性能肯定是HashMap更佳。

3.                  HashMap允许有null值的存在,而在HashTable中put进的键值只要有一个null,直接抛出NullPointerException。

HashMap和ConCurrentHashMap的对比:

先对ConcurrentHashMap进行一些介绍吧,它是线程安全的HashMap的实现。

HashTable里使用的是synchronized关键字,这其实是对对象加锁,锁住的都是对象整体,当Hashtable的大小增加到一定的时候,性能会急剧下降,因为迭代时需要被锁定很长的时间。

 

1.        ConcurrentHashMap对整个桶数组进行了分割分段(Segment),然后在每一个分段上都用lock锁进行保护,相对于HashTable的syn关键字锁的粒度更精细了一些,并发性能更好,而HashMap没有锁机制,不是线程安全的。

 

2.        HashMap的键值对允许有null,但是ConCurrentHashMap都不允许。

 

wait和sleep的区别

对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。

sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。

在调用sleep()方法的过程中,线程不会释放对象锁。

而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

 

10)JVM的内存结构,JVM的算法

JVM内存结构主要有三大块:堆内存、方法区和栈。堆内存是JVM中最大的一块由年轻代和老年代组成,而年轻代内存又被分成三部分,Eden空间、From Survivor空间、To Survivor空间,默认情况下年轻代按照8:1:1的比例来分配;

 

方法区存储类信息、常量、静态变量等数据,是线程共享的区域,为与Java堆区分,方法区还有一个别名Non-Heap(非堆);栈又分为java虚拟机栈和本地方法栈主要用于方法的执行。

 

http,https协议

HTTP 和 HTTPS 的相同点

大多数情况下,HTTP 和 HTTPS 是相同的,因为都是采用同一个基础的协议,作为 HTTP 或 HTTPS 客户端——浏览器,设立一个连接到 Web 服务器指定的端口。当服务器接收到请求,它会返回一个状态码以及消息,这个回应可能是请求信息、或者指示某个错误发送的错误信息。系统使用统一资源定位器 URI 模式,因此资源可以被唯一指定。而 HTTPS 和 HTTP 唯一不同的只是一个协议头(https)的说明,其他都是一样的。

HTTP 和 HTTPS 的不同之处

1.HTTP 的 URL 以 http:// 开头,而 HTTPS 的 URL 以 https:// 开头

2.HTTP 是不安全的,而 HTTPS 是安全的

3.HTTP 标准端口是 80 ,而 HTTPS 的标准端口是 443

4.在 OSI 网络模型中,HTTP 工作于应用层,而HTTPS 工作在传输层

5.HTTP 无需加密,而 HTTPS 对传输的数据进行加密

6.HTTP 无需证书,而 HTTPS 需要认证证书

17)tcp/ip协议簇是什么意思

TCP/IP是一个网络通讯协议群,它包含了很多通信协议。这些协议制定了网络设备、计算机连入网络以及数据是如何在它们之间进行传输的标准。TCP协议又叫传输控制协议,作用于传输层。IP协议又叫网络间互联协议,工作在网络层。它们都是TCP/IP协议簇中非常重要的协议。

 

 NIO对比IO的有点在哪里

Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。

1.        io是面向流的,也就是读取数据的时候是从流上逐个读取,所以数据不能进行整体以为,没有缓冲区;nio是面向缓冲区的,数据是存储在缓冲区中,读取数据是在缓冲区中进行,所以进行数据的偏移操作更加方便

2.        io是阻塞的,当一个线程操作io时如果当前没有数据可读,那么线程阻塞,nio由于是对通道操作io,所以是非阻塞,当一个通道无数据可读,可切换通道处理其他io

3.        nio有selecter选择器,就是线程通过选择器可以选择多个通道,而io只能处理一个

 

redis常用的五种数据类型

说一下spring中Bean的作用域

 

singleton

    Spring IoC容器中只会存在一个共享的Bean实例,无论有多少个Bean引用它,始终指向同一对象。Singleton作用域是Spring中的缺省作用域。

prototype

    每次通过Spring容器获取prototype定义的bean时,容器都将创建一个新的Bean实例,每个Bean实例都有自己的属性和状态,而singleton全局只有一个对象。

request

    在一次Http请求中,容器会返回该Bean的同一实例。而对不同的Http请求则会产生新的Bean,而且该bean仅在当前Http Request内有效。

session

    在一次Http Session中,容器会返回该Bean的同一实例。而对不同的Session请求则会创建新的实例,该bean实例仅在当前Session内有效。

global Session

    在一个全局的Http Session中,容器会返回该Bean的同一个实例,仅在使用portlet context时有效。

 


 

 

说一下spring中Bean的生命周期

 

  • 实例化一个Bean,也就是我们通常说的new
  • 按照Spring上下文对实例化的Bean进行配置,也就是IOC注入。
  • 如果这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的是Spring配置文件中BeanID
  • 如果这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(),传递的是Spring工厂本身(可以用这个方法获取到其他Bean)。
  • 如果这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文。
  • 如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用After方法,也可用于内存或缓存技术。
  • 如果这个BeanSpring配置文件中配置了init-method属性会自动调用其配置的初始化方法。
  • 如果这个Bean关联了BeanPostProcessor接口,将会调用postAfterInitialization(Object obj, String s)方法。
  • Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean接口,会调用其实现的destroy方法。
  • 最后,如果这个BeanSpring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

对Spring中依赖注入两种方式的认识

 

两种注入方式为:构造方法注入和设值注入

  1. 设值注入与传统的JavaBean的写法更相似,程序员更容易理解、接受,通过setter方式设定依赖关系显得更加直观、明显;
  2. 对于复杂的依赖关系,如果采用构造注入,会导致构造器过于臃肿,难以阅读。Spring在创建Bean实例时,需要同时实例化其依赖的全部实例,因而会产生浪费。而使用设置注入,则避免这下问题;
  3. 在某些属性可选的情况下,多参数的构造器更加笨拙,官方更鼓励使用设值注入。
  4. 构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入。
  5. 对于依赖关系无须变化的Bean,构造注入更有用处,因为没有setter方法,所有的依赖关系全部在构造器内设定,因此,不用担心后续代码对依赖关系的破坏。
  6. 构造注入使依赖关系只能在构造器中设定,则只有组件的创建者才能改变组件的依赖关系。对组件的调用者而言,组件内部的依赖关系完全透明,更符合高内聚的原则。
  7. 设值注入不会重写构造方法的值。如果我们对同一个变量同时使用了构造方法注入又使用了设置方法注入的话,那么构造方法将不能覆盖由设值方法注入的值。
  8. 建议采用以设值注入为主,构造注入为辅的注入策略。对于依赖关系无须变化的注入,尽量采用构造注入;而其他的依赖关系的注入,则考虑采用set注入。

Spring 配置bean实例化有哪些方式?

1)使用类构造器实例化(默认无参数)

<bean id="bean1" class="cn.itcast.spring.b_instance.Bean1"></bean>

    2)使用静态工厂方法实例化(简单工厂模式)

//下面这段配置的含义:调用Bean2FactorygetBean2方法得到bean2

<bean id="bean2" class="cn.itcast.spring.b_instance.Bean2Factory" factory-method="getBean2"></bean>

    3)使用实例工厂方法实例化(工厂方法模式)

//先创建工厂实例bean3Facory,再通过工厂实例创建目标bean实例

<bean id="bean3Factory" class="cn.itcast.spring.b_instance.Bean3Factory"></bean>

<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean>

 

 

Spring如何处理线程并发问题

Spring使用ThreadLocal解决线程安全问题

我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态,因为有状态的Bean就可以在多线程中共享了。

ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。

在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。

ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。

由于ThreadLocal中可以持有任何类型的对象,低版本JDK所提供的get()返回的是Object对象,需要强制类型转换。但JDK5.0通过泛型很好的解决了这个问题,在一定程度地简化ThreadLocal的使用。

概括起来说,对于多线程资源共享的问题,同步机制采用了以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

实例方法和静态方法有什么不一样?

常用的集合类有哪些?比如List如何排序?

分两种,一种实现Set接口,一种是实现List接口的。

SetTreeSet,HashSet.

List:ArrayList,LinkedList,Vector(线程安全)

JDK7以前用collections.sort(list,Comparator).

JDK8直接用List.sort(Comparator).

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值