面试题-List和Set的区别

上周末面试被问到List和Set的区别,支支吾吾答不上(之前没有用过Set,学过却忘了),写个文章补一下。

本来想直接写一篇文章复习整个Collection Framework的,后来发现要写完可以变成一本书……(其实是水平不够)

Set:
一个不包含重复元素的 collection。
更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。

事实上最常用的Set接口的实现类HashSet,底层是使用HashMap实现的,元素是HashMap的Key,而Value是一个私有的静态的Object对象。

HashSet有一个addAll方法,可以用来给ArrayList去重(阿里代码规约也有提到):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) {  
Set set=new HashSet();
set.add("字符串1");
set.add("字符串1");
set.add("字符串1");
set.add("字符串2");
set.add("字符串3");
System.out.println("size="+ set.size()); //3

List list = new ArrayList();
list.add("字符串1");
list.add("字符串4");
list.add("字符串5");
set.addAll(list);
System.out.println("size="+ set.size() ); //5

for(String s:set) {
System.out.println(s);
}
}

面试题——强引用和Spring的模块

2018-10-19更新:关于Spring模块的理解

spring-expression是一套内置的EL表达式语言,参考文章
spring-instrument是早期版本Spring对老版本Tomcat等Web容器的支持,参考文章;
spring-tx事务相关也有用过了,@Transaction注解等
spring-messaging这块则是用于消息交互,现代似乎更倾向于REST,目前还没有用过

关于强引用:


强引用:

个人理解:强引用指向的对象,会霸占堆空间不走
学术解释:只要强引用还在,GC永远不会回收掉被引用的对象(via 深入理解JVM),如果内存不足就OOM。

1
Object o=new Object();

软引用:

个人理解:设置了软引用的对象,会在内存里苟且偷生到内存不足的时候,被用作缓存。
学术解释:用于描述非必需对象,在系统发生内存溢出异常之前,将会把软引用列入回收对象进行第二次回收,如果还是没有足够的内存才会抛出内存溢出。(via 深入理解JVM)

1
SoftReference<String> softRef=new SoftReference<String>(str); 

弱引用:

个人理解:与软引用类似,但是它只能活到下一次GC
学术解释:软引用、弱引用可以和一个引用队列联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。
(关于引用队列暂时理解不了,先死记下来)

虚引用:

个人理解:唯一的作用是,虚引用关联的对象被回收时会收到一个通知,用于细粒度的内存控制。
学术解释:有虚引用的对象必须联合引用队列使用,被回收时会将这个引用加入到关联的队列里。

Spring的模块


(稍微扯几句,是不是只有我一个人觉得java是同人逼死官方,Mybatis逼死了JPA,Spring逼死了EJB)

核心容器

  • spring-core提供了框架的基本组成部分,包括 IoC 和DI功能。(见名知义,核心)

  • spring-beans提供BeanFactory,它是一个工厂模式的复杂实现。(管理beans)

  • spring-context是访问定义和配置的任何对象的媒介。ApplicationContext 接口是上下文模块的重点。(用来处理XML配置文件)

  • spring-expression(Spring Expression Language ,SpEL)在运行时提供了查询和操作一个对象图的强大的表达式语言。(暂时没有用到过。)

数据访问/集成

  • spring-jdbc提供了删除冗余的 JDBC 相关编码的 JDBC 抽象层。(让jdbc简洁化,然而现在主流用Mybatis、Hibernate的多,一般还整合了连接池,这个似乎用不到)

  • spring-orm(Spring Object/Relational Mapping)为流行的对象关系映射 API,包括 JPA,JDO,Hibernate 和 iBatis,提供了集成层。(将数据库虚拟化为对象,)

  • spring-oxm(Spring Object/XML Marshalling)提供了抽象层,它支持对 JAXB,Castor,XMLBeans,JiBX 和 XStream 的对象/XML 映射实现。

  • spring-jms包含生产和消费的信息的功能。(之前尝试配置远程Tomcat时遇到过这块的错误,但是我没有去解决,目前是我的知识盲区,有待学习)

  • spring-tx模块为实现特殊接口的类及所有的 POJO 支持编程式和声明式事务管理。(暂时没用过Spring的事务管理……)

Web 层

  • spring-web提供了基本的面向 web 的集成功能,例如多个文件上传的功能和使用 servlet 监听器和面向 web 应用程序的上下文来初始化 IoC 容器。(就是把自己做成一个servlet,容器一启动Spring也就启动了)

  • spring-webmvc包含 Spring 的模型-视图-控制器(MVC),实现了 web 应用程序。(就是现在著名的SpringMVC)

  • spring-websocket为 WebSocket-based 提供了支持,而且在 web 应用程序中提供了客户端和服务器端之间通信的两种方式。(知识盲区,并没有用过_(:з」∠)_)

  • spring-webmvc-portlet提供了在 portlet 环境中实现 MVC,并且反映了 Web-Servlet 模块的功能。(知识盲区,并没有用过_(:з」∠)_)

其他

  • spring-aop提供了面向切面的编程实现,允许你定义方法拦截器和切入点对代码进行干净地解耦,它实现了应该分离的功能。(另一种解耦方式,单独开发,需要的时候插入)

  • spring-aspects提供了与 AspectJ 的集成,这是一个功能强大且成熟的面向切面编程(AOP)框架。(结合aop使用,实现织入)

  • spring-instrument在一定的应用服务器中提供了类 instrumentation的支持和类加载器的实现。(?????)

  • spring-messaging为 STOMP 提供了支持作为在应用程序中 WebSocket 子协议的使用。它也支持一个注解编程模型,它是为了选路和处理来自 WebSocket 客户端的 STOMP 信息。(?????)

  • spring-test支持对具有 JUnit 或 TestNG 框架的 Spring 组件的测试。(@Runwith注解,支持Test类中运行Spring框架,而不用启动web容器)

面试题——Java线程的状态

Java线程的状态

1)NEW

线程创建之后,启动之前的状态。

1
2
Thread thread = new Thread();
thread.getState();//NEW

2)RUNNABLE

启动完成,正常运行的线程。
(需要注意的是,线程等待系统资源时也会处于该状态,例如BIO等待网络资源的时候)

3)BLOCKED

被阻塞的状态,出现在多线程环境下。
线程A占用了一个synchronize的方法/代码块/对象,这时候线程B如果也想占用这个资源,就会处于BLOCKED状态

4)WAITING

等待中的状态,由于执行了Object.wait();或者Thread.join()并且没有指定Timeout,以及LockSupport.park()而导致。
如果调用了Object.notify()或者notifyAll()方法,等待状态就会结束。

5)TIMED_WAITING

如果调用了Thread.sleep();或者Object.wait(),Thread.join(),并指定了Timeout,
或者LockSupport的parkNanos(),parkUntil()方法,并指定了Timeout。线程就会进入TimedWaiting状态。

6)TERMINATED

线程的run方法执行完毕后,在虚拟机层面上的状态。