Android Intermediate and Advanced Development Interview Questions Sprint Collection (1)

The following is mainly for the interview questions collected in the past to make a classification and sorting, which is convenient for everyone to review and refer to. Today is the first episode~

Emphasize: [ 因篇幅问题:文中只放部分内容,全部文档需要的可找作者获取。]

Java Basics

1. What is the difference between an abstract class and an interface?

Reference answer: The general difference is as follows:

  • Abstract classes can provide implementation details of member methods, while only public abstract methods can exist in interfaces;
  • Member variables in abstract classes can be of various types, while member variables in interfaces can only be of public static finaltype ;
  • Interfaces cannot contain constructors, static code blocks and static methods, while abstract classes can have constructors, static code blocks and static methods;
  • A class can only inherit one abstract class, but a class can implement multiple interfaces;
  • An abstract class is faster to access than an interface, because the interface takes time to find a method that is implemented in the class;
  • If you add new methods to an abstract class, you can provide it with default implementations. So you don't need to change your current code. If you add methods to an interface, then you must change the class that implements the interface.
  • Interfaces are more for constraining the behavior of classes and can be used for decoupling, while abstract classes focus more on code reuse.

2. Talk about what can be modified by final, static and synchronized, and the role after modification?

Reference answer: final: You can modify classes, methods, and fields.

修饰类:该类不会被继承。
​
修饰方法:该方法不能被重写。
​
修饰字段:被修饰的 字段必须 赋初始值,并且不能被改变。如果字段是引用类型的。那么他将不能引用别的对象,但是当前的对象内的属性值是可以改变的。

static : inner classes, methods, fields can be modified.

修饰内部类:被static修饰 的内部类可以直接作为一个 普通的类来使用,而不需先实例一个外部列。
​
修饰方法:调用该方法的时候只需要类名 . 方法就可以直接调用,不需要创建对象。
​
修饰字段:通过类名 . 的方式可以直接 获取 或者 赋值。

synchronized can modify methods, code blocks

修饰方法:被 synchronized 修饰方法方法在同一时刻只能被一个线程访问。其他线程将会被阻塞,直到当前线程释放锁。
​
修饰代码块:其实和修饰方法差不多,只不过 修饰代码块可以 使用 类锁。方法如果要使用类锁,只能设置为静态的方法。

3. Please briefly describe the difference between String, StringBuffer and StringBuilder?

Reference answer:

String is a string constant. Once created, it cannot be modified and is thread-safe; the String class uses the final modifier and cannot be inherited; the length of String is unchanged. A string suitable for a small number of operations. StringBuffer is a string variable with variable length and thread safety. It is suitable for a large number of string operations in the character buffer under multi-threading. StringBuilder is a string variable, the length is variable, and the thread is not safe. It is suitable for a large number of string operations in the character buffer under a single thread. String operations are performed at speed: StringBuilder > StringBuffer > String

  1. The difference and usage scenarios of "equals", "==" and "hashCode"?

Reference answer:

  • : == is used to compare whether the values ​​stored in the memory corresponding to the variables are the same. To compare the data of two basic types (note that they are basic types) or whether two reference variables are equal, you can only useoperator. If the data pointed to by a variable is of object type, such as Objet obj 1= new Object(), then two pieces of memory are involved; the variable obj1 is one memory, and new Object() is another memory (heap memory). , the value stored in the memory corresponding to the variable obj1 is the first address of the memory (heap memory) occupied by the object. For a variable that points to an object type, if you want to compare whether two variables point to the same object, that is, to see if the values ​​in the memory corresponding to the two variables are equal, then you need to use the == operator to compare;
  • equals: The equals method is used to compare whether the contents of two independent objects are the same:
String a=new String("a");
String b=new String("a");

The two new statements create two objects, and then use the two variables a/b to point to one of the objects respectively. These are two different objects, and their first addresses are different, that is, the values ​​stored in a and b. (the first address of the corresponding object) is not the same, so the expression a==b will return false, and the contents of the two objects are the same, so the expression a.equals(b) will return true. Let's look at the equal source code:

 * Note that it is generally necessary to override the {@code hashCode}
 * method whenever this method is overridden, so as to maintain the
 * general contract for the {@code hashCode} method, which states
 * that equal objects must have equal hash codes.
   *
 * @param   obj   the reference object with which to compare.
 * @return  {@code true} if this object is the same as the obj
 * argument; {@code false} otherwise.
 * @see     #hashCode()
 * @see     java.util.HashMap
   */
   public boolean equals(Object obj) {
   return (this == obj);
   }

If a class does not override the equals method, then calling the object's equals is actually ==.

  • hashCode: Because the rewritten equals() is generally more comprehensive and complex, so the efficiency is relatively low, and using hashCode() for comparison, you only need to generate a hash value for comparison, and the efficiency is very high, then hashCode () Why do you need equals() when the efficiency is so high?
  • Usage scenario: Because hashCode() is not completely reliable, and sometimes the hashcodes generated by different objects will be the same (hash conflict), so hashCode() can only be said to be reliable most of the time, not absolutely reliable, so you can get Out: two objects that are equals() are equal, their hashCode() must be equal, that is, the comparison with equals() is absolutely reliable. The equals() of two objects with equal hashCode() are not necessarily equal, that is, hashCode() is not absolutely reliable. It is obviously too inefficient to use equals() for all the comparisons that require a lot and fast, so the solution is to use hashCode() to compare first whenever you need to compare. If the hashCode() is different, then It means that the two objects are definitely not equal (that is, there is no need to use equals() to compare again). If the hashCode() is the same, then compare their equals() at this time. If equals() is also the same, it means that the two objects are really the same

5. What is the difference between deep copy and shallow copy in Java?

Reference answer:

First of all, you need to understand that both shallow and deep copies are operations on an existing object. Let's first look at the concepts of shallow copy and deep copy. In Java, in addition to the basic data types (metatypes), there is also a reference data type of an instance object of a class. And generally use the "=" sign for assignment operation. For basic data types, its value is actually copied, but for objects, it is only the reference of the object that is assigned, and the reference of the original object is passed, and they actually point to the same object.

Shallow copy and deep copy are the distinctions made on this basis. If when copying the object, only the basic data type is copied, and the reference data type is only passed by reference, without real creation. A new object is considered a shallow copy. On the contrary, when copying the reference data type, a new object is created and the member variables in it are copied, which is considered as a deep copy. So now, you should understand that the so-called shallow copy and deep copy are just different operations on the reference data type of the instance object of the class when copying the object.

to conclude:

1. Shallow copy: The basic data type is passed by value, and the reference data type is copied by reference. This is a shallow copy.

2. Deep copy: pass the value of the basic data type, create a new object for the reference data type, and copy its content, this is a deep copy.

6. Talk about the difference between Error and Exception?

Reference answer:

Error is an error in the system, which is unpredictable. After such an exception occurs, the program will crash immediately. Only by modifying the code, so that the error does not appear, this kind of error cannot be caught.

Exception is to be expected. In the program, if you ever feel that an exception will occur in a certain piece of code, you can use try catch to catch it, or throw an exception directly. Exception can be divided into compile-time exception (CheckedException) and runtime exception (RuntimeException). Runtime exceptions can ignore the capture operation (RuntimeException), and compile-time exceptions must be caught using try catch.

7. What is the reflection mechanism? What are the application scenarios of the reflection mechanism?

Reference answer:

The Java reflection mechanism is that in the running state, for any class, you can know all the properties and methods in this class, and for any object, you can call any of its methods and properties; this dynamically acquired information and dynamic The ability to call a method of an object is called the reflection mechanism of the Java language. Application scenarios:

  1. Reverse code, such as decompiling
  2. Frameworks combined with annotations such as Retrofit
  3. Simple reflection mechanism application framework, such as EventBus (event bus)
  4. Dynamically generate class frameworks such as Gson

8. Talk about how to override the equals() method? Why rewrite hashCode()?

Reference answer:

equals: Compare the addresses of two objects for equality

hashCode: generally used in collections, such as in hashMap, when storing an element, the hash value will be calculated first, and then the location of the element will be determined according to the hash value. When calling hashCode on any object, the returned hash The values ​​must be equal.

Why do you need to rewrite hashCode

When storing an element in the collection, the value of the hashCode will be obtained first. If the hashCode is not rewritten, it will directly convert the address of the element into an integer and return it. If we create two objects, all the attribute values ​​of the two objects are the same, when storing in HashSet, the first element will be directly stored, and the hash value obtained by the second is different from the first, so the second Each element will also be stored, because jdk defaults to different hashCode values, equals must return false. So both values ​​will be stored. However, the attribute values ​​of these two objects are the same, so this will cause data non-uniqueness. So generally after rewriting equals, hashCode must be rewritten.

memory leak problem

Imagine a class that creates two objects with different property values, overriding both equals and hashCode. Then they are all stored in HashSet. Then modify the value of the second element. Finally, remove the second element from the set collection. After deleting, iteratively print, and you will find that the second element has not been deleted. Why? Because when an element is deleted, the hashCode value will be obtained, but because the attribute value is modified, the obtained hash value is different from the one obtained when saving, so the search is empty, and jdk thinks that the object is not in the collection, so it will not The deletion operation is performed, but the user task object has been deleted, so that the object cannot be released for a long time, resulting in a memory leak. The solution is not to modify the object information related to the HashCode value during execution. If you have to modify it, you must first delete it from the collection, and then add it to the collection after updating the data.

Summarize:

1.hashCode是为了提高在散列结构存储中查找的效率,在线性表中没有作用 
​
2.equals和hashCode需要同时覆盖。 
​
3.若两个对象equals返回true,则hashCode一定返回相同的int数。 
​
4.若两个对象equals返回false,则hashCode不一定返回不同的int数,但为不相等的对象生成不同hashCode值可以提高 哈希表的性能 
​
5.若两个对象hashCode返回相同int数,则equals不一定返回true。 
​
6.若两个对象hashCode返回不同int数,则equals一定返回false。 
​
7.同一对象在执行期间若已经存储在集合中,则不能修改影响hashCode值的相关信息,否则会导致内存泄露问题。 

9. What are the types of IO streams in Java? What is the difference between them?

Reference answer:

IO streams are divided into several

There are two kinds of streams in Java, one is byte stream and the other is character stream, which are represented by four abstract classes (each stream includes input and output, so there are four in total): InputStream, OutputStream , Reader, Writer. Other streams of various changes in Java are derived from them.

Character stream and byte stream are distinguished according to the difference in processing data. The byte stream is transmitted according to 8 bits. The byte stream is the most basic. The storage of all files is the storage of bytes. The characters of the file are not reserved on the disk, but the characters are encoded into bytes first. , and then store these bytes to disk.

  • 1. Byte streams can be used for any type of object, including binary objects, while character streams can only handle characters or strings;
  • 2. Throttling provides the ability to handle any type of IO operation, but it cannot handle Unicode characters directly, while character streams can.

Use character streams when reading text, such as txt files. Use byte streams when reading non-text files, such as mp3. In theory, any file can be read by byte stream, but when reading text data, in order to restore it to text, you must go through a conversion process. Relatively speaking, character stream saves this trouble, you can have method to read directly.

The character stream processing unit is 2-byte Unicode characters, which operate on characters, character arrays or strings respectively, while the byte stream processing unit is 1 byte, operating on bytes and byte arrays. Therefore, the character stream is formed by the Java virtual machine converting bytes into 2-byte Unicode characters, so it has better support for multiple languages!

What is the difference between BIO, NIO, and AIO

BIO: Block IO synchronous blocking IO is the traditional IO we usually use. It is characterized by a simple and convenient mode and low concurrent processing capability. NIO: Non IO synchronous non-blocking IO is an upgrade of traditional IO. The client and server communicate through Channel (channel) to achieve multiplexing. AIO: Asynchronous IO is an upgrade of NIO, also called NIO2, which implements asynchronous non-blocking IO. The operation of asynchronous IO is based on events and callback mechanisms.

BIO is a connection a thread. NIO is one thread per request. AIO is effectively one thread per request.

  • BIO: synchronization and blocking, the server implementation mode is one connection and one thread, that is, when the client has a connection request, the server needs to start a thread for processing. If the connection does not do anything, it will cause unnecessary thread overhead. Thread pool mechanism improved.
  • NIO: Synchronous non-blocking, the server implementation mode is one request and one thread, that is, the connection request sent by the client will be registered on the multiplexer, and the multiplexer will only start one when polling to connect with an I/O request. thread for processing.
  • AIO: Asynchronous non-blocking, the server implementation mode is one valid request for one thread, and the client's I/O request is completed by the OS first and then notifies the server application to start the thread for processing.

Applicable scenario analysis

  • The BIO method is suitable for a structure with a relatively small number of connections and a fixed number of connections. This method has relatively high requirements on server resources, and concurrency is limited to applications. It is the only choice before JDK1.4, but the program is intuitive and easy to understand.
  • The NIO method is suitable for architectures with a large number of connections and relatively short connections (light operation), such as chat servers, where concurrency is limited to applications, and programming is more complicated. JDK1.4 began to support it.
  • The AIO method is used for architectures with a large number of connections and relatively long connections (heavy operations), such as photo album servers. It fully calls the OS to participate in concurrent operations, and the programming is more complicated. JDK7 began to support it.

10. Talk about your understanding of type erasure in Java generics, and talk about its limitations?

Reference answer:

1: Type erasure occurs during compilation. It means that all generic information will be erased (inheriting Object by default)

2: Resolved limitations: 1 ArrayList(String> cannot add data of type Integer; the compiler first checks the type of the generic type in the code to solve 2 The editor gets the value from the generic type in ArrayList(String>, both Object forcibly converts String 3 The parent class defines the generic type, and the subclass implements it; the overloading of the implementation, in fact, the compiler will become an overriding. Solved by the bridge method of the compiler

3: Unresolved limitations: 1) Generic type variables cannot be basic data types 2) At runtime, the type cannot be detected; for example: object instanceof ArrayList (String> This logic cannot be implemented 3) Generic types cannot be used in static used in methods and static variables; as follows:

public class TestClass {
public static T getSome() {
return null;
}
}

This piece of logic, adding a static field, the compiler reports an error

11. Why is String designed to be immutable?

Reference answer:

1: Need for string constant pool

When creating a String object, if the string already exists in the constant pool, a new object will not be created, but the existing object will be referenced

If it is allowed to change, it will lead to various logical errors, such as changing one object will affect another independent object. Strictly speaking, the idea of ​​this constant pool is an optimization method

2: Allow String objects to cache HashCode

The hash code of String objects in java is frequently used, such as in hashMap. The invariance of the string ensures the uniqueness of the hash code, so it can be safely cached. This is also an optimization, meaning that new hash codes need not be computed at all. There is a private int hash in the String class to cache the hashcode

3: Security

String is used by many classes as parameters, such as network url, file path path, etc. If String is not fixed, it will cause various security risks

12. Tell me about your understanding of Java annotations?

Reference answer:

Essence: Make a mark, and make some modifications to the code specification and variable value through this mark. Mainly divided into three categories

Source It only exists in .java files, compiled into .class files and disappeared. The role is to allow developers to write code according to the specifications of the annotations. For example: @OverRide
Class In the process of the pre-compilation period, it will be processed into .class content, which is almost the same as the native code efficiency. The role is: automatically generate .class files and do some auxiliary work. For example: ButterKnife, GreenDao, ARouter Efficiency is comparable to native code
Runtime After compiling into a .class file, it still exists in the form of annotations. Instead, it takes effect at runtime. The role is: during runtime, do some auxiliary work through reflection. For example: xUtils Less efficient due to centralized use of traversal + reflection. And also disable reflection in 9.0

13. Talk about the creation and recycling timing of Java member variables, local variables and static variables?

Reference answer:

Member variables: The life cycle is accompanied by class objects. When the class objects are recycled, they are stored in the heap. Static variables: not recycled. In the method area, they are loaded with the loading of the class, and disappear with the disappearance of the class. Because the class needs to be unused for a long time , if it is not used or associated, it may be recycled by the recycling mechanism, so the life cycle of static member variables is very long. Unless it is shared data, it is not recommended to use static; Recyclables are stored on the stack.

Guess you like

Origin blog.csdn.net/m0_64420071/article/details/127215833