搜档网
当前位置:搜档网 › 2018最新Java面试题整理

2018最新Java面试题整理

1基础篇

1.1基本功

1.1.1面向对象特征

封装,继承,多态和抽象

1、封装

封装给对象提供了隐藏内部特性和行为的能力。对象提供一些能被其他对象访问的方法

来改变它内部的数据。在 Java 当中,有 3 种修饰符: public, private 和

protected。每一种修饰符给其他的位于同一个包或者不同包下面对象赋予了不同的访

问权限。下面列出了使用封装的一些好处:

1)通过隐藏对象的属性来保护对象内部的状态。

2)提高了代码的可用性和可维护性,因为对象的行为可以被单独的改变或者是扩展。

3)禁止对象之间的不良交互提高模块化

2、继承

继承给对象提供了从基类获取字段和方法的能力。继承提供了代码的重用行,也可以在

不修改类的情况下给现存的类添加新特性。

3、多态

多态是编程语言给不同的底层数据类型做相同的接口展示的一种能力。一个多态类型上

的操作可以应用到其他类型的值上面。

4、抽象

抽象是把想法从具体的实例中分离出来的步骤,因此,要根据他们的功能而不是实现细

节来创建类。 Java 支持创建只暴漏接口而不包含方法实现的抽象的类。这种抽象技术

的主要目的是把类的行为和实现细节分离开。

1.1.2final, finally, finalize 的区别

1、final修饰符(关键字)

如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。

因此一个类不能既被声明为 abstract的,又被声明为final的。

将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量

必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方

法也同样只能使用,不能重载。

2、finally

在异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配

的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。

3、finalize

方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去

之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个

对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖

finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收

集器删除对象之前对这个对象调用的。

1.1.3int 和 Integer 有什么区别

int是基本数据类型,而Integer是其包装类,注意是一个类。

为什么要提供包装类呢???

一是为了在各种类型间转化,通过各种方法的调用。否则你无法直接通过变量转化。

1.1.4重载和重写的区别

override(重写)

1. 方法名、参数、返回值相同。

2. 子类方法不能缩小父类方法的访问权限。

3. 子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常)。

4. 存在于父类和子类之间。

5. 方法被定义为final不能被重写。

overload(重载)

1. 参数类型、个数、顺序至少有一个不相同。

2. 不能重载只有返回值不同的方法名。

英文Overloading Overiding

定义方法名称相同,参数的类型或个数不同方法名称、参数类型、返回值类型全部相同

权限对权限没要求被重写的方法不能拥有更严格的权限

范围发生在一个类中发生在继承类中

1.1.5抽象类和接口有什么区别

接口是公开的,里面不能有私有的方法或变量,是用于让别人使用的,而抽象类是可以有私有方法或私有变量的,另外,实现接口的一定要实现接口里定义的所有方法,而实现抽象类可以有选择地重写需要用到的方法,一般的应用里,最顶级的是接口,然后是抽象类实现接口,最后才到具体类实现。

还有,接口可以实现多重继承,而一个类只能继承一个超类,但可以通过继承多个接口实现多重继承,接口还有标识(里面没有任何方法,如Remote接口)和数据共享(里面的变量全是常量)的作用。

1.1.6说说反射的用途及实现

Java反射机制主要提供了以下功能:在运行时构造一个类的对象;判断一个类所具有的成员变量和方法;调用一个对象的方法;生成动态代理。反射最大的应用就是框架

Java反射的主要功能:

- 确定一个对象的类

- 取出类的modifiers,数据成员,方法,构造器,和超类.

- 找出某个接口里定义的常量和方法说明.

- 创建一个类实例,这个实例在运行时刻才有名字(运行时间才生成的对象).

- 取得和设定对象数据成员的值,如果数据成员名是运行时刻确定的也能做到.

- 在运行时刻调用动态对象的方法.

- 创建数组,数组大小和类型在运行时刻才确定,也能更改数组成员的值.

反射的应用很多,很多框架都有用到

spring 的 ioc/di 也是反射….

javaBean和jsp之间调用也是反射….

struts的 FormBean 和页面之间…也是通过反射调用….

JDBC 的 classForName()也是反射…..

hibernate的 find(Class clazz) 也是反射….

反射还有一个不得不说的问题,就是性能问题,大量使用反射系统性能大打折扣。怎么使用使你的系统达到最优就看你系统架构和综合使用问题啦,这里就不多说了。

来源:https://www.sodocs.net/doc/84596443.html,/blog/1423512

1.1.7说说自定义注解的场景及实现

登陆、权限拦截、日志处理,以及各种Java框架,如Spring,Hibernate,JUnit 提到注解就不能不说反射,Java自定义注解是通过运行时靠反射获取注解。

实际开发中,例如我们要获取某个方法的调用日志,可以通过AOP(动态代理机制)给方法添加切面,通过反射来获取方法包含的注解,如果包含日志注解,就进行日志记录。

1.1.8HTTP 请求的 GET 与 POST 方式的区别

1、请求数据的方式

GET请求,请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接。

URL的编码格式采用的是ASCII编码,而不是uniclde,即是说所有的非ASCII字符都

要编码之后再传输。POST请求会把请求的数据放置在HTTP请求包的包体中。因此,GET

请求的数据会暴露在地址栏中,而POST请求则不会。

2、传输数据的大小

在HTTP规范中,没有对URL的长度和传输的数据大小进行限制。但是在实际开发过程

中,对于GET,特定的浏览器和服务器对URL的长度有限制。因此,在使用GET请求时,

传输数据会受到URL长度的限制。对于POST,由于不是URL传值,理论上是不会受限

制的,但是实际上各个服务器会规定对POST提交数据大小进行限制,Apache、IIS都有

各自的配置。

3、安全性

POST的安全性比GET的高。这里的安全是指真正的安全,而不同于上面GET提到的安全

方法中的安全,上面提到的安全仅仅是不修改服务器的数据。比如,在进行登录操作,

通过GET请求,用户名和密码都会暴露再URL上,因为登录页面有可能被浏览器缓存以

及其他人查看浏览器的历史记录的原因,此时的用户名和密码就很容易被他人拿到了。

除此之外,GET请求提交的数据还可能会造成Cross-site request frogery攻击

4、HTTP中的GET,POST,SOAP协议都是在HTTP上运行的

参考:https://https://www.sodocs.net/doc/84596443.html,/wangli-66/p/5453507.html

1.1.9Session与Cookie 区别

cookie是Web服务器发送给浏览器的一块信息。浏览器会在本地文件中给每一个 Web 服务器存储cookie。以后浏览器在给特定的 Web 服务器发请求的时候,同时会发送所有为

该服务器存储的 cookie。下面列出了session和cookie的区别:

无论客户端浏览器做怎么样的设置,session都应该能正常工作。

客户端可以选择禁用cookie,但是,session 仍然是能够工作的,因为客户端无法禁用服务端的session。

1.1.10JDBC 流程

1、加载JDBC驱动程序:

在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),这通

过https://www.sodocs.net/doc/84596443.html,ng.Class类的静态方法forName(String className)实现。

例如:

//加载MySql的驱动类

Class.forName("com.mysql.jdbc.Driver");

成功加载后,会将Driver类的实例注册到DriverManager类中。

2、提供JDBC连接的URL

- 连接URL定义了连接数据库时的协议、子协议、数据源标识。

- 书写形式:协议:子协议:数据源标识

协议:在JDBC中总是以jdbc开始子协议:是桥连接的驱动程序或是数据库管理系统名称。

数据源标识:标记找到数据库来源的地址与连接端口。

例如:

//MySql的连接URL,true表示使用Unicode字符集, characterEncoding字符编码方式。

jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=gbk;

3、创建数据库的连接

- 要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象,该对象就代表一个数据库的连接。

- 使用DriverManager的getConnectin(String url , String username , String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和密码来获得。

例如:

//连接MySql数据库,用户名和密码都是root

String url = "jdbc:mysql://localhost:3306/test";

Connection con = DriverManager.getConnection(url, "root","root")

4、创建一个Statement,要执行SQL语句,必须获得java.sql.Statement实例,Statement

实例分为以下3 种类型:

1)执行静态SQL语句。通常通过Statement实例实现。

Statement stmt = con.createStatement() ;

2)执行动态SQL语句。通常通过PreparedStatement实例实现。

PreparedStatement pstmt = con.prepareStatement(sql) ;

3)执行数据库存储过程。通常通过CallableStatement实例实现。

CallableStatement c stmt = con.prepareCall(“{CALL demoSp(? , ?)}”) ;

5、执行SQL语句

提供了三种执行SQL语句的方法:executeQuery 、executeUpdate 和execute

1)ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句,返

回一个结果集(ResultSet)对象。

2)int executeUpdate(String sqlString):用于执行INSERT、UPDATE或 DELETE语

句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等

3)execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的语

句。

6、处理结果:

1)执行更新返回的是本次操作影响到的记录数。

2)执行查询返回的结果是一个ResultSet对象。

? ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了

对这些行中数据的访问(列是从左到右编号的,并且从列1开始)。

? 使用结果集(ResultSet)对象的访问方法获取数据:

while(rs.next()){

String name = rs.getString(“name”) ;

String pass = rs.getString(1) ; // 此方法比较高效

}

7、关闭JDBC对象

操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声明

顺序相反:

1)关闭记录集rs.close()

2)关闭声明stmt.close()

3)关闭连接对象conn.close()

1.1.11MVC 设计思想

M:Model 模型

V:View 视图

C:Controller 控制器

模型就是封装业务逻辑和数据的一个一个的模块,

控制器就是调用这些模块的(java中通常是用Servlet来实现,框架的话很多是用Struts2来实现这一层),

视图就主要是你看到的,比如JSP等。

当用户发出请求的时候,控制器根据请求来选择要处理的业务逻辑和要选择的数据,再返回去把结果输出到视图层,这里可能是进行重定向或转发等.

1.1.12equals 与 == 的区别

值类型(int,char,long,boolean等)都是用==判断相等性。

对象引用的话,==判断引用所指的对象是否是同一个。

equals是Object的成员函数,有些类会覆盖(override)这个方法,用于判断对象的等价性。

例如String类,两个引用所指向的String都是”abc”,但可能出现他们实际对应的对象并不是同一个(和jvm实现方式有关),因此用==判断他们可能不相等,但用equals 判断一定是相等的。

1.2集合

1.2.1List 和 Set 区别

List,Set都是继承自Collection接口

List特点:元素有放入顺序,元素可重复

Set特点:元素无放入顺序,元素不可重复,重复元素会覆盖掉

(注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的,加入Set的Object必须定义equals()方法,另外list支持for循环,也就是通过下标来遍历,也可以用迭代器,但是set只能用迭代,因为他无序,无法用下标来取得想要的值。)

Set和List对比:

Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。

List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。

1.2.2List 和 Map 区别

List是对象集合,允许对象重复。

Map是键值对的集合,不允许key重复。

1.2.3Arraylist 与 LinkedList 区别

Arraylist:

优点:ArrayList是实现了基于动态数组的数据结构,因为地址连续,一旦数据存储好了,查询操作效率会比较高(在内存里是连着放的)。

缺点:因为地址连续, ArrayList要移动数据,所以插入和删除操作效率比较低。LinkedList:

优点:LinkedList基于链表的数据结构,地址是任意的,所以在开辟内存空间的时候不需要等一个连续的地址,对于新增和删除操作add和remove,LinedList比较占优势。LinkedList 适用于要头尾操作或插入指定位置的场景

缺点:因为LinkedList要移动指针,所以查询操作性能比较低。

适用场景分析:

当需要对数据进行对此访问的情况下选用ArrayList,当需要对数据进行多次增加删除修改时采用LinkedList。

1.2.4ArrayList 与 Vector 区别

//构造一个初始容量为10的空列表

public ArrayList()

//构造一个具有指定初始容量的空列表。

public ArrayList(int initialCapacity)

//构造一个包含指定collection 的元素的列表

public ArrayList(Collection c)

Vector有四个构造方法:

//使用指定的初始容量和等于零的容量增量构造一个空向量

public Vector()

//构造一个空向量,使其内部数据数组的大小,其标准容量增量为零

public Vector(int initialCapacity)

//构造一个包含指定collection 中的元素的向量

public Vector(Collection c)

//使用指定的初始容量和容量增量构造一个空的向量

public Vector(int initialCapacity,int capacityIncrement)

ArrayList和Vector都是用数组实现的,主要有这么三个区别:

Vector是多线程安全的,线程安全就是说多线程访问同一代码,不会产生不确定的结果。而ArrayList不是,这个可以从源码中看出,Vector类中的方法很多有synchronized进行修饰,这样就导致了Vector在效率上无法与ArrayList相比;

两个都是采用的线性连续空间存储元素,但是当空间不足的时候,两个类的增加方式是不同。Vector可以设置增长因子,而ArrayList不可以。

Vector是一种老的动态数组,是线程同步的,效率很低,一般不赞成使用。

适用场景分析:

Vector是线程同步的,所以它也是线程安全的,而ArrayList是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用ArrayList效率比较高。

如果集合中的元素的数目大于目前集合数组的长度时,在集合中使用数据量比较大的数据,用Vector有一定的优势。

1.2.5HashMap和Hashtable的区别

1.hashMap去掉了HashTable的contains方法,但是加上了containsValue()和containsKey ()方法。

2.hashTable同步的,而HashMap是非同步的,效率上逼hashTable要高。

3.hashMap允许空键值,而hashTable不允许。

注意:

TreeMap:非线程安全基于红黑树实现。TreeMap没有调优选项,因为该树总处于平衡状态。Treemap:适用于按自然顺序或自定义顺序遍历键(key)。

参考:https://www.sodocs.net/doc/84596443.html,/qq_22118507/article/details/51576319

1.2.6HashSet 和 HashMap 区别

set是线性结构,set中的值不能重复,hashset是set的hash实现,hashset中值不能重复是用hashmap的key来实现的。

map是键值对映射,可以空键空值。HashMap是Map接口的hash实现,key的唯一性是通过key值hash值的唯一来确定,value值是则是链表结构。

他们的共同点都是hash算法实现的唯一性,他们都不能持有基本类型,只能持有对象

1.2.7HashMap 和 ConcurrentHashMap 的区别

ConcurrentHashMap是线程安全的HashMap的实现。

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

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

1.2.8HashMap 的工作原理及代码实现

简单地说,HashMap 在底层将 key-value 当成一个整体进行处理,这个整体就是一个Entry 对象。HashMap 底层采用一个 Entry[] 数组来保存所有的 key-value 对,当需要存储一个 Entry 对象时,会根据hash算法来决定其在数组中的存储位置,在根据equals方

法决定其在该数组位置上的链表中的存储位置;

当需要取出一个Entry时,也会根据hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Entry。

Fail-Fast机制是java集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生 fail-fast 事件。

例如:当某一个线程A通过 iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出 ConcurrentModificationException异常,产生 fail-fast 事件。

参考:https://tracylihui.github.io/2015/07/01/Java集合学习1:HashMap的实现原理1.2.9Con currentHashMap 的工作原理及代码实现

HashTable里使用的是synchronized关键字,这其实是对对象加锁,锁住的都是对象整体,当Hashtable的大小增加到一定的时候,性能会急剧下降,因为迭代时需要被锁定很长的时间。ConcurrentHashMap算是对上述问题的优化,其构造函数如下,默认传入的是16,0.75,16。

ConcurrentHashMap引入了分割(Segment),上面代码中的最后一行其实就可以理解为把一个大的Map拆分成N个小的HashTable,在put方法中,会根据hash(paramK.hashCode())来决定具体存放进哪个Segment,如果查看Segment的put操作,我们会发现内部使用的同步机制是基于lock操作的,这样就可以对Map的一部分(Segment)进行上锁,这样影响的只是将要放入同一个Segment的元素的put操作,保证同步的时候,锁住的不是整个Map (HashTable就是这么做的),相对于HashTable提高了多线程环境下的性能,因此HashTable 已经被淘汰了。

1.3线程

1.3.1创建线程的方式及实现

Java中创建线程主要有三种方式:

一、继承Thread类创建线程类

(1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。

(2)创建Thread子类的实例,即创建了线程对象。

(3)调用线程对象的start()方法来启动该线程。

二、通过Runnable接口创建线程类

(1)定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。

(2)创建 Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。

(3)调用线程对象的start()方法来启动该线程。

三、通过Callable和Future创建线程

(1)创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。

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

(3)使用FutureTask对象作为Thread对象的target创建并启动新线程。

(4)调用FutureTask对象的get()方法来获得子线程执行结束后的返回值

创建线程的三种方式的对比

采用实现Runnable、Callable接口的方式创见多线程时,优势是:

线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。

在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。

劣势是:

编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。

使用继承Thread类的方式创建多线程时优势是:

编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。

劣势是:

线程类已经继承了Thread类,所以不能再继承其他父类。

1.3.2sleep() 、join()、yield()有什么区别

1、sleep()方法

在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。让其他线程有机会继续执行,但它并不释放对象锁。也就是如果有Synchronized同步块,其他线程仍然不能访问共享数据。注意该方法要捕获异常

比如有两个线程同时执行(没有Synchronized),一个线程优先级为MAX_PRIORITY,另一个为MIN_PRIORITY,如果没有Sleep()方法,只有高优先级的线程执行完成后,低优先级的线程才能执行;但当高优先级的线程sleep(5000)后,低优先级就有机会执行了。

总之,sleep()可以使低优先级的线程得到执行的机会,当然也可以让同优先级、高优先级的线程有执行的机会。

2、yield()方法

yield()方法和sleep()方法类似,也不会释放“锁标志”,区别在于,它没有参数,即yield()方法只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行,另外yield()方法只能使同优先级或者高优先级的线程得到执行机会,这也和sleep()方法不同。

3、join()方法

Thread的非静态方法join()让一个线程B“加入”到另外一个线程A的尾部。在A执行完毕之前,B不能工作。

Thread t = new MyThread();

t.start();

t.join();

保证当前线程停止执行,直到该线程所加入的线程完成为止。然而,如果它加入的线程没有存活,则当前线程不需要停止。

1.3.3说说 CountDownLatch 原理

CountDownLatch是同步工具类之一,可以指定一个计数值,在并发环境下由线程进行减1操作,当计数值变为0之后,被await方法阻塞的线程将会唤醒,实现线程间的同步。

1、构造器。构造函数很简单地传递计数值给Sync,并且设置了state。

2、阻塞线程。await方法,直接调用了AQS(即Sync)的acquireSharedInterruptibly

首先尝试获取共享锁,实现方式和独占锁类似,由CountDownLatch实现判断逻辑。

返回1代表获取成功,返回-1代表获取失败。如果获取失败,需要调用doAcquireSharedInterruptibly:

doAcquireSharedInterruptibly的逻辑和独占功能具体如下:

1)创建的Node是定义成共享的(Node.SHARED);

2)被唤醒后重新尝试获取锁,不只设置自己为head,还需要通知其他等待的线程。(重点

看后文释放操作里的setHeadAndPropagate)

3、释放操作。countDown操作实际就是释放锁的操作,每调用一次,计数值减少1。

同样是首先尝试释放锁,具体实现在CountDownLatch中:

毕,被await阻塞的线程可以唤醒了,下一步调用doReleaseShared:

标记1里,头节点状态如果SIGNAL,则状态重置为0,并调用unparkSuccessor唤醒下个节点。

标记2里,被唤醒的节点状态会重置成0,在下一次循环中被设置成PROPAGATE状态,代表状态要向后传播。

参考:

分析CountDownLatch的实现原理

什么时候使用CountDownLatch

Java并发编程:CountDownLatch、CyclicBarrier和Semaphore

1)CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;

而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;

另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。

2)Semaphore其实和锁有点类似,它一般用于控制对某组资源的访问权限。

1.3.4说说 CyclicBarrier 原理

参考:

JUC回顾之-CyclicBarrier底层实现和原理

1.3.5说说 Semaphore 原理

JAVA多线程–信号量(Semaphore)

JUC回顾之-Semaphore底层实现和原理

1.3.6说说 Exchanger 原理

java.util.concurrent.Exchanger应用范例与原理浅析

1.3.7说说 CountDownLatch 与 CyclicBarrier 区别

减计数方式加计数方式

计算为0时释放所有等待的线程计数达到指定值时释放所有等待线程

计数为0时,无法重置计数达到指定值时,计数置为0重新开始

调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响调用await()方法计数加1,若加1后的值不等于构造方法的值,则线程阻塞

不可重复利用可重复利用

尽量把CyclicBarrier和CountDownLatch的区别说通俗点

1.3.8ThreadLocal 原理分析

ThreadLocal不是用来解决对象共享访问问题的,而主要是提供了保持对象的方法和避免参数传递的方便的对象访问方式。归纳了两点:

1)每个线程中都有一个自己的ThreadLocalMap类对象,可以将线程自己的对象保持

到其中,各管各的,线程可以正确的访问到自己的对象。

2)将一个共用的ThreadLocal静态实例作为key,将不同对象的引用保存到不同线程

的ThreadLocalMap中,然后在线程执行的各处通过这个静态ThreadLocal实例的

get()方法取得自己线程保存的那个对象,避免了将这个对象作为参数传递的麻烦。Java并发编程:深入剖析ThreadLocal

1.3.9讲讲线程池的实现原理

线程池的具体实现原理,将从下面几个方面讲解:

1.线程池状态

1)当创建线程池后,初始时,线程池处于RUNNING状态;

2)如果调用了shutdown()方法,则线程池处于SHUTDOWN状态,此时线程池不能

够接受新的任务,它会等待所有任务执行完毕;

3)如果调用了shutdownNow()方法,则线程池处于STOP状态,此时线程池不能接

受新的任务,并且会去尝试终止正在执行的任务;

4)当线程池处于SHUTDOWN或STOP状态,并且所有工作线程已经销毁,任务缓存

队列已经清空或执行结束后,线程池被设置为TERMINATED状态。

2.任务的执行

1)首先,要清楚corePoolSize和maximumPoolSize的含义;

2)其次,要知道Worker是用来起到什么作用的;

3)要知道任务提交给线程池之后的处理策略,这里总结一下主要有4点:

●如果当前线程池中的线程数目小于corePoolSize,则每来一个任务,就会创

建一个线程去执行这个任务;

●如果当前线程池中的线程数目>=corePoolSize,则每来一个任务,会尝试将其

添加到任务缓存队列当中,若添加成功,则该任务会等待空闲线程将其取出去

执行;若添加失败(一般来说是任务缓存队列已满),则会尝试创建新的线程

去执行这个任务;

●如果当前线程池中的线程数目达到maximumPoolSize,则会采取任务拒绝策略

进行处理;

●如果线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过

keepAliveTime,线程将被终止,直至线程池中的线程数目不大于

corePoolSize;如果允许为核心池中的线程设置存活时间,那么核心池中的线

程空闲时间超过keepAliveTime,线程也会被终止。

3.线程池中的线程初始化

默认情况下,创建线程池之后,线程池中是没有线程的,需要提交任务之后才会创

建线程。在实际中如果需要线程池创建之后立即创建线程,可以通过以下两个方法

办到:

●prestartCoreThread():初始化一个核心线程;

●prestartAllCoreThreads():初始化所有核心线程

注意上面传进去的参数是null,如果传进去的参数为null,则最后执行线程会阻

塞在getTask方法中的workQueue.take();即等待任务队列中有任务。

4.任务缓存队列及排队策略

在前面我们多次提到了任务缓存队列,即workQueue,它用来存放等待执行的任务。

workQueue的类型为BlockingQueue,通常可以取下面三种类型:

●ArrayBlockingQueue:基于数组的先进先出队列,此队列创建时必须指定大小;

●LinkedBlockingQueue:基于链表的先进先出队列,如果创建时没有指定此队

列大小,则默认为Integer.MAX_VALUE;

●synchronousQueue:这个队列比较特殊,它不会保存提交的任务,而是将直接

新建一个线程来执行新来的任务。

5.任务拒绝策略

当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略:

●ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出

RejectedExecutionException异常。

●ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。

●ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重

新尝试执行任务(重复此过程)

●ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

6.线程池的关闭

ThreadPoolExecutor提供了两个方法,用于线程池的关闭,分别是shutdown()和shutdownNow(),其中:

●shutdown():不会立即终止线程池,而是要等所有任务缓存队列中的任务都执

行完后才终止,但再也不会接受新的任务

●shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任

务缓存队列,返回尚未执行的任务

7.线程池容量的动态调整

ThreadPoolExecutor提供了动态调整线程池容量大小的方法:setCorePoolSize()和setMaximumPoolSize(),

●setCorePoolSize:设置核心池大小

●setMaximumPoolSize:设置线程池最大能创建的线程数目大小

当上述参数从小变大时,ThreadPoolExecutor进行线程赋值,还可能立即创建新

的线程来执行任务。

主要是ThreadPoolExecutor的实现原理

Java并发编程:线程池的使用

1.3.10线程池的几种方式

newFixedThreadPool(int nThreads)

创建一个固定长度的线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程规模将不再变化,当线程发生未预期的错误而结束时,线程池会补充一个新的线程

newCachedThreadPool()

创建一个可缓存的线程池,如果线程池的规模超过了处理需求,将自动回收空闲线程,而当需求增加时,则可以自动添加新线程,线程池的规模不存在任何限制newSingleThreadExecutor()

这是一个单线程的Executor,它创建单个工作线程来执行任务,如果这个线程异常结束,会创建一个新的来替代它;它的特点是能确保依照任务在队列中的顺序来串行执行newScheduledThreadPool(int corePoolSize)

创建了一个固定长度的线程池,而且以延迟或定时的方式来执行任务,类似于Timer。

参考:

创建线程池的几种方式

1.3.11线程的生命周期

新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)5种状态(1)生命周期的五种状态

新建(new Thread)

当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。

例如:Thread t1=new Thread();

就绪(runnable)

线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源。例如:t1.start();

运行(running)

线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。

死亡(dead)

当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。

自然终止:正常运行run()方法后终止

异常终止:调用stop()方法让一个线程终止运行

堵塞(blocked)

由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。

正在睡眠:用sleep(long t) 方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。

正在等待:调用wait()方法。(调用motify()方法回到就绪状态)

被另一个线程所阻塞:调用suspend()方法。(调用resume()方法恢复)

参考:

线程的生命周期

1.4锁机制

1.4.1说说线程安全问题

线程安全是指要控制多个线程对某个资源的有序访问或修改,而在这些线程之间没有产生冲突。在Java里,线程安全一般体现在两个方面:

1)多个thread对同一个java实例的访问(read和modify)不会相互干扰,它主要体现

在关键字synchronized。如ArrayList和Vector,HashMap和Hashtable(后者每个方法前都有synchronized关键字)。如果你在interator一个List对象时,其它线程remove一个element,问题就出现了。

2)每个线程都有自己的字段,而不会在多个线程之间共享。它主要体现在

https://www.sodocs.net/doc/84596443.html,ng.ThreadLocal类,而没有Java关键字支持,如像static、transient那样。

1.4.2volatile 实现原理

Volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”。可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。它在某些情况下比synchronized的开销更小,本文将深入分析在硬件层面上

Inter处理器是如何实现Volatile的,通过深入分析能帮助我们正确的使用Volatile 变量。

聊聊并发(一)——深入分析Volatile的实现原理

1.4.3悲观锁乐观锁

乐观锁悲观锁

是一种思想。可以用在很多方面。

比如数据库方面。

悲观锁就是for update(锁定查询的行)

乐观锁就是 version字段(比较跟上一次的版本号,如果一样则更新,如果失败则要重复读-比较-写的操作。)

JDK方面:

悲观锁就是sync

乐观锁就是原子类(内部使用CAS实现)

本质来说,就是悲观锁认为总会有人抢我的。

乐观锁就认为,基本没人抢。

1.4.4CAS 乐观锁

乐观锁是一种思想,即认为读多写少,遇到并发写的可能性比较低,所以采取在写时先读出当前版本号,然后加锁操作(比较跟上一次的版本号,如果一样则更新),如果失败则要重复读-比较-写的操作。

CAS是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败。CAS顶多算是乐观锁写那一步操作的一种实现方式罢了,不用CAS自己加锁也是可以的。ABA 问题

ABA:如果另一个线程修改V值假设原来是A,先修改成B,再修改回成A,当前线程的CAS 操作无法分辨当前V值是否发生过变化。

参考:

Java CAS 和ABA问题

1.4.5乐观锁的业务场景及实现方式

乐观锁(Optimistic Lock):

每次获取数据的时候,都不会担心数据被修改,所以每次获取数据的时候都不会进行加锁,但是在更新数据的时候需要判断该数据是否被别人修改过。如果数据被其他线程修改,则不进行数据更新,如果数据没有被其他线程修改,则进行数据更新。由于数据没有进行加锁,期间该数据可以被其他线程进行读写操作。

乐观锁:比较适合读取操作比较频繁的场景,如果出现大量的写入操作,数据发生冲突的可能性就会增大,为了保证数据的一致性,应用层需要不断的重新获取数据,这样会增加大量的查询操作,降低了系统的吞吐量。

2核心篇

2.1数据存储

2.1.1MySQL 索引使用的注意事项

参考:

mysql索引使用技巧及注意事项

2.1.2说说反模式设计

参考:

每个程序员要注意的 9 种反模式

2.1.3说说分库与分表设计

分表与分库使用场景以及设计方式

2.1.4分库与分表带来的分布式困境与应对之策

服务端指南数据存储篇 | MySQL(09)分库与分表带来的分布式困境与应对之策

2.1.5说说 SQL 优化之道

sql优化的几种方法

2.1.6MySQL 遇到的死锁问题

参考:

Mysql并发时经典常见的死锁原因及解决方法

2.1.7存储引擎的 InnoDB 与 MyISAM

1)InnoDB支持事务,MyISAM不支持,这一点是非常之重要。事务是一种高级的处理方式,如在一些列增删改中只要哪个出错还可以回滚还原,而MyISAM就不可以了。

2)MyISAM适合查询以及插入为主的应用,InnoDB适合频繁修改以及涉及到安全性较高的应用

3)InnoDB支持外键,MyISAM不支持

4)从MySQL5.5.5以后,InnoDB是默认引擎

5)InnoDB不支持FULLTEXT类型的索引

6)InnoDB中不保存表的行数,如select count() from table时,InnoDB需要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count()语句包含where条件时MyISAM也需要扫描整个表

7)对于自增长的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中可以和其他字段一起建立联合索引

8)清空整个表时,InnoDB是一行一行的删除,效率非常慢。MyISAM则会重建表

9)InnoDB支持行锁(某些情况下还是锁整表,如 update table set a=1 where user like ‘%lee%’

参考:

2016最新java面试题_详细版

详解笔试面试题集 (1)下列各题ABCD四个选顼中,只有一个选项是正确的,请将正确选项填写在答题纸上 (1)下列关于栈的描述中错误的是( B) A. 栈是先进后出的线性表 B 栈只能顺序存储 C 栈具有记忆作用 D 对栈的插入弓删除操作中,不需要改变栈底指针 正确答案:B 分析:栈是链式存储的 (2)对于长度为n的线性表,在最坏情况下,下列各排序法所对应的比较次数中正确的是( ) A 冒泡排序为n/2 B 冒泡排序为n C 快速排序为n D 快速排序为n(n-l)/2 正确答案:D 分析: 想想快速排序,每次都会选取线性表的轴值,随后以此轴值划分为两个子线性表再分别进行快排,在最坏情况下,也就是说每次选出的线性表轴值完全不能将这个线性表划分为两个子线性表。那么此时快速排序退化为冒泡排序了。 那么第一趟排序时,轴值(线性表的中间位置)被选出,这个值绝对是这个线性表中最大的(不然也不能是最坏情况),其他值都比他小,那么线性表现在分为完全不对等的两段(一段是0,另一段是n - 1),一段是这个值,一段是其他值。同样第二趟排序在刚才剩下的值中选中间值(剩余值中最大的那个),又分为不对等两段,依次递推。也就是说每次都比较了N - 1个元素(轴值选出后都与它比较大小),那么肯定是比较了n - 1次(如第一次先挑了个轴值,然后剩下n - 1比较),n代表当前子线性表中元素个数由此最白痴的数列问题出现了,如下 1 + 2 + 3 + .......... + n - 2 + n - 1 = n(n - 1) / 2 还有一种投机取巧的方法,在最垃圾情况下既然快排变为冒泡,那由时间复杂度知其必为o(n ^ 2)的复杂度,答案中ABC都是线性时间复杂,显然错误 (3)下列对于线性链表的描述中正确的是( ) A 存储空间间不一定是连续,且各元素的存储顺序是任意的

java软件工程师面试题集

java软件工程师面试题集 EJB方面 1、EJB2.0有哪些内容?分别用在什么场合? EJB2.0和EJB1.1的区别? 答:规范内容包括Bean提供者,应用程序装配者,EJB容器,EJB配置工具,EJB服务提供者,系统管理员。这里面,EJB容器是EJB之所以能够运行的核心。EJB容器管理着EJB的创建,撤消,激活,去活,与数据库的连接等等重要的核心工作。JSP,Servlet,EJB,JNDI,JDBC,JMS..... 2、EJB与JAVA BEAN的区别? 答:Java Bean 是可复用的组件,对Java Bean并没有严格的规范,理论上讲,任何一个Java 类都可以是一个Bean。但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地进程内COM组件,它是不能被跨进程访问的。Enterprise Java Bean 相当于DCOM,即分布式组件。它是基于Java的远程方法调用(RMI)技术的,所以EJB可以被远程访问(跨进程、跨计算机)。但EJB 必须被布署在诸如Webspere、WebLogic这样的容器中,EJB客户从不直接访问真正的EJB组件,而是通过其容器访问。EJB容器是EJB组件的代理,EJB组件由容器所创建和管理。客户通过容器来访问真正的EJB组件。 3、EJB的基本架构 答:一个EJB包括三个部分: Remote Interface 接口的代码 package Beans; import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface Add extends EJBObject { //some method declare } Home Interface 接口的代码

java经典面试题汇总

Java基础方面: 1、作用域public,private,protected,以及不写时的区别 答:区别如下: 作用域当前类同一package 子孙类其他package public √√√√ protected √√√ × friendly √√ × × private √ × × × 不写时默认为friendly 2、Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口) 答:匿名的内部类是没有名字的内部类。不能extends(继承) 其它类,但一个内部类可以作为一个接口,由另一个内部类实现 3、Static Nested Class 和 Inner Class的不同 答:Nested Class (一般是C++的说法),Inner Class (一般是JA V A的说法)。Java内部类与C++嵌套类最大的不同就在于是否有指向外部的引用上。注:静态内部类(Inner Class)意味着1创建一个static内部类的对象,不需要一个外部类对象,2不能从一个static内部类的一个对象访问一个外部类对象 4、&和&&的区别 答:&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and) 5、Collection 和 Collections的区别 答:Collection是集合类的上级接口,继承与他的接口主要有Set 和List. Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作 6、什么时候用assert 答:assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,系统将给出警告或退出。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的 7、String s = new String("xyz");创建了几个String Object 答:两个,一个字符对象,一个字符对象引用对象 8、Math.round(11.5)等於多少? Math.round(-11.5)等於多少 答: Math.round(11.5)==12;Math.round(-11.5)==-11;round方法返回与参数最接近的长整数,参数加1/2后求其floor 9、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错 答:short s1 = 1; s1 = s1 + 1; (s1+1运算结果是int型,需要强制转换类型)short s1 = 1; s1 += 1;(可以正确编译) 10、Java有没有goto 答:java中的保留字,现在没有在java中使用 11、数组有没有length()这个方法? String有没有length()这个方法 答:数组没有length()这个方法,有length的属性。String有有length()这个方法 12、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型

java笔试题及答案

java笔试题及答案(必背) 来源:黄德洋的日志 1、作用域public,private,protected,以及不写时的区别 答:区别如下: 作用域当前类同一package 子孙类其他package public √√√√ protected √√√× friendly √√ × × private √××× 不写时默认为friendly 2、Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实 现)interface(接口) 答:匿名的内部类是没有名字的内部类。不能extends(继承) 其它类,但一个内部类可以作为一个接口,由另一个内部类实现 3、Static Nested Class 和Inner Class的不同 答:Nested Class (一般是C++的说法),Inner Class (一般是JAVA的说法)。Java内部类与C++嵌套类最大的不同就在于是否有指向外部的引用上。注:静态内部类(Inner Class)意味着1创建一个static 内部类的对象,不需要一个外部类对象,2不能从一个static内部类的一个对象访问一个外部类对象 4、&和&&的区别 答:&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and) 5、Collection 和Collections的区别 答:Collection是集合类的上级接口,继承与他的接口主要有Set 和List. Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作 6、什么时候用assert 答:assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,系统将给出警告或退出。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的

2019最新Java面试题,常见面试题及答案汇总

ava最新常见面试题+ 答案汇总 1、面试题模块汇总 面试题包括以下十九个模块:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql、Redis、JVM 。如下图所示: 可能对于初学者不需要后面的框架和JVM 模块的知识,读者朋友们可根据自己的情况,选择对应的模块进行阅读。 适宜阅读人群 需要面试的初/中/高级java 程序员 想要查漏补缺的人 想要不断完善和扩充自己java 技术栈的人 java 面试官 具体面试题 下面一起来看208 道面试题,具体的内容。 一、Java 基础 1.JDK 和JRE 有什么区别? 2.== 和equals 的区别是什么? 3.两个对象的hashCode()相同,则equals()也一定为true,对吗? 4.final 在java 中有什么作用? 5.java 中的Math.round(-1.5) 等于多少? 6.String 属于基础的数据类型吗? 7.java 中操作字符串都有哪些类?它们之间有什么区别? 8.String str="i"与String str=new String(“i”)一样吗? 9.如何将字符串反转? 10.String 类的常用方法都有那些? 11.抽象类必须要有抽象方法吗? 12.普通类和抽象类有哪些区别? 13.抽象类能使用final 修饰吗?

14.接口和抽象类有什么区别? 15.java 中IO 流分为几种? 16.BIO、NIO、AIO 有什么区别? 17.Files的常用方法都有哪些? 二、容器 18.java 容器都有哪些? 19.Collection 和Collections 有什么区别? 20.List、Set、Map 之间的区别是什么? 21.HashMap 和Hashtable 有什么区别? 22.如何决定使用HashMap 还是TreeMap? 23.说一下HashMap 的实现原理? 24.说一下HashSet 的实现原理? 25.ArrayList 和LinkedList 的区别是什么? 26.如何实现数组和List 之间的转换? 27.ArrayList 和Vector 的区别是什么? 28.Array 和ArrayList 有何区别? 29.在Queue 中poll()和remove()有什么区别? 30.哪些集合类是线程安全的? 31.迭代器Iterator 是什么? 32.Iterator 怎么使用?有什么特点? 33.Iterator 和ListIterator 有什么区别? 34.怎么确保一个集合不能被修改?

JAVA笔试题--Java选择题100道

1.下列不可作为java语言修饰符的是(D) A) a1 B) $1 C) _1 D) 11 2.有一段java 应用程序,它的主类名是a1,那么保存它的源文件名可以是(A) A) a1.java B) a1.class C) a1 D) 都对 3.整型数据类型中,需要内存空间最少的是(D) A) short B) long C) int D) byte 4. Java 类可以作为(C) A) 类型定义机制 B) 数据封装机制 C) 类型定义机制和数据封装机制 D) 上述都不对 5.在创建对象时必须(C) A) 先声明对象,然后才能使用对象 B) 先声明对象,为对象分配内存空间,然后才能使用对象 C) 先声明对象,为对象分配内存空间,对对象初始化,然后才能使用对象 D) 上述说法都对 6.在调用方法时,若要使方法改变实参的值,可以(B) A) 用基本数据类型作为参数 B) 用对象作为参数 C) A和B都对 D) A和B都不对 7. Java中(C) A) 一个子类可以有多个父类,一个父类也可以有多个子类 B) 一个子类可以有多个父类,但一个父类只可以有一个子类 C) 一个子类可以有一个父类,但一个父类可以有多个子类 D) 上述说法都不对 8.Java语言具有许多优点和特点,哪个反映了Java程序并行机制的特点?(B) A) 安全性B) 多线性C) 跨平台D) 可移植 9. Character流与Byte流的区别是(C) A) 每次读入的字节数不同B) 前者带有缓冲,后者没有 C) 前者是字符读写,后者是字节读写D) 二者没有区别,可以互换使用 10.以下声明合法的是( D ) A、default String s; B、public final static native int w( ) C、abstract double d; D、abstract final double hyperbolicCosine( ) 11.关于以下application的说明,正确的是( C ) 1.class StaticStuff 2.{ 3.static int x=10; 4.static { x+=5;} 5.public static void main(String args[ ]) 6.{ 7.System.out.println(“x=”+ x); 8.} 9.static { x/=3;}

Java经典面试题大全_带答案

Java经典面试题带答案一、单项选择题 1.Java是从()语言改进重新设计。 A.Ada B.C++ C.Pasacal D.BASIC 答案:B 2.下列语句哪一个正确() A.Java程序经编译后会产生machine code B.Java程序经编译后会产生byte code(字节码) C.Java程序经编译后会产生DLL D.以上都不正确 答案:B 3.下列说法正确的有() A.class中的constructor不可省略 B.constructor必须与class同名,但方法不能与class同名C.constructor在一个对象被new时执行(构造器) D.一个class只能定义一个constructor 答案:C 4.提供Java存取数据库能力的包是() A.Java.sql /sql/数据库还有Oracle 也是一种数据库 B.java.awt C.https://www.sodocs.net/doc/84596443.html,ng D.java.swing 答案:A 5.下列运算符合法的是() A.&& B.<> C.if D.:= 答案:A 6.执行如下程序代码 a=0;c=0; do{ --c; a=a-1; }while(a>0); 后,C的值是() A.0 B.1 C.-1 D.死循环

答案:C 7.下列哪一种叙述是正确的() A.abstract修饰符可修饰字段、方法和类 B.抽象方法的body部分必须用一对大括号{}包住 C.声明抽象方法,大括号可有可无 D.声明抽象方法不可写出大括号 答案:D 8.下列语句正确的是() A.形式参数可被视为localvariable B.形式参数可被字段修饰符修饰 C.形式参数为方法被调用时,真正被传递的参数 D.形式参数不可以是对象 答案:A 9.下列哪种说法是正确的() A.实例方法可直接调用超类的实例方法 B.实例方法可直接调用超类的类方法 C.实例方法可直接调用其他类的实例方法 D.实例方法可直接调用本类的类方法 答案:D 二、多项选择题 1.Java程序的种类有() A.类(Class) B.Applet C.Application D.Servlet 2.下列说法正确的有() A.环境变量可在编译sourcecode时指定 B.在编译程序时,所能指定的环境变量不包括class path C.javac一次可同时编译数个Java源文件 D.javac.exe能指定编译结果要置于哪个目录(directory)答案:BCD 3.下列标识符不合法的有() A.new B.$Usdollars C.1234 D.car.taxi 答案:ACD 4.下列说法错误的有() A.数组是一种对象 B.数组属于一种原生类 C.intnumber=[]={31,23,33,43,35,63} D.数组的大小可以任意改变 答案:BCD 5.不能用来修饰interface的有()

最新最新java笔试题及答案

一.选择题(1-10题每题2分,11-15题每题4分) 1.下面关于Java语言说法错误的是:() A.java语言是完全面向对象的 B。java语言支持多继承 C.java语言支持多线程 D。java语言最早是为消费电子产品领域设计的 2.下面标识符中正确的是:() A.*123 B。12java C.continue D。java$next 3.下列关于注释语句的描述中,正确的一项是() A。以//开始的是多行注释语句 B。以/*开始,*/结束的是单行注释语句 C。以/**开始,*/结束的是可以用于生成帮助文档的注释语句 D。以/**开始,*/结束的是单行注释语句 4.为了区分重载多态中同名的不同方法,要求()。 A)形式参数个数或者类型不同 B)返回值类型不同 C)调用时用类名或对象名做前缀 D)形式参数名称不同 5.下面定义数组的格式中正确的是:() A.int a[10] B。int a=new int[10] C.int []a=new int[5] D.int a[] 6.下面说法中不正确的是:() A.类是对象的抽象,对象是类的实例 B。类是组成java程序的最小的单位 C.java语言支持多继承 D。java一个程序中只能有一个public类 7.定义类时,不可能用到的保留字是()。 A) private B) class C) extends D) implements 8.为 AB 类的定义一个公共的构造函数,该方法头的形式为()

A.void AB( ) B。public void method( ) C.public method ( ) D。public AB( ) 9.下面说法中不正确的是:() A.java中一个类只允许实现一个接口 B。抽象类中允许有非抽象方法的存在 C.类变量(实例变量)可以直接用类名调用 D。通过super可以调用基类的构造函数 10.容器JFrame 默认使用的布局编辑策略是() A.BorderLayout B。FlowLayout C。GridLayout D。CardLayout 11.以下哪个表达式是不合法的() A.String x=”Hello”; int y=9; x+=y; B.String x=”Hello”; int y=9; if(x= =y) { } C.String x=”Hello”; int y=9; x=x+y; D.String x=null; int y=(x!=null)&&(x.length()>0) 12.class person { public int addvalue(int a,int b) { int s; s=a+b; return s; } }

BAT等IT公司最新Java笔试题及答案

给出以下代码 public class Switch1{ final static short x=2; public static int y=0; public static void main(String[] args) { for(int z=0;z<4;z++){ switch(z){ case x:System.out.print(“0″); default:System.out.print(“def”); case x-1:System.out.print(“1″);break; case x-2:System.out.print(“2″); } } } } class ParentClass{ public int doStuff(int x){ return x*2; } } public class ChildClass extends ParentClass{ public static void main(String[] args){

ChildClass cc=new ChildClass(); long x=cc.doStuff(7); System.out.println(“x=”+x); } public long doStuff(int x){ return x*3; } } Public static void main(String[] args){ X.x=new X(); X.x2=m1(x); X.x4=new X(); X2=x4; //comment …. } Static X m1(X mx){ Mx=new X(); Return mx; } } 以上代码执行到comment处时有多少个可被垃圾收集的对象

常见的java面试笔试题大汇总

1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。 3.封装: 封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。 4. 多态性: 多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。 5、String是最基本的数据类型吗? 基本数据类型包括byte、int、char、long、float、double、boolean和short。 https://www.sodocs.net/doc/84596443.html,ng.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类 6、int 和Integer 有什么区别 Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。 原始类型封装类 boolean Boolean char Character byte Byte short Short int Integer long Long float Float double Double 引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的

Java经典面试笔试题及答案

1.什么是对象序列化,为什么要使用? 所谓对象序列化就是把一个对象以二进制流的方式保存到硬盘上。好处:方便远程调用。 2.值传递与引用传递的区别? 所谓值传递就是把一个对象的值传给一个新的变量,但是系统会给这个新的变量开辟一个新的内存空间。不会改变原有的值所谓引用传递就是把一个对象在堆中保存的数据传递给一个变量,此时新的变量与原有的变量对应同一个内存存储空间,当新的变量修改对象的属性时,内存中的数据也会修改。 3.接口与抽象类的区别? 1:接口里面不可以实现方法体,抽象类可以实现方法体。 2:接口可以多继承接口,抽象类不可以。 3:接口需要被子类实现,抽象类是要被子类继承(单一继承)。 4:接口中只能有公有的方法和属性而且必须赋初始值,抽象类中可以有私有方法和属性. 5: 接口中不能存在静态方法,但属性可以和final,抽象类中方法中可以有静态方法,属性也可以。 4.谈谈继承,为什么要使用继承? 所谓继承就是找出几个类中共同的部分,提取出来作为父类。而子类只需要继承父类,就可以共享父类的方法。 使用继承能够减少重复的代码。 5.方法重载的好处?

所谓重载就是在一个类中可以定义多个相同的方法,但是方法的参数类型和参数的个数以及顺序要不同。 重载的好处就是能够让我们很快的掌握该方法的功能,我们只要要记住该方法就能很快的理解该方法的参数以及参数的作用 6.项目中印象最深的部分? 我觉得在该项目中我体现到了反射技术的强大之处,原来我一直不清楚反射是一种什么样的技术,只知道一些概念上的知识,经过这个项目之后,终于知道该怎样灵活运用反射,以及在什么时候运用。 谈谈你对面向对象的理解与认识? 我觉得使用面向对象这种思维的方式比较符合我们人类的思想,不需要去学习一些什么新的思考方式,就按照现实生活做的一些故事就能让人理解该内容的知识以及他们的作用。 我的看法就是: 1:当加入新的功能的时候不会修改原有的代码。(面向接口编程) 2: 当我们写的一个类可以重复的运用在其他项目中。(代码的复用性) 3:当写一个新类的时候要考虑到他的可扩展性。(灵活性) 7.谈谈集合框架? 集合框架分为三部分,第一部分是collection接口,第二部分是Map接口、第三部分是collections帮助类 首先说一下collection接口,collection接口下面的接口分为set 接口、list接口,在往下面就是他们一些实现类。

【2020最新Java面试题资料】30个Java经典的集合面试题

1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的版本包含几种集合类:Vector Stack HashTable和Array。 随着集合的广泛使用,Java1.2提出了囊括所有集合接口、实现和算法的集合框架。在保证线程安全的情况下使用泛型和并发集合类,已经经历了很久。它还包括在并发包中,阻塞接口以及它们的实现。 集合框架的部分优点如下: (1)使用核心集合类降低开发成本,而非实现我们自己的集合类。 (2)随着使用经过严格测试的集合框架类,代码质量会得到提高。 (3)通过使用JDK附带的集合类,可以降低代码维护成本。 (4)复用性和可操作性。 2.集合框架中的泛型有什么优点? 1.Java1.5引入了泛型,所有的集合接口和实现都大量地使用它。 2.泛型允许我们为集合提供一个可以容纳的对象类型,因此,如果你添加其它类型的任何元素,它会在编译时报错。 3.这避免了在运行时出现ClassCastException,因为你将会在编译时得到报错信息。 4.泛型也使得代码整洁,我们不需要使用显式转换和instanceOf操作符。 5.它也给运行时带来好处,因为不会产生类型检查的字节码指令。 3.Java集合框架的基础接口有哪些? Collection为集合层级的根接口。一个集合代表一组对象,这些对象即为它的元素。平台不提供这个接口任何直接的实现。 Set是一个不能包含重复元素的集合。这个接口对数学集合抽象进行建模,被用来代表集合,就如一副牌。 List是一个有序集合,可以包含重复元素。你可以通过它的索引来访问任何元素。List更像长度动态变换的数组。 Map是一个将key映射到value的对象.一个Map不能包含重复的key:每个key最多只能映射一个value。

JAVA笔试试题

1. 下面哪些是Thread类的方法() A start() B run() C exit() D getPriority() 答案:ABD 解析:看Java API docs吧:https://www.sodocs.net/doc/84596443.html,/javase/7/docs/api/,exit()是System类的方法,如System.exit(0)。 2. 下面关于https://www.sodocs.net/doc/84596443.html,ng.Exception类的说法正确的是() A 继承自Throwable B Serialable CD 不记得,反正不正确 答案:A 解析:Java异常的基类为https://www.sodocs.net/doc/84596443.html,ng.Throwable,https://www.sodocs.net/doc/84596443.html,ng.Error和https://www.sodocs.net/doc/84596443.html,ng.Exception继承Throwable,RuntimeException和其它的Exception等继承Exception,具体的RuntimeException 继承RuntimeException。 扩展:错误和异常的区别(Error vs Exception) 1) https://www.sodocs.net/doc/84596443.html,ng.Error: Throwable的子类,用于标记严重错误。合理的应用程序不应该去try/catch 这种错误。绝大多数的错误都是非正常的,就根本不该出现的。 https://www.sodocs.net/doc/84596443.html,ng.Exception: Throwable的子类,用于指示一种合理的程序想去catch的条件。即它仅仅是一种程序运行条件,而非严重错误,并且鼓励用户程序去catch它。 2) Error和RuntimeException 及其子类都是未检查的异常(unchecked exceptions),而所有其他的Exception类都是检查了的异常(checked exceptions). checked exceptions:通常是从一个可以恢复的程序中抛出来的,并且最好能够从这种异常中使用程序恢复。比如FileNotFoundException, ParseException等。检查了的异常发生在编译阶段,必须要使用try…catch(或者throws)否则编译不通过。 unchecked exceptions:通常是如果一切正常的话本不该发生的异常,但是的确发生了。发生在运行期,具有不确定性,主要是由于程序的逻辑问题所引起的。比如ArrayIndexOutOfBoundException, ClassCastException等。从语言本身的角度讲,程序不该去catch这类异常,虽然能够从诸如RuntimeException这样的异常中catch并恢复,但是并不鼓励终端程序员这么做,因为完全没要必要。因为这类错误本身就是bug,应该被修复,出现此类错误时程序就应该立即停止执行。因此,面对Errors和unchecked exceptions应该让程序自动终止执行,程序员不该做诸如try/catch这样的事情,而是应该查明原因,修改代码逻辑。 RuntimeException:RuntimeException体系包括错误的类型转换、数组越界访问和试图访问空指针等等。 处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。例如,可以通过检查数组下标和数组边界来避免数组越界访问异常。其他(IOException等等)checked异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误。 3. 下面程序的运行结果是() String str1 = "hello"; String str2 = "he" + new String("llo"); System.err.println(str1 == str2); 答案:false 解析:因为str2中的llo是新申请的内存块,而==判断的是对象的地址而非值,所以不一样。如果是String str2 = str1,那么就是true了。 4. 下列说法正确的有() A.class中的constructor不可省略 B.constructor必须与class同名,但方法不能与class同名 C.constructor在一个对象被new时执行

2018最新Java面试题整理

1基础篇 1.1基本功 1.1.1面向对象特征 封装,继承,多态和抽象 1、封装 封装给对象提供了隐藏内部特性和行为的能力。对象提供一些能被其他对象访问的方法 来改变它内部的数据。在 Java 当中,有 3 种修饰符: public, private 和 protected。每一种修饰符给其他的位于同一个包或者不同包下面对象赋予了不同的访 问权限。下面列出了使用封装的一些好处: 1)通过隐藏对象的属性来保护对象内部的状态。 2)提高了代码的可用性和可维护性,因为对象的行为可以被单独的改变或者是扩展。 3)禁止对象之间的不良交互提高模块化 2、继承 继承给对象提供了从基类获取字段和方法的能力。继承提供了代码的重用行,也可以在 不修改类的情况下给现存的类添加新特性。 3、多态 多态是编程语言给不同的底层数据类型做相同的接口展示的一种能力。一个多态类型上 的操作可以应用到其他类型的值上面。 4、抽象 抽象是把想法从具体的实例中分离出来的步骤,因此,要根据他们的功能而不是实现细 节来创建类。 Java 支持创建只暴漏接口而不包含方法实现的抽象的类。这种抽象技术 的主要目的是把类的行为和实现细节分离开。 1.1.2final, finally, finalize 的区别 1、final修饰符(关键字) 如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。 因此一个类不能既被声明为 abstract的,又被声明为final的。 将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量 必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方 法也同样只能使用,不能重载。 2、finally 在异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配 的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。 3、finalize 方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去 之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个 对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收 集器删除对象之前对这个对象调用的。

【黑马程序员】2019最新Java面试题

【黑马程序员】2019最新Java面试题 1,short s1=1;s1=s1+1;有什么错??? 答:s1为short型,1为int型,s1+1=2先为int型,S1为short 型,所以需要通过强制转化—s1=(short)(s1+1); 举例:short s1=1; s1+=1;(正确,因为可以自动转化) 2,请简述equals与==的区别 在String中,equals对比的是内容,==是比较地址 3,sleep与wait的区别 (1)sleep方法可以设置线程阻塞的时间,而wait方法必须要notily方法来唤醒(2)sleep方法属于Thread类,而wait属于Object类 (3)sleep方法不会释放锁的资源,而wait方法会释放锁的资源面试官:每个引用对象都有wait方法吗? 答:都有,因为每个类都会继承Object基类 4,String,Stringbuffer,Stringbuidder的区别? (1)String是JAVA的基础类,他可以定义少量的字符串 (2)StringBuffer是对String的扩充,他可以拼接大量字符串,但是他的效率比较低,因为他是线程安全的 (3)StringBuidder是对StringBuffer的拓展,他提高了效率,但是他是线程不安全的 5,ArrayList和Vector的区别? (1)ArrayList底层是用数组实现的,所以查找快,增删慢,ArrayList是线程不安全的(2)Vector由于是线程安全的,所以他的效率要比ArrayList底的多 6,Super关键字的使用? (1)Super关键字实现的前提必须要有继承 (2)Super关键字可以调用父类的方法,属性,通过Super.方法名,Super.属性(3)Super 关键字必须位于类的第一行

最新java面试题(技术面试)

1、servlet执行流程 客户端发出http请求,web服务器将请求转发到servlet容器,servlet容器解析 url并根据web.xml找到相对应的servlet,并将request、response对象传递给找到的servlet,servlet根据request就可以知道是谁发出的请求,请求信息及其他信息,当servlet处理完业务逻辑后会将信息放入到response并响应到客户端。 2、springMVC的执行流程 springMVC是由dispatchservlet为核心的分层控制框架。首先客户端发出一个 请求web服务器解析请求url并去匹配dispatchservlet的映射url,如果匹配上就将这个请求放入到dispatchservlet,dispatchservlet根据mapping映射配置去寻找相对应的handel,然后把处理权交给找到的handel,handel封装了处理业务逻辑的代码,当handel处理完后会返回一个逻辑视图modelandview给dispatchservlet,此时的modelandview是一个逻辑视图不是一个正式视图,所以dispatchservlet会通过viewresource视图资源去解析modelandview,然后将解析后的参数放到view 中返回到客户端并展现。 3、给定一个txt文件,如何得到某字符串出现的次数 = new File("E://test.txt"); InputStream is = new (file); byte b[] = new byte[1024]; int a = is.read(b); String str[] = new String(b,0,a).split(""); int count = 0; for(int i = 0;i

最新java基础笔试题(答案已整理)

Java基础试题 一:选择题(1*30=30)(题目写在答题纸上面) 1:Java 提供哪几种运算符多选( abcd)。 A)算术运算符B)位运算符 C)关系运算符D)逻辑运算符E)条件运算符 2:https://www.sodocs.net/doc/84596443.html,ng包的()方法比较二个对象是否相等返回true.。(b) A:toString() B:equals() C:compare D:以上都不正确 3:下列对Java 的变量与函数说法正确的是多选(ace)。 A)变量是用来保存数据的B)变量是用来实现操作过程的C)函数是用来实现操作过程的D)函数是用来保存数据的E)函数的参数是数据的入口 4:已知:int[] a = new int[100];在下列给出的数组元素中,非法的是。(d) A:a[0] B:a[1] C:a[99] D:a[100] 5:在java中,一个类可同时定义许多同名的方法,在这些方法的形式参数个数,类型或顺序各不相同,传值也可以各不相同。这种面向对象程序的特性称为。(c) A:隐藏B:覆盖C:重载D:Java不支持此特性 6:()是一组常量和抽象方法的集合。(d) A:实例B:类C:包D:接口 7:下面关于数组说法正确的是多选(abcde)。 A)一维数组实质上是相同类型变量的列表 B)创建一个数组首先定义数组变量所需的类型 C)char c[]=new char[26];可声明一个含有26 个元素的char型数组 D)当为一个多维数组的时候分配内存时,仅需要为第一指定内存,然后再分配其他维的存E)int twain[][] = new int[4][5];可声明一个二维数组 8:Java源文件和编译后的文件扩展名分别为。(b) A:.class和.java B:.java各.class C:.class和.class D:.java和.java 9:设x=5;则y=x--和y=--x的结果,使y分别为。(c) A:5,5 B:5,6 C:5,4 D:4,4 10:若x是float类变量,x=10/4;则x 的值是。(b) A:2 B:2.0 C:2,5 D:编译错误 11:.下面方法中,用于调度线程使其运行的是?多选(bc) A. init() B. start() C. run() D. resume() E. sleep() 12.下面哪种情况能实现自动转换多选(ace)。 A)byte 型转换成 int 型 B)int 型转换成 byte 型 C)float 型转换成 double型 D)double 型转换成 int 型 E)char型转换成 int 型13:下列那些是正确的JAVA字符串?多选(abd)。 A. "\"\"" B. "Oxzabc" C. "\"\" D. "\t\t\r\n" E. "boolean"5 14:在使用super 和this关键字时,以下描述正确的是。(a) A::在子类构造方法中使用super()显示调用父类的构造方法,super()必须写在子类构造方法的第一行,否则编译不通过 B:super()和this()不一定要放在构造方法内第一行

JAVA面试题( 华为)(答案)

软件开发应试人员考试试题(Java) 姓名:___________ 电话:___________ 以下信息有工作经验人员如实填写,应届毕业不填(时间从毕业参加工作算起) 从事Java开发时间____月熟悉JavaScrip时间____月 熟悉EXT开发时间____月熟悉PDM开发时间____月 熟悉的数据库及时间(如SQLServer 3个月,可多填)___________________ 一、JAVA基础 1、简述你所知道的JA V A修饰符及各自的使用机制?(public、abstract、final、synchronized、super…) public :允许所有客户访问 protected:只能在本包内被该类的子类所使用 private:只允许在本类内使用 abstract:没有提供实现,需要子类提供 static:与整个类相关,与单个对象无关 final:你只能定义一个实体一次,以后不能改变它或继承它。一个final修饰的类不能被子类化,一个final 修饰的方法不能被重写,一个final修饰的变量不能改变其初始值 synchronized:方法获得对对象监控的访问权;如果该方法是static类型的,获得是对类本身的访问权。super:构造器和方法,都用关键字super指向超类,但是用的方法不一样。方法用这个关键字去执行被重载的超类中的方法。 2. String、StringBuffer与StringBuilder之间区别?别简述各自的执行效率? 区别:String 类型和StringBuffer 类型的主要性能区别其实在于String 是不可变的对象, 因此在每次对String 类型进行改变的时候其实都等同于生成了一个新的String 对象,然后将指针指向新的String 对象,所以经常改变内容的字符串最好不要用String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后,JVM 的GC 就会开始工作,那速度是一定会相当慢的, 执行速度:三者在执行速度方面的比较:StringBuilder > StringBuffer > String 使用场景:1.如果要操作少量的数据用= String 2.单线程操作字符串缓冲区下操作大量数据= StringBuilder 3.多线程操作字符串缓冲区下操作大量数据= StringBuffer 2、静态变量和实例变量的区别?能在静态方法中调用非静态变量吗? 静态变量属于类,该类不生产对象,通过类名就可以调用静态变量。实例变量属于该类的对象,必须产生该类对象,才能调用实例变量 静态方法及变量属于整个类,数据将会被存储在公共区域,非静态方法及变量属于对象 静态方法中无法调用实例变量,而实例方法却可以调用静态变量

相关主题