文章目录
- 1
- 2
- 3
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29、Java Bean 属性命名规范问题分析
- 30、什么是 Java 的内存模型?
- 31、在 Java 中,什么时候用重载,什么时候用重写?
- 32、举例说明什么情况下会更倾向于使用抽象类而不是接口?
- 33、实例化对象有哪几种方式What are several ways to instantiate an object
- 34、byte类型127+1等于多少
- 35、Java 容器都有哪些?What are the Java containers?
- 36、Collection 和 Collections 有什么区别?
- 37、list与Set区别
- 38、HashMap 和 Hashtable 有什么区别?
- 39、说一下 HashMap 的实现原理?
- 40、set有哪些实现类?What are the implementation classes for set?
- 41、说一下 HashSet 的实现原理?
- 42、ArrayList 和 LinkedList 的区别是什么?
- 44、在 Queue 中 poll()和 remove()有什么区别?
- 45、哪些集合类是线程安全的
- 46、迭代器 Iterator 是什么?What is an Iterator?
- 47、Iterator 怎么使用?有什么特点?
- 48、Iterator 和 ListIterator 有什么区别?
- 49、怎么确保一个集合不能被修改?
- 50、队列和栈是什么?有什么区别?
1
== 和 equals 的区别是什么?
对于基本类型,==比较的是值;
对于引用类型,==比较的是地址;
equals不能用于基本类型的比较;
如果没有重写equals,equals就相当于==;
如果重写了equals方法,equals比较的是对象的内容;
What is the difference between = = and equals?
For primitive types, = = compares values;
For reference types, = = compares addresses;
Equals cannot be used for comparison of primitive types;
If equals is not overridden, equals is equivalent to = =;
If the equals method is overridden, equals compares the contents of the object;
2
final 在 java 中有什么作用?
(1)用来修饰一个引用
如果引用为基本数据类型,则该引用为常量,该值无法修改;
如果引用为引用数据类型,比如对象、数组,则该对象、数组本身可以修改,但指向该对象或数组的地址的引用不能修改。
如果引用时类的成员变量,则必须当场赋值,否则编译会报错。
(2)用来修饰一个方法
当使用final修饰方法时,这个方法将成为最终方法,无法被子类重写。但是,该方法仍然可以被继承。
(3)用来修饰类
当用final修改类时,该类成为最终类,无法被继承。
比如常用的String类就是最终类。
What does final do in Java?
(1) Used to modify a reference.
If the reference is a basic data type, the reference is a constant and the value cannot be modified;
If the reference is a reference data type, such as an object or an array, the object or array itself can be modified, but the reference to the address of the object or array cannot be modified.
If a member variable of a class is referenced, it must be assigned on the spot, otherwise the compiler will report an error.
(2) Used to modify a method.
When a final-decorated method is used, the method becomes final and cannot be overridden by subclasses. However, the method can still be inherited.
(3) Used to modify a class.
When a class is modified with final, the class becomes final and cannot be inherited.
For example, the commonly used String class is the final class.
3
String 属于基础的数据类型吗?
不属于。
八种基本数据类型:byte、short、char、int、long、double、float、boolean。
String 属于基础的数据类型吗?
不属于。
八种基本数据类型:byte、short、char、int、long、double、float、boolean。
如何将字符串反转?添加到StringBuilder中,然后调用reverse()。
How do I reverse a string? To the String Builder, and then call reverse ().
String 类的常用方法都有那些?
equals、length、contains、replace、split、hashcode、indexof、substring、trim、toUpperCase、toLowerCase、isEmpty等等。
What are the common methods of the String class?
Equals, length, contains, replace, split, hashcode, indexof, substring, trim, toUpperCase, toLowerCase, isEmpty, and so on.
普通类和抽象类有哪些区别?
抽象类不能被实例化;
抽象类可以有抽象方法,只需申明,无须实现;
有抽象方法的类一定是抽象类;
抽象类的子类必须实现抽象类中的所有抽象方法,否则子类仍然是抽象类;
抽象方法不能声明为静态、不能被static、final修饰。
What are the differences between a normal class and an abstract class?
An abstract class cannot be instantiated;
An abstract class can have abstract methods that only need to be declared and not implemented;
A class with an abstract method must be an abstract class;
A subclass of an abstract class must implement all abstract methods in the abstract class, otherwise the subclass is still an abstract class;
An abstract method cannot be declared as static and cannot be decorated with static or final.
接口和抽象类有什么区别?
(1)接口
接口使用interface修饰;
接口不能实例化;
类可以实现多个接口;
①java8之前,接口中的方法都是抽象方法,省略了public abstract。②java8之后;接口中可以定义静态方法,静态方法必须有方法体,普通方法没有方法体,需要被实现;
(2)抽象类
抽象类使用abstract修饰;
抽象类不能被实例化;
抽象类只能单继承;
抽象类中可以包含抽象方法和非抽象方法,非抽象方法需要有方法体;
如果一个类继承了抽象类,①如果实现了所有的抽象方法,子类可以不是抽象类;②如果没有实现所有的抽象方法,子类仍然是抽象类。
An abstract class is decorated with abstract;
An abstract class cannot be instantiated;
An abstract class can only inherit singly;
An abstract class can contain an abstract method and a non-abstract method, and a non-abstract method requires a method body;
If a class inherits the abstract class, ① if all the abstract methods are implemented, the subclass may not be an abstract class; ② if all the abstract methods are not implemented, the subclass is still an abstract class.
java 中 IO 流分为几种?
(1)按流划分,可以分为输入流和输出流;
(2)按单位划分,可以分为字节流和字符流;
字节流:inputStream、outputStream;
字符流:reader、writer;
How many types of IO streams are there in Java?
(1) According to the flow, it can be divided into input flow and output flow;
(2) According to the unit, it can be divided into byte stream and character stream;
Byte stream: inputStream, output Stream;
Character stream: reader, writer;
BIO、NIO、AIO 有什么区别?
(1)同步阻塞BIO
一个连接一个线程。
JDK1.4之前,建立网络连接的时候采用BIO模式,先在启动服务端socket,然后启动客户端socket,对服务端通信,客户端发送请求后,先判断服务端是否有线程响应,如果没有则会一直等待或者遭到拒绝请求,如果有的话会等待请求结束后才继续执行。
(2)同步非阻塞NIO
NIO主要是想解决BIO的大并发问题,BIO是每一个请求分配一个线程,当请求过多时,每个线程占用一定的内存空间,服务器瘫痪了。
JDK1.4开始支持NIO,适用于连接数目多且连接比较短的架构,比如聊天服务器,并发局限于应用中。
一个请求一个线程。
(3)异步非阻塞AIO
一个有效请求一个线程。
JDK1.7开始支持AIO,适用于连接数目多且连接比较长的结构,比如相册服务器,充分调用OS参与并发操作。
What is the difference between BIO, NIO and AIO?
(1) Synchronous Blocking BIO
One thread per connection.
Before JDK1.4, a BIO mode is adopted when a network connection is established, a server socket is started first, and then a client socket is started to communicate with the server; after the client sends a request, whether the server has a thread response is judged first, if not, the server waits all the time or the request is rejected, If there is, it will wait for the request to finish before continuing.
(2) Synchronous non-blocking NIO
NIO is mainly to solve the large concurrency problem of BIO. BIO allocates a thread for each request. When there are too many requests, each thread occupies a certain amount of memory space, and the server is paralyzed.
JDK1.4 begins to support NIO, which is suitable for architectures with a large number of connections and relatively short connections, such as chat servers, where concurrency is limited to applications.
One thread per request.
(3) Asynchronous non-blocking AIO
A valid request is a thread.
JDK1.7 begins to support AIO, which is suitable for structures with a large number of connections and long connections, such as album servers, and fully calls the OS to participate in concurrent operations.
什么是反射?
所谓反射,是java在运行时进行自我观察的能力,通过class、constructor、field、method四个方法获取一个类的各个组成部分。
在Java运行时环境中,对任意一个类,可以知道类有哪些属性和方法。这种动态获取类的信息以及动态调用对象的方法的功能来自于反射机制。
What is a reflex?
The so-called reflection is the ability of Java to observe itself at runtime, obtaining the components of a class through the four methods of class, constructor, field and method.
In the Java runtime environment, for any class, you can know what properties and methods the class has. This ability to dynamically obtain information about a class and dynamically invoke methods on an object comes from the reflection mechanism.
什么是 java 序列化?什么情况下需要序列化?
序列化就是一种用来处理对象流的机制。将对象的内容流化,将流化后的对象传输于网络之间。
序列化是通过实现serializable接口,该接口没有需要实现的方法,implement Serializable只是为了标注该对象是可被序列化的,使用一个输出流(FileOutputStream)来构造一个ObjectOutputStream对象,接着使用ObjectOutputStream对象的writeObejct(Object object)方法就可以将参数的obj对象到磁盘,需要恢复的时候使用输入流。
序列化是将对象转换为容易传输的格式的过程。
例如,可以序列化一个对象,然后通过HTTP通过Internet在客户端和服务器之间传输该对象。在另一端,反序列化将从流中心构造成对象。
一般程序在运行时,产生对象,这些对象随着程序的停止而消失,但我们想将某些对象保存下来,这时,我们就可以通过序列化将对象保存在磁盘,需要使用的时候通过反序列化获取到。
对象序列化的最主要目的就是传递和保存对象,保存对象的完整性和可传递性。
譬如通过网络传输或者把一个对象保存成本地一个文件的时候,需要使用序列化。
What is Java serialization? When is serialization required?
Serialization is a mechanism for processing a stream of objects. The content of the object is streamed, and the streamed object is transmitted between networks.
Serialization is done by implementing the serializable interface, which has no methods to implement, implement Serial izable just to mark the object as being serializable. Use an output stream (FileOutputStream) to construct an ObjectOutputStream object, and then use the writeObejct (Object Object) method of the ObjectOutputStream object to transfer the obj object of the parameter to disk. Use the input stream when recovery is required.
Serialization is the process of converting an object into an easily transportable format.
For example, you can serialize an object and then transfer it between the client and the server over HTTP over the Internet. At the other end, deserialization constructs the object from the center of the stream.
Generally, when a program is running, it generates objects, which disappear as the program stops, but we want to save some objects. At this time, we can save the objects on disk through serialization, and obtain them through deserialization when we need to use them.
The primary purpose of object serialization is to pass and preserve objects, preserving their integrity and transitivity.
For example, when transferring an object over a network or saving it to a local file, serialization is required.
为什么要使用克隆?如何实现对象克隆?深拷贝和浅拷贝区别是什么?
(1)什么要使用克隆?
想对一个对象进行复制,又想保留原有的对象进行接下来的操作,这个时候就需要克隆了。
(2)如何实现对象克隆?
实现Cloneable接口,重写clone方法;
实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深克隆。
BeanUtils,apache和Spring都提供了bean工具,只是这都是浅克隆。
(3)深拷贝和浅拷贝区别是什么?
浅拷贝:仅仅克隆基本类型变量,不克隆引用类型变量;
深克隆:既克隆基本类型变量,又克隆引用类型变量;
(4)代码实例
Why use clones? How do I implement object cloning? What is the difference between a deep copy and a shallow copy?
(1) Why use cloning?
If you want to copy an object and keep the original object for the next operation, you need to clone it.
(2) How to implement object cloning?
Implement the Cloneable interface and override the clone method;
Implement the Serializable interface and clone through serialization and deserialization of objects to achieve true deep cloning.
BeanUtils, Apache, and Spring all provide bean utilities, but these are all shallow clones.
(3) what is that difference between a deep copy and a shallow copy?
Shallow copy: only basic type variables are cloned, reference type variables are not cloned;
Deep cloning: both basic type variables and reference type variables are cloned;
(4) Code examples
throw 和 throws 的区别?
(1)throw
作用在方法内,表示抛出具体异常,由方法体内的语句处理;
一定抛出了异常;
(2)throws
作用在方法的声明上,表示抛出异常,由调用者来进行异常处理;
可能出现异常,不一定会发生异常;
The difference between throws and throws?
(1)throw
Acting within a method, indicating that a specific exception is thrown, which is handled by a statement in the body of the method;
An exception must have been thrown;
(2)throws
Acting on the declaration of a method, it indicates that an exception is thrown and is handled by the caller;
Exceptions may or may not occur;
21
final、finally、finalize 有什么区别?
final可以修饰类,变量,方法,修饰的类不能被继承,修饰的变量不能重新赋值,修饰的方法不能被重写
finally用于抛异常,finally代码块内语句无论是否发生异常,都会在执行finally,常用于一些流的关闭。
finalize方法用于垃圾回收。
一般情况下不需要我们实现finalize,当对象被回收的时候需要释放一些资源,比如socket链接,在对象初始化时创建,整个生命周期内有效,那么需要实现finalize方法,关闭这个链接。
但是当调用finalize方法后,并不意味着gc会立即回收该对象,所以有可能真正调用的时候,对象又不需要回收了,然后到了真正要回收的时候,因为之前调用过一次,这次又不会调用了,产生问题。所以,不推荐使用finalize方法。
What's the difference between final, finally, and finalize?
You can decorate classes, variables, and methods, decorated classes cannot be inherited, decorated variables cannot be reassigned, and decorated methods cannot be overridden
Finally is used to throw an exception. The statement in the finally code block will execute finally regardless of whether an exception occurs. It is often used to close some streams.
The finalize method is used for garbage collection.
In general, we do not need to implement finalize. When the object is recycled, we need to release some resources, such as the socket link, which is created when the object is initialized and is valid throughout its life cycle. Then we need to implement the finalize method to close the link.
However, when the finalize method is called, it does not mean that GC will immediately recycle the object, so it is possible that when it is really called, the object does not need to be recycled, and then when it is really time to recycle, because it has been called once before, it will not be called this time, causing problems. Therefore, the finalize method is not recommended.
22
try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
In try-catch-finally, if the catch returns, will the finally be executed?
23
常见的异常类有哪些?
NullPointerException:空指针异常;
SQLException:数据库相关的异常;
IndexOutOfBoundsException:数组下角标越界异常;
FileNotFoundException:打开文件失败时抛出;
IOException:当发生某种IO异常时抛出;
ClassCastException:当试图将对象强制转换为不是实例的子类时,抛出此异常;
NoSuchMethodException:无法找到某一方法时,抛出;
ArrayStoreException:试图将错误类型的对象存储到一个对象数组时抛出的异常;
NumberFormatException:当试图将字符串转换成数字时,失败了,抛出;
IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数。
ArithmeticException当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。
What are the common exception classes?
Null PointerException: null pointer exception;
SQL Exception: database-related exception;
IndexOutOfBound Exception: array lower corner out-of-range exception;
File NotFound Exception: thrown when opening a file fails;
IO Exception: Thrown when an IO exception occurs;
ClassCast Exception: This exception is thrown when an attempt is made to cast an object to a subclass that is not an instance;
NoSuch MethodE xception: Thrown when a method cannot be found;
ArrayStore Exception: An exception thrown when attempting to store an object of the wrong type into an array of objects;
Number FormatException: Thrown when an attempt to convert a string to a number fails;
IllegalArgument Exception throws an exception indicating that an illegal or incorrect argument was passed to the method.
Arithmetic Exception This exception is thrown when the operational condition of the exception occurs. For example, an integer "divided by zero" throws an instance of this class.
24
hashcode是什么?有什么作用?
Java中Object有一个方法:
public native int hashcode();
(1)hashcode()方法的作用
hashcode()方法主要配合基于散列的集合一起使用,比如HashSet、HashMap、HashTable。
当集合需要添加新的对象时,先调用这个对象的hashcode()方法,得到对应的hashcode值,实际上hashmap中会有一个table保存已经存进去的对象的hashcode值,如果table中没有改hashcode值,则直接存入,如果有,就调用equals方法与新元素进行比较,相同就不存了,不同就存入。
(2)equals和hashcode的关系
如果equals为true,hashcode一定相等;
如果equals为false,hashcode不一定不相等;
如果hashcode值相等,equals不一定相等;
如果hashcode值不等,equals一定不等;
(3)重写equals方法时,一定要重写hashcode方法
(4)百度百科
hashcode方法返回该对象的哈希码值。支持该方法是为哈希表提供一些优点,例如,java.util.Hashtable 提供的哈希表。
hashCode 的常规协定是:
在 Java 应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上 equals 比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。
以下情况不 是必需的:如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
当equals方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
25
java 中操作字符串都有哪些类?它们之间有什么区别?
(1)String
String是不可变对象,每次对String类型的改变时都会生成一个新的对象。
(2)StringBuilder
线程不安全,效率高,多用于单线程。
(3)StringBuffer
线程安全,由于加锁的原因,效率不如StringBuilder,多用于多线程。
不频繁的字符串操作使用String,操作频繁的情况不建议使用String。
StringBuilder > StringBuffer > String。
What are the classes for manipulating strings in Java? What's the difference between them?
(1)String
String is an immutable object, and every change to the String type generates a new object.
(2)StringBuilder
Threads are not safe and efficient, and are mostly used for single threads.
(3)StringBuffer
Thread-safe. Not as efficient as StringBuilder due to locking. Mostly used for multithreading.
String is used for infrequent string operations, and it is not recommended to use String for frequent operations.
StringBuilder > StringBuffer > String。
26
java 中都有哪些引用类型?
(1)强引用
Java中默认声明的就是强引用,比如:
What are the reference types in Java?
(1) Strong reference
The default declaration in Java is a strong reference, such as:
Object obj = new Object();
obj = null;
只要强引用存在,垃圾回收器将永远不会回收被引用的对象。如果想被回收,可以将对象置为null;
As long as a strong reference exists, the garbage collector will never reclaim the referenced object. If you want to be recycled, you can set the object to null;
(2)软引用(SoftReference)
在内存足够的时候,软引用不会被回收,只有在内存不足时,系统才会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会跑出内存溢出异常。
When the memory is sufficient, the soft reference will not be recycled. Only when the memory is insufficient, the system will recycle the soft reference object. If there is still not enough memory after recycling the soft reference object, a memory overflow exception will occur.
byte[] buff = new byte[1024 * 1024];
SoftReference<byte[]> sr = new SoftReference<>(buff);
(3)弱引用(WeakReference)
进行垃圾回收时,弱引用就会被回收。
When garbage collection occurs, the weak reference is collected.
(4)虚引用(PhantomReference)
(5)引用队列(ReferenceQueue)
引用队列可以与软引用、弱引用、虚引用一起配合使用。
当垃圾回收器准备回收一个对象时,如果发现它还有引用,就会在回收对象之前,把这个引用加入到引用队列中。
程序可以通过判断引用队列中是否加入了引用,来判断被引用的对象是否将要被垃圾回收,这样可以在对象被回收之前采取一些必要的措施。
Reference queues can be used with soft, weak, and virtual references.
When the garbage collector is ready to reclaim an object, if it finds that it still has a reference, it will add the reference to the reference queue before the object is reclaimed.
The program can determine whether the referenced object will be garbage collected by determining whether a reference is added to the reference queue, so that some necessary measures can be taken before the object is collected.
27
在 Java 中,为什么不允许从静态方法中访问非静态变量?
静态变量属于类本身,在类加载的时候就会分配内存,可以通过类名直接访问;
非静态变量属于类的对象,只有在类的对象产生时,才会分配内存,通过类的实例去访问;
静态方法也属于类本身,但是此时没有类的实例,内存中没有非静态变量,所以无法调用。
In Java, why not allow non-static variables to be accessed from static methods?
Static variables belong to the class itself, which allocates memory when the class is loaded and can be accessed directly through the class name;
A non-static variable belongs to an object of a class. Only when an object of the class is generated, memory will be allocated and accessed through an instance of the class;
Static methods also belong to the class itself, but there is no instance of the class at this time, and there are no non-static variables in memory, so they cannot be called.
28
28、说说Java Bean的命名规范
JavaBean 类必须是一个公共类,并将其访问属性设置为 public
JavaBean 类必须有一个空的构造函数:类中必须有一个不带参数的公用构造器,此构造器也应该通过调用各个特性的设置方法来设置特性的缺省值。
一个javaBean类不应有公共实例变量,类变量都为private
持有值应该通过一组存取方法(getXxx 和 setXxx)来访问:对于每个特性,应该有一个带匹配公用 getter 和 setter 方法的专用实例变量。
属性为布尔类型,可以使用 isXxx() 方法代替 getXxx() 方法。
通常属性名是要和 包名、类名、方法名、字段名、常量名作出区别的:
首先:必须用英文,不要用汉语拼音
(1)包(package)
用于将完成不同功能的类分门别类,放在不同的目录(包)下,包的命名规则:将公司域名反转作为包名。比如www.sohu.com 对于包名:每个字母都需要小写。比如:com.sohu.test;该包下的Test类的全名是:com.sohu.Test.Java 。
如果定义类的时候没有使用package,那么java就认为我们所定义的类位于默认包里面(default package)。
(2)类
首字母大写,如果一个类由多个单词构成,那么每个单词的首字母都大写,而且中间不使用任何的连接符。尽量使用英文。如ConnectionFactory
(3)方法
首单词全部小写,如果一个方法由多个单词构成,那么从第二个单词开始首字母大写,不使用连接符。addPerson
(4)字段
与方法相同。如ageOfPerson
(5)常量
所有单词的字母都是大写,如果有多个单词,那么使用下划线链接即可。
如:public static final int AGE_OF_PERSON = 20; //通常加上static
29、Java Bean 属性命名规范问题分析
public class User {
private String busName;
private String pCount;
private Boolean isRunning;
//正确的命名方式,驼峰式的
public String getBusName() {
return busName;
}
public void setBusName(String busName) {
this.busName = busName;
}
//这是什么?
public String getpCount() {
return pCount;
}
public void setpCount(String pCount) {
this.pCount = pCount;
}
//这个也是不允许的
public Boolean getIsRunning() {
return isRunning;
}
public void setIsRunning(Boolean isRunning) {
this.isRunning = isRunning;
}
}
1. javabean属性命名尽量使用常规的驼峰式命名规则
2. 属性名第一个单词尽量避免使用一个字母:如eBook, eMail。
3. boolean属性名避免使用 “is” 开头的名称
4. 随着jdk, eclipse, spring 等软件版本的不断提高, 底版本的出现的问题可能在高版本中解决了, 低版本原来正常的代码可能在高版本环境下不再支持。
1. The JavaBean attributes are named using the usual camelback naming convention whenever possible.
2. Try to avoid using one letter in the first word of the property name: eBook, eMail.
3. Boolean property names Avoid names that begin with "is"
4. With the continuous improvement of JDK, eclipse, spring and other software versions, the problems of the lower version may be solved in the higher version, and the original normal code of the lower version may no longer be supported in the higher version environment.
30、什么是 Java 的内存模型?
在了解什么是 Java 内存模型之前,先了解一下为什么要提出 Java 内存模型。
之前提到过并发编程有三大问题
CPU 缓存,在多核 CPU 的情况下,带来了可见性问题
操作系统对当前执行线程的切换,带来了原子性问题
译器指令重排优化,带来了有序性问题
为了解决并发编程的三大问题,提出了 JSR-133,新的 Java 内存模型,JDK 5 开始使用。
简单总结下
Java 内存模型是 JVM 的一种规范
定义了共享内存在多线程程序中读写操作行为的规范
屏蔽了各种硬件和操作系统的访问差异,保证了 Java 程序在各种平台下对内存的访问效果一致
解决并发问题采用的方式:限制处理器优化和使用内存屏障
增强了三个同步原语(synchronized、volatile、final)的内存语义
定义了 happens-before 规则
Before we look at what the Java memory model is, let's look at why the Java memory model was proposed.
As I mentioned before, there are three big problems with concurrent programming.
CPU caching, in the case of multi-core CPUs, brings visibility issues
The switching of the current thread of execution by the operating system introduces the problem of atomicity.
The rearrangement and optimization of the translator instructions bring about the problem of orderliness.
In order to solve the three problems of concurrent programming, JSR-133, a new Java memory model, was proposed and JDK 5 began to use it.
A brief summary
The Java Memory Model is a specification for the JVM
Defines the behavior of read and write operations in a multithreaded program with shared memory
The access difference of various hardware and operating systems is shielded, and the memory access effect of a Java program under various platforms is ensured to be consistent.
Ways to solve concurrency problems: limiting processor optimization and using memory barriers
Enhanced memory semantics for three synchronization primitives (synchronized, volatile, final)
Defines the happens-before rule
31、在 Java 中,什么时候用重载,什么时候用重写?
(1)重载是多态的集中体现,在类中,要以统一的方式处理不同类型数据的时候,可以用重载。
(2)重写的使用是建立在继承关系上的,子类在继承父类的基础上,增加新的功能,可以用重写。
(3)简单总结:
重载是多样性,重写是增强剂;
目的是提高程序的多样性和健壮性,以适配不同场景使用时,使用重载进行扩展;
目的是在不修改原方法及源代码的基础上对方法进行扩展或增强时,使用重写;
生活例子:
你想吃一碗面,我给你提供了拉面,炒面,刀削面,担担面供你选择,这是重载;
你想吃一碗面,我不但给你端来了面,还给你加了青菜,加了鸡蛋,这个是重写;
设计模式:
cglib实现动态代理,核心原理用的就是方法的重写;
详细解答:
Java的重载(overload) 最重要的应用场景就是构造器的重载,构造器重载后,提供多种形参形式的构造器,可以应对不同的业务需求,加强程序的健壮性和可扩展性,比如我们最近学习的Spring源码中的ClassPathXmlApplicationContext,它的构造函数使用重载一共提供了10个构造函数,这样就为业务的选择提供了多选择性。在应用到方法中时,主要是为了增强方法的健壮性和可扩展性,比如我们在开发中常用的各种工具类,比如我目前工作中的短信工具类SMSUtil, 发短信的方法就会使用重载,针对不同业务场景下的不同形参,提供短信发送方法,这样提高了工具类的扩展性和健壮性。
总结:重载必须要修改方法(构造器)的形参列表,可以修改方法的返回值类型,也可以修改方法的异常信息即访问权限;使用范围是在同一个类中,目的是对方法(构造器)进行功能扩展,以应对多业务场景的不同使用需求。提高程序的健壮性和扩展性。
java的重写(override) 只要用于子类对父类方法的扩展或修改,但是在我们开发中,为了避免程序混乱,重写一般都是为了方法的扩展,比如在cglib方式实现的动态代理中,代理类就是继承了目标类,对目标类的方法进行重写,同时在方法前后进行切面织入。
总结:方法重写时,参数列表,返回值得类型是一定不能修改的,异常可以减少或者删除,但是不能抛出新的异常或者更广的异常,方法的访问权限可以降低限制,但是不能做更严格的限制。
(4)在里氏替换原则中,子类对父类的方法尽量不要重写和重载。(我们可以采用final的手段强制来遵循)
32、举例说明什么情况下会更倾向于使用抽象类而不是接口?
Give an example of when you would prefer to use an abstract class instead of an interface?
接口和抽象类都遵循”面向接口而不是实现编码”设计原则,它可以增加代码的灵活性,可以适应不断变化的需求。下面有几个点可以帮助你回答这个问题:在 Java 中,你只能继承一个类,但可以实现多个接口。所以一旦你继承了一个类,你就失去了继承其他类的机会了。
Both interfaces and abstract classes follow the design principle of “interface orientation rather than implementation coding”, which can increase the flexibility of code and adapt to changing requirements. Here are a few points to help you answer this question: In Java, you can only inherit from one class, but you can implement multiple interfaces. So once you inherit one class, you lose the opportunity to inherit other classes.
接口通常被用来表示附属描述或行为如: Runnable 、 Clonable 、 Serializable 等等,因此当你使用抽象类来表示行为时,你的类就不能同时是 Runnable 和 Clonable( 注:这里的意思是指如果把 Runnable 等实现为抽象类的情况 ) ,因为在 Java 中你不能继承两个类,但当你使用接口时,你的类就可以同时拥有多个不同的行为。
Interfaces are often used to represent subordinate descriptions or behaviors such as Runnable, Clonable, Serializable, and so on, so when you use abstract classes to represent behaviors, Your class can’t be both Runnable and Clonable, because in Java you can’t inherit from two classes, but when you use interfaces, your class can have multiple different behaviors at the same time.
在一些对时间要求比较高的应用中,倾向于使用抽象类,它会比接口稍快一点。如果希望把一系列行为都规范在类继承层次内,并且可以更好地在同一个地方进行编码,那么抽象类是一个更好的选择。有时,接口和抽象类可以一起使用,接口中定义函数,而在抽象类中定义默认的实现。
In some time-critical applications, abstract classes tend to be used, which are slightly faster than interfaces. If you want to normalize a set of behaviors within a class inheritance hierarchy, and you can better code them in the same place, abstract classes are a better choice. Sometimes an interface and an abstract class can be used together, with the function defined in the interface and the default implementation defined in the abstract class.
33、实例化对象有哪几种方式What are several ways to instantiate an object
new
clone()
通过反射机制创建Created by the reflection mechanism
//用 Class.forName方法获取类,在调用类的newinstance()方法
Class<?> cls = Class.forName("com.dao.User");
User u = (User)cls.newInstance();
序列化反序列化Serialize deserialize
//将一个对象实例化后,进行序列化,再反序列化,也可以获得一个对象(远程通信的场景下使用)
ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream("D:/data.txt"));
//序列化对象
out.writeObject(user1);
out.close();
//反序列化对象
ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:/data.txt"));
User user2 = (User) in.readObject();
System.out.println("反序列化user:" + user2);
in.close();
34、byte类型127+1等于多少
byte的范围是-128~127。
字节长度为8位,最左边的是符号位,而127的二进制为01111111,所以执行+1操作时,01111111变为10000000。
大家知道,计算机中存储负数,存的是补码的兴衰。左边第一位为符号位。
那么负数的补码转换成十进制如下:
一个数如果为正,则它的原码、反码、补码相同;一个正数的补码,将其转化为十进制,可以直接转换。
已知一个负数的补码,将其转换为十进制数,步骤如下:
先对各位取反;
将其转换为十进制数;
加上负号,再减去1;
例如10000000,最高位是1,是负数,①对各位取反得01111111,转换为十进制就是127,加上负号得-127,再减去1得-128;
35、Java 容器都有哪些?What are the Java containers?
(1)Collection
① set
HashSet、TreeSet
② list
ArrayList、LinkedList、Vector
(2)Map
HashMap、HashTable、TreeMap
36、Collection 和 Collections 有什么区别?
(1)Collection是最基本的集合接口,Collection派生了两个子接口list和set,分别定义了两种不同的存储方式。Collection is the most basic collection interface. Collection derives two subinterfaces, list and set, which define two different storage modes respectively.
(2)Collections是一个包装类,它包含各种有关集合操作的静态方法(对集合的搜索、排序、线程安全化等)。Collections is a wrapper class that contains static methods for various collection operations (searching, sorting, thread-securing, and so on)
此类不能实例化,就像一个工具类,服务于Collection框架。This class cannot be instantiated, just like a utility class, serving the Collection framework.
37、list与Set区别
(1)List简介
List introduction
实际上有两种List:一种是基本的ArrayList,其优点在于随机访问元素,另一种是LinkedList,它并不是为快速随机访问设计的,而是快速的插入或删除。
There are actually two kinds of Lists: a basic ArrayList, which has the advantage of random access to elements, and a LinkedList, which is not designed for fast random access, but for fast insertion or deletion.
ArrayList:由数组实现的List。允许对元素进行快速随机访问,但是向List中间插入与移除元素的速度很慢。
Array List: a list implemented by an array. Allows fast random access to elements, but is slow to insert and remove elements into the middle of the List.
LinkedList :对顺序访问进行了优化,向List中间插入与删除的开销并不大。随机访问则相对较慢。
还具有下列方 法:addFirst(), addLast(), getFirst(), getLast(), removeFirst() 和 removeLast(), 这些方法 (没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。
Sequential access is optimized, and the cost of inserting and deleting in the middle of the List is not large. Random access is relatively slow.
Also has the following methods: addFirst (), addLast (), get first (), getLast (), removeFirst () and removeLast (). These methods, which are not defined in any interface or base class, allow the LinkedList to be used as a stack, a queue, and a bidirectional queue.
(2)Set简介
Set具有与Collection完全一样的接口,因此没有任何额外的功能。实际上Set就是Collection,只是行为不同。这是继承与多态思想的典型应用:表现不同的行为。Set不保存重复的元素(至于如何判断元素相同则较为负责)
Set has exactly the same interface as Collection, so there is no additional functionality. In fact, a Set is just a Collection, but the behavior is different. This is a typical application of the idea of inheritance and polymorphism: behaving differently. Set does not save duplicate elements (it is more responsible for how elements are judged to be identical)
Set : 存入Set的每个元素都必须是唯一的,因为Set不保存重复元素。加入Set的元素必须定义equals()方法以确保对象的唯一性。Set与Collection有完全一样的接口。Set接口不保证维护元素的次序。
Set: Each element stored in a set must be unique, because a set does not hold duplicate elements. Elements added to a Set must define an equals () method to ensure the uniqueness of the object. Set has exactly the same interface as Collection. The Set interface does not guarantee that the order of the elements is maintained.
HashSet:为快速查找设计的Set。存入HashSet的对象必须定义hashCode()。
HashSet: Set designed for fast lookup. The object stored in the HashSet must define hashCode ().
TreeSet: 保存次序的Set, 底层为树结构。使用它可以从Set中提取有序的序列。
Set that holds the order, with a tree structure at the bottom. Use it to extract an ordered sequence from a Set.
(3)list与Set区别
① List,Set都是继承自Collection接口
List,Set都是继承自Collection接口
② List特点:元素有放入顺序,元素可重复 ,Set特点:元素无放入顺序,元素不可重复,重复元素会覆盖掉,(元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的,加入Set 的Object必须定义equals()方法 ,另外list支持for循环,也就是通过下标来遍历,也可以用迭代器,但是set只能用迭代,因为他无序,无法用下标来取得想要的值。)
List features: Elements are placed in order and can be repeated. Set features: Elements are not placed in order and cannot be repeated. Repeated elements will be overwritten. (Although elements are not placed in order, the position of an element in set is determined by the HashCode of the element, and its position is actually fixed. An Object added to a Set must define an equals () method. In addition, a list supports a for loop, that is, traversing through subscripts. An iterator can also be used, but a set can only be iterated, because it is unordered and cannot use subscripts to get the desired value.)
③ Set和List对比:
Set vs. List:
Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
The efficiency of element retrieval is low, the efficiency of deletion and insertion is high, and the insertion and deletion will not cause the change of element position.
List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。
Similar to an array, a List can grow dynamically, making it efficient to find elements, and inefficient to insert and delete elements, because it causes other elements to change their positions.
38、HashMap 和 Hashtable 有什么区别?
HashMap是线程不安全的,HashTable是线程安全的;
HashMap中允许键和值为null,HashTable不允许;
HashMap的默认容器是16,为2倍扩容,HashTable默认是11,为2倍+1扩容;
HashMap is thread-unsafe, HashTable is thread-safe;
Keys and values are allowed to be null in HashMap, but not in HashTable;
The default container of HashMap is 16, which is 2 times the expansion. The default container of HashTable is 11, which is 2 times + 1 the expansion.
39、说一下 HashMap 的实现原理?
What is the implementation principle of HashMap?
(1)简介
HashMap基于map接口,元素以键值对方式存储,允许有null值,HashMap是线程不安全的。
HashMap is based on the map interface. Elements are stored in the form of key-value pairs, and null values are allowed. HashMap is thread-unsafe.
(2)基本属性Basic properties
初始化大小,默认16,2倍扩容;
负载因子0.75;
初始化的默认数组;
size
threshold。判断是否需要调整hashmap容量
Initialization size, default 16, 2 times capacity expansion;
Load factor 0.75;
Initialized default array;
size
threshold。 Determine if hashmap capacity needs to be adjusted
(3)HashMap的存储结构
Storage structure of HashMap
JDK1.7中采用数组+链表的存储形式。
JDK 1.7 uses the storage form of array + linked list.
HashMap采取Entry数组来存储key-value,每一个键值对组成了一个Entry实体,Entry类时机上是一个单向的链表结构,它具有next指针,指向下一个Entry实体,以此来解决Hash冲突的问题。
HashMap uses Entry array to store key-value, and each key-value pair forms an Entry entity. The Entry class is a one-way linked list structure with a next pointer pointing to the next Entry entity, so as to solve the problem of Hash conflict.
HashMap实现一个内部类Entry,重要的属性有hash、key、value、next。
HashMap implements an internal class Entry, and the important attributes are hash, key, value, and next.
JDK1.8中采用数据+链表+红黑树的存储形式。当链表长度超过阈值(8)时,将链表转换为红黑树。在性能上进一步得到提升。
JDK 1.8 uses the storage form of data + linked list + red-black tree. When the length of the linked list exceeds the threshold value (8), the linked list is converted into a red-black tree. The performance has been further improved.
40、set有哪些实现类?What are the implementation classes for set?
(1)HashSet
HashSet是set接口的实现类,set下面最主要的实现类就是HashSet(也就是用的最多的),此外还有LinkedHashSet和TreeSet。
HashSet是无序的、不可重复的。通过对象的hashCode和equals方法保证对象的唯一性。
HashSet内部的存储结构是哈希表,是线程不安全的。
HashSet is the implementation class of the set interface. The most important implementation class under set is HashSet (that is, the most used). In addition, there are LinkedHashSet and TreeSet.
A HashSet is unordered and unrepeatable. The uniqueness of an object is guaranteed by its hashCode and equals methods.
The storage structure inside the HashSet is a hash table, which is not thread-safe.
(2)TreeSet
TreeSet对元素进行排序的方式:TreeSet sorts elements by:
元素自身具备比较功能,需要实现Comparable接口,并覆盖compareTo方法。
元素自身不具备比较功能,需要实现Comparator接口,并覆盖compare方法。
The element itself has a comparison function, and it needs to implement the Comparable interface and override the compareTo method.
The element itself does not have a comparison function. You need to implement the Comparator interface and override the compare method.
(3)LinkedHashSet
LinkedHashSet是一种有序的Set集合,即其元素的存入和输出的顺序是相同的。
A LinkedHashSet is an ordered Set, that is, its elements are stored and output in the same order.
41、说一下 HashSet 的实现原理?
What is the implementation principle of HashSet?
HashSet实际上是一个HashMap实例,数据存储结构都是数组+链表。
HashSet is actually a HashMap instance, and the data storage structure is array + linked list.
HashSet是基于HashMap实现的,HashSet中的元素都存放在HashMap的key上面,而value都是一个统一的对象PRESENT。
HashSet is implemented based on HashMap. The elements in HashSet are stored in the key of HashMap, and the value is a unified object PRESENT.
private static final Object PRESENT = new Object();
HashSet中add方法调用的是底层HashMap中的put方法,put方法要判断插入值是否存在,而HashSet的add方法,首先判断元素是否存在,如果存在则插入,如果不存在则不插入,这样就保证了HashSet中不存在重复值。
The add method in HashSet calls the put method in the underlying HashMap. The put method determines whether the inserted value exists, while the add method of HashSet first determines whether the element exists. If it exists, it is inserted. If it does not exist, it is not inserted. This ensures that there is no duplicate value in HashSet.
通过对象的hashCode和equals方法保证对象的唯一性。
The uniqueness of an object is guaranteed by its hashCode and equals methods.
42、ArrayList 和 LinkedList 的区别是什么?
ArrayList是动态数组的数据结构实现,查找和遍历的效率较高;
LinkedList 是双向链表的数据结构,增加和删除的效率较高;
ArrayList is the data structure implementation of dynamic array, and the efficiency of search and traversal is high;
LinkedList is a doubly linked list data structure, which is more efficient to add and delete;
44、在 Queue 中 poll()和 remove()有什么区别?
What’s the difference between poll () and remove () in Queue?
(1)offer()和add()区别:
增加新项时,如果队列满了,add会抛出异常,offer返回false。
When adding a new item, if the queue is full, add throws an exception and offer returns false.
(2)poll()和remove()区别:
poll()和remove()都是从队列中删除第一个元素,remove抛出异常,poll返回null。
Both poll () and remove () remove the first element from the queue, remove throws an exception, and poll returns null.
(3)peek()和element()区别:
peek()和element()用于查询队列头部元素,为空时element抛出异常,peek返回null。
Peek () and element () are used to query the element at the head of the queue. When it is empty, element throws an exception, and peek returns null.
45、哪些集合类是线程安全的
Which collection classes are thread-safe
Vector:就比Arraylist多了个同步化机制(线程安全)。
Stack:栈,也是线程安全的,继承于Vector。
Hashtable:就比Hashmap多了个线程安全。
ConcurrentHashMap:是一种高效但是线程安全的集合。
Vector: It has one more synchronization mechanism (thread-safe) than Arraylist.
Stack: Stack, also thread-safe, inherits from Vector.
Hashtable: It’s one more thread-safe than Hashmap.
Concurrent HashMap: is an efficient but thread-safe collection.
46、迭代器 Iterator 是什么?What is an Iterator?
为了方便的处理集合中的元素,Java中出现了一个对象,该对象提供了一些方法专门处理集合中的元素.例如删除和获取集合中的元素.该对象就叫做迭代器(Iterator)。
In order to facilitate the processing of the elements in the collection, an object appeared in Java, which provides some methods to deal with the elements in the collection. Such as deleting and getting elements from the collection. This object is called an Iterator.
47、Iterator 怎么使用?有什么特点?
Iterator 接口源码中的方法:
java.lang.Iterable 接口被 java.util.Collection 接口继承,java.util.Collection 接口的 iterator() 方法返回一个 Iterator 对象
next() 方法获得集合中的下一个元素
hasNext() 检查集合中是否还有元素
remove() 方法将迭代器新返回的元素删除
Methods in the Iterator interface source code:
The Java. Lang. Iterable interface is inherited by the Java. Util. Collection interface, and the iterator () method of the Java. Util. Collection interface returns an Iterator object
The next () method gets the next element in the collection
HasNext () checks if there are more elements in the collection
The remove () method removes the new element returned by the iterator
48、Iterator 和 ListIterator 有什么区别?
(1)ListIterator 继承 Iterator
(2)ListIterator 比 Iterator多方法
add(E e) 将指定的元素插入列表,插入位置为迭代器当前位置之前
set(E e) 迭代器返回的最后一个元素替换参数e
hasPrevious() 迭代器当前位置,反向遍历集合是否含有元素
previous() 迭代器当前位置,反向遍历集合,下一个元素
previousIndex() 迭代器当前位置,反向遍历集合,返回下一个元素的下标
nextIndex() 迭代器当前位置,返回下一个元素的下标
(3)使用范围不同,Iterator可以迭代所有集合;ListIterator 只能用于List及其子类
ListIterator 有 add 方法,可以向 List 中添加对象;Iterator 不能
ListIterator 有 hasPrevious() 和 previous() 方法,可以实现逆向遍历;Iterator不可以
ListIterator 有 nextIndex() 和previousIndex() 方法,可定位当前索引的位置;Iterator不可以
ListIterator 有 set()方法,可以实现对 List 的修改;Iterator 仅能遍历,不能修改。
49、怎么确保一个集合不能被修改?
我们很容易想到用final关键字进行修饰,我们都知道
It’s easy to think of decorating with the final keyword, as we all know.
final关键字可以修饰类,方法,成员变量,final修饰的类不能被继承,final修饰的方法不能被重写,final修饰的成员变量必须初始化值,如果这个成员变量是基本数据类型,表示这个变量的值是不可改变的,如果说这个成员变量是引用类型,则表示这个引用的地址值是不能改变的,但是这个引用所指向的对象里面的内容还是可以改变的。
The final keyword can modify classes, methods, and member variables. A final-decorated class cannot be inherited, a final-decorated method cannot be overridden, and a final-decorated member variable must be initialized. If the member variable is a primitive data type, the value of the variable is immutable. If the member variable is a reference type, It means that the address value of the reference cannot be changed, but the contents of the object to which the reference points can still be changed.
那么,我们怎么确保一个集合不能被修改?首先我们要清楚,集合(map,set,list…)都是引用类型,所以我们如果用final修饰的话,集合里面的内容还是可以修改的。
So, how do we ensure that a collection cannot be modified? First of all, let’s be clear that the set (map, set, list …) They are all reference types, so if we decorate them with final, the contents of the collection can still be modified.
我们可以做一个实验:
We can do an experiment:
可以看到:我们用final关键字定义了一个map集合,这时候我们往集合里面传值,第一个键值对1,1;我们再修改后,可以把键为1的值改为100,说明我们是可以修改map集合的值的。
It can be seen that we use the final keyword to define a map set. At this time, we pass a value to the set. The first key value is 1, 1. After we modify it, we can change the value of the key 1 to 100, indicating that we can modify the value of the map set.
那我们应该怎么做才能确保集合不被修改呢?
我们可以采用Collections包下的unmodifiableMap方法,通过这个方法返回的map,是不可以修改的。他会报 java.lang.UnsupportedOperationException错。
So what should we do to ensure that the collection is not modified?
We can use the unmodifiableMap method under the Collections package. The map returned by this method cannot be modified. He will report Java. Lang. UnsupportedOperation Exception mistakes.
同理:Collections包也提供了对list和set集合的方法。
Similarly, the Collections package also provides methods on list and set collections.
Collections.unmodifiableList(List)
Collections.unmodifiableSet(Set)
50、队列和栈是什么?有什么区别?
What are queues and stacks? What’s the difference?
(1)队列先进先出,栈先进后出。
(1) First in first out of the queue and first in last out of the stack.
(2)遍历数据速度不同。
(2) The speed of traversing data is different.
栈只能从头部取数据 也就最先放入的需要遍历整个栈最后才能取出来,而且在遍历数据的时候还得为数据开辟临时空间,保持数据在遍历前的一致性;
The stack can only fetch data from the head, that is, the first one put in needs to traverse the whole stack before it can be fetched, and when traversing the data, it has to open up temporary space for the data to maintain the consistency of the data before traversing
队列则不同,他基于地址指针进行遍历,而且可以从头或尾部开始遍历,但不能同时遍历,无需开辟临时空间,因为在遍历的过程中不影像数据结构,速度要快的多。
Queues, on the other hand, are traversed based on address pointers, and can be traversed from the beginning or the end, but not at the same time. There is no need to open up temporary space, because the data structure is not scanned in the process of traversing, and the speed is much faster.