A few days ago, a friend asked me some questions about back-end architecture before the interview, but I forgot about it because I was mostly engaged in mobile SDK development last year. I have no choice but to summarize it later.
Today’s topic is about finding a job. Job hunting is in every technical career have to go through many times, for most of us, before entering their favorite company, it is necessary to prepare, have a comprehensive and detailed interview questions will help us reduce a lot of trouble. Before job-hopping season comes, I specially do this series of articles, on the one hand to help myself to consolidate the foundation, on the other hand, I also hope to help friends who want to change jobs.
Since 2012, I have worked on crawler, search, machine learning,javaEE and Android successively, and the main tools are Java and C, so this series also focuses on these two aspects. Interested friends can follow: github.com/closedevice… .
In order to better establish the knowledge system, I attached relevant mind maps, which are divided into PDF version and Mindnote version. For example, the map related to Java is as follows:
Due to the haste of time, some places are not finished, will continue to supplement. If there is any problem, please contact me in time.
Relevant concepts
Three characteristics of object orientation
Encapsulation, inheritance, polymorphism. I think everyone knows that.
The benefits of polymorphism
Allow different classes of objects to respond to the same message, meaning that the same message can behave in many different ways depending on the sending object (sending a message is a function call). The main advantages are as follows:
- Replaceable: Polymorphism is replaceable for existing code.
- Extensibility: Adding new subclasses does not affect the existing class structure.
- Interface: Polymorphism is implemented through method signatures that provide a common interface for subclasses to complete or override.
- Flexibility:
- Simplify:
How is polymorphism implemented in code
There are three main ways to implement polymorphism: 1. Interface implementation 2. Method overloading in the same class
How are virtual machines polymorphic
Dynamic binding technology. During execution, the actual type of the referenced object is determined and the corresponding method is invoked according to the actual type.
Meaning of interfaces
The meaning of interfaces can be summed up in three words: specification, extension, and callback.
The meaning of abstract classes
The meaning of abstract classes can be summed up in three sentences:
- Provide a common type for other subclasses
- Encapsulate content that is repeatedly defined in subclasses
- Define abstract methods. Subclasses have different implementations but are defined consistently
The difference between interfaces and abstract classes
To compare | An abstract class | interface |
---|---|---|
The default method | Abstract classes can have default method implementations | Prior to Java 8, there were no implementations of methods in interfaces. |
implementation | Subclasses inherit abstract classes using the extends keyword. If the subclass is not abstract, the subclass needs to provide an implementation of the methods declared in the abstract class. | Subclasses implement interfaces using implements and need to provide implementations of all declarations in the interface. |
The constructor | An abstract class can have constructors, | The interface cannot |
Different from normal classes | Abstract classes cannot be instantiated | Interfaces are of an entirely different type |
Access modifier | Abstract methods can have public,protected, and default | The interface defaults to public and cannot use other modifiers |
Multiple inheritance | A subclass can have only one parent class | A subclass can have multiple interfaces |
Add a new method | If you want to add a new method to an abstract class, you can provide a default implementation, so you don’t have to modify the existing code of the subclass | If you add a new method to an interface, you need to implement that method in a subclass. |
Whether a static method of a parent class can be overridden by a subclass
Not. After a subclass inherits the parent class, have the same static method and the static, this is a static method to cover in the parent class method (namely rewriting), the static method of the parent is hidden (if the object is the parent class is called the hidden method), additional subclasses can integrated static and non-static methods of the parent class, as for the method overloading I think it is one of the elements in the same class, not at all Being able to say what methods are in a parent class and what methods are in a child class is a reflection of method overloading.
What is an immutable object
Immutable objects mean that once an object is created, its state cannot be changed. Any changes create a new object, such as String, Integer, and other wrapper classes.
Can I create an immutable object that contains a mutable object?
It is certainly possible to create an immutable object that contains a mutable object. You just need to be careful not to share references to mutable objects and return a copy of the original object if changes are needed. The most common example is when an object contains a reference to a date object.
Java creates objects in several ways
- Using the new
- By reflection
- The clone
- Through serialization mechanism
The first two need to explicitly call the constructor. The one that causes the most coupling happens to be the first, so you’ll find that any framework that involves decoupling has to reduce the use of new first.
Whether to use string as parameter in switch
Prior to IDK 1.7, the Switch could only support byte,short, CHAR,int or their corresponding encapsulated classes and Enum types. Since IDK 1.7, the Switch has supported String.
What are the public methods in Object?
equals()
clone()
getClass()
notify(),notifyAll(),wait()
Four references in Java
Strong reference, soft reference, weak reference, virtual reference. The different reference types are mainly reflected in GC:
- Strong references: If an object has strong references, it will not be collected by the garbage collector. Even if the current memory space is insufficient, the JVM does not reclaim it, but instead throws an OutOfMemoryError, causing the program to abort abnormally. If you want to break the association between a strong reference and an object, you can explicitly assign the reference to NULL so that the JVM can reclaim the object at the appropriate time
- Soft references: When a soft reference is used, if there is enough memory, the soft reference can continue to be used without being collected by the garbage collector, and only when there is insufficient memory, the soft reference is collected by the garbage collector.
- Weak references: Objects with weak references have a shorter lifetime. Because when the JVM does garbage collection, weak references are collected whenever they are found, regardless of whether there is currently sufficient memory space. However, because the garbage collector is a low-priority thread, it is not always possible to find weak reference objects quickly
- Virtual references: As the name implies, virtual references. If an object holds only virtual references, it has no references and can be collected by the garbage collector at any time.
See Digging into Object References for more information
What is the difference between WeakReference and SoftReference?
This is explained in the four reference types, but it can be explained briefly here: Although WeakReference and SoftReference are both beneficial to improving the efficiency of GC and memory, WeakReference will be recovered by GC once it loses the last strong reference, while SoftReference cannot prevent collection. But it can be deferred until the JVM runs out of memory.
Why different reference types
Unlike C, where we can control the allocation and release of memory, in Java we sometimes need to properly control when objects are reclaimed, hence the creation of different reference types, which can be said to be an uncontrollable compromise on GC reclaim timing. The following usage scenarios can be fully illustrated:
- Soft and Weak References solve OOM problems: Use a HashMap to store the mapping between the path of the image and the soft references associated with the corresponding image object. When memory runs out, the JVM automatically reclaims the space occupied by these cached image objects, effectively avoiding OOM problems.
- Caching Java objects with soft references: For example, if we created a Person class, we would have to rebuild an instance every time we needed to query a Person’s information, even if it had been queried only a few seconds earlier. This causes consumption of a large number of Person objects, and because these objects have a relatively short life cycle, multiple GCS affect performance. At this point, a combination of soft references and HashMap can be used to build a cache to provide performance.
= = and Javaeqauls()
The difference between,equals()
And ‘Hashcode
== is the operator that compares whether two variables are equal, and equals is the method of the Object class that compares whether two objects are equal. The default equals method of the Object class compares the addresses of two objects with the same result as ==. In other words: primitive types compare with ==, comparing their values. By default, when objects are compared with ==, they compare memory addresses. If you want to compare object contents, you need to override the equal method
equals()
andhashcode()
The link
HashCode () is a method of the Object class that returns a hash. If two objects are equal according to the equal() method, then calling the hashCode() method on either object must produce the same hash value. If two objects are not equal according to the eqaul() method, the resulting hash values are not necessarily equal (and will be equal in the case of collisions).
What does a.hash code () do? What does it have to do with A. als(b)
The hashCode() method is the hash value of the corresponding object’s integer. It is commonly used for hash-based collection classes such as Hashtable, HashMap, LinkedHashMap, and so on. It is particularly closely related to the equals() method. According to the Java specification, two objects that use the equal() method to determine equality must have the same Hashcode.
When an object is put into a collection, it first checks whether the hashcode to be put into the object already exists in the collection. If not, it is put into the collection directly. If hashCode is equal, then the equal() method determines whether the object to be put into is equal to any object in the collection: if equal() determines not equal, the element is put directly into the collection, otherwise not.
Is it possible that two objects that are not equal have the same Hashcode
It is possible that two objects that are not equal may have the same HashCode value, which is why there are conflicts in the HashMap. The rule for equal Hashcode values simply says that if two objects are equal, they must have the same Hashcode value, but there is nothing about unequal objects.
Can I use random numbers in HashCode?
No, because the hashCode values for the same object must be the same
What is the difference between “a==b” and a. quals(b)
If a and b are both objects, then a==b is a reference to compare two objects, and returns true only if a and B refer to the same object in the heap, while a.equals(b) is a logical comparison, so it is often necessary to override this method to provide a logically consistent comparison. For example, the String class overrides equals() so it can be used to compare two different objects that contain the same letters.
3 * 0.1 = = 0.3
What is the return value
False because some floating-point numbers cannot be represented exactly.
Is there any difference between a=a+b and a+=b?
Implicitly casts the result type of the add operation to the type that holds the result. If two integers are added, such as byte, short, or int, they are first promoted to int and then added. If the result of the addition operation is larger than the maximum value of a, a+b will generate a compilation error, but a+ = b is fine, as follows: byte a = 127; byte b = 127; b = a + b; // error : cannot convert from int to byte b += a; A +b raises a and B to int, so assigning an int to byte causes a compilation error.
The role of inner classes
An inner class can have multiple instances, each of which has its own state information and is independent of the information of other peripheral objects. Within a single enclosing class, you can have multiple inner classes implement the same interface in different ways, or inherit from the same class. The timing of creating an inner class object is independent of the creation of an outer class object. The inner class doesn’t have the puzzling “IS-A” relationship; it’s like a separate entity.
The inner class provides better encapsulation and is not accessible by any other class except the enclosing class
Differences between Final, Finalize and finally
Final is a modifier that modifies variables, methods, and classes. If final decorates a variable, it means that its value cannot be changed after initialization. Finalize method is a method called before objects are collected to give objects themselves the last chance to revive, but there is no guarantee when To call Finalize. Finally is a keyword that is used with try and catch for exception handling. A finally block must be executed regardless of whether an exception occurs in the try block.
What type of method is Clone ()?
Java.lang.Cloneable is an explicit interface that does not contain any methods. The Clone method is defined in the Object class. You also need to know that the Clone () method is a native method, which means it is implemented in C or C ++ or another native language.
What is the difference between a deep copy and a shallow copy?
Shallow copy: All variables of the copied object have the same values as the original object, and all references to other objects still refer to the original object. In other words, shallow copy copies only the object in question, not the object it references.
Deep copy: All variables of the copied object have the same values as the original object, and variables that refer to other objects refer to the copied object instead of the original referenced objects. In other words, the deep copy copies all the objects referenced by the object to be copied.
Data type correlation
How many bytes are int char and long in Java?
type | digits | The number of bytes |
---|---|---|
short | 2 | 16 |
int | 4 | 32 |
long | 8 | 64 |
float | 4 | 32 |
double | 8 | 64 |
char | 2 | 16 |
What is the length of an int in a 64-bit JVM?
In Java, the length of a variable of type int is a fixed value of 32 bits, regardless of the platform. In 32-bit and 64-bit Java virtual machines, the length of an int is the same.
Java int and Integer
An Integer is the wrapper type of an int that is automatically converted during unpacking and boxing. An int is a primitive type that holds a value directly, whereas an Integer is an object that is referred to by a reference.
Who takes up more memory, int or Integer?
Integer objects take up more memory. Integer is an object whose metadata needs to be stored. But int is a primitive type of data, so it takes up less space.
The difference between String,StringBuffer and StringBuilder
String is a String constant,final; StringBuffer String variable (thread-safe); StringBuilder String variable (thread unsafe).
String and StringBuffer
The main difference between a String and a StringBuffer is performance: A String is immutable, and every operation on a String creates a new String and points to the new String. So try not to do a lot of concatenation of strings, otherwise you will have a lot of temporary objects, causing the GC to start working and affecting system performance.
StringBuffer operates on the object itself, rather than generating new objects, so we recommend using StringBuffer in situations where there is usually a lot of concatenation.
But note that the JVM now optimizes String concatenation: String s= “This is only” + “simple” + “test” is optimized to String S = “This is only simple test” by the VM.
StringBuffer and StringBuilder
A StringBuffer is a thread-safe mutable string whose internal implementation is a mutable array. StringBuilder is new to Java 5.0 and is similar to StringBuffer, but not thread-safe. Therefore, using StringBuilder provides better performance without multithreading issues.
What are compiler constants? What are the risks of using it?
Public static final variables are compile-time constants, which are optional. These variables are actually replaced at compile time because the compiler knows their values and knows that they cannot be changed at run time. One problem with this approach is that you use a public compile-time constant from an internal or third-party library, but the value is later changed by someone else, but your client still uses the old value, even if you have deployed a new JAR. To avoid this, be sure to recompile your program when updating dependent JAR files.
What type of price is good in Java?
Use BigDecimal if you are not particularly concerned with memory and performance, otherwise use a double of predefined precision.
How to convert byte to String
The conversion can be done using the String constructor that accepts the byte[] argument. The important thing is to use the correct encoding, otherwise the platform default encoding will be used, which may or may not be the same as the original encoding.
Can int be forcibly converted to byte? What problems will arise?
We can do casts, but ints are 32 bits and byte is 8 bits in Java, so if we cast the higher 24 bits of ints, byte ranges from -128 will be discarded. To 128
About Garbage Collection
What garbage collection algorithms do you know?
Garbage collection is easy to understand in theory. The specific methods are as follows: 1. Mark – clean 2. Mark-copy 3. Mark-tidy 4. Generational Collection For more details, see understanding garbage collection algorithms in depth
How do you determine if an object should be reclaimed
This is the so-called object viability judgment, commonly used in two ways :1. Reference counting method; 2: Object reachability analysis. Due to the cross-reference problem with reference counting methods, object reachability analysis algorithms are commonly used by JVM VMS today.
A brief explanation of garbage collection
The most basic approach to Java garbage collection is generational collection. Regions in memory are divided into different generations, and objects are stored in regions of the corresponding generation according to how long they live. A typical implementation is divided into three generations: young, old, and permanent. Memory allocation occurs in the younger generation. When an object survives long enough, it is copied into the old generation. Different garbage collection algorithms can be used for different generations. The starting point of generation division is the statistical rule derived from the study of the life time of the object in application. In general, most objects in an application have a short lifetime. For example, local variables live only during the execution of the method. With this in mind, garbage collection algorithms can be tailored to the younger generation.
What happens when system.gc () is called?
The GC is told to start work, but the time when the GC actually starts is uncertain.
Process, thread dependent
Talk about the differences between processes, threads, and coroutines
In short, a process is the basic unit of program execution and resource allocation. A program has at least one process and a process has at least one thread. A process has a separate memory unit during execution, while multiple threads share memory resources, reducing the number of switches and making it more efficient. A thread is an entity of a process. It is the basic unit of CPU scheduling and dispatching. It is a basic unit smaller than a program that can run independently. Multiple threads in the same process can execute concurrently.
Do you know anything about daemons? How is it different from a non-daemon thread
When the program finishes running, the JVM waits for the non-daemon thread to complete and shut down, but the JVM does not wait for the daemon thread. The most typical example of a daemon thread is a GC thread
What is multithreaded context switching
Context switching in multithreading is the process of switching CPU control from one thread that is already running to another thread that is ready and waiting for CPU execution.
How to create two kinds of threads? What’s the difference?
By implementing java.lang.Runnable or by extending the java.lang.Thread class. Implementing the Runnable interface is probably better than extending Thread. There are two reasons:
- Java does not support multiple inheritance. Therefore, extending Thread means that the subclass cannot extend other classes. A class that implements the Runnable interface may extend another class.
- The class might just be required to be executable, so integrating the entire Thread class would be too expensive.
Difference between Runnable and Callable
The return value of the run() method in the Runnable interface is void, and all it does is execute the code in the run() method; The Call () method in the Callable interface, which returns a value, is a generic type that can be used in conjunction with Future and FutureTask to retrieve the result of asynchronous execution. And this is actually a very useful feature, because one of the big reasons that multithreading is more difficult and more complex than single threading is because multithreading is so unpredictable. Does a thread execute? How long did a thread execute? Is the expected data already assigned when a thread executes? We don’t know. All we can do is wait for the multithreaded task to finish. Callable+Future/FutureTask can retrieve the results of multiple threads. It can cancel the task if it waits too long to retrieve the required data, which is really useful.
What causes a thread to block
Blocking is the process of suspending the execution of a thread until a condition (such as a resource is ready) occurs, and those of you who have studied operating systems will be familiar with it. Java provides a number of ways to support blocking, so let’s take a look at each one.
methods | instructions |
---|---|
sleep() | Sleep () allows you to specify a period of time in milliseconds that causes the thread to block for a specified period of time and not get CPU time, after which the thread returns to the executable state. Typically, sleep() is used to wait for a resource to be ready: after the test finds that the condition is not met, the thread blocks for a while and then retests until the condition is met |
Suspend () and resume () | Suspend () is used in conjunction with suspend() to put a thread into a blocked state. It does not resume automatically and its corresponding resume() must be called before the thread can be put back into an executable state. Typically, suspend() and resume() are used to wait for a result from another thread: after a test finds that the result has not yet been produced, suspend the thread, and resume() is called after another thread has produced the result. |
yield() | Yield () causes a thread to give up its current allocation of CPU time, but does not cause it to block; that is, the thread is still in an executable state and could be allocated CPU time again at any time. The effect of calling yield() is equivalent to the scheduler thinking that the thread has executed for enough time to switch to another thread |
Wait () and notify () | Wait () allows a thread to block, either by specifying a period of time in milliseconds, or by taking no arguments. Wait () allows the thread to return to the executable state when notify() is called or when the specified amount of time has elapsed. The latter must be called with notify(). |
The difference between wait(),notify() and suspend(),resume()
At first glance, they look no different from the suspend() and resume() methods, but in fact they are very different. The crux of the difference is that none of the methods described above will release the locked lock (if any) when blocking, as opposed to the other way around. The core differences above lead to a series of detailed differences.
First, all of the methods described above belong to the Thread class, but this pair belongs directly to the Object class, which means that all objects have this pair of methods. This may seem strange at first, but it is actually quite natural because the pair of methods that block release the lock that is held by any object, and calling wait() on any object causes the thread to block and the lock on that object to be released. Calling the notify() method of any object causes one of the randomly selected threads blocked by calling the wait() method of that object to be unblocked (but not actually executed until the lock is acquired).
Second, all of the methods described above can be called from anywhere, but this pair of methods must be called from a synchronized method or block for the simple reason that it is only in a synchronized method or block that the current thread owns the lock and can release it. Similarly, the lock on the object calling this pair of methods must be owned by the current thread in order for any lock to be released. Therefore, the pair of method calls must be placed in such a synchronized method or block, whose locking object is the object calling the pair of methods. If they do not meet the conditions, the program, though still able to compile, but abnormal IllegalMonitorStateException at run time.
The above characteristics of wait() and notify() mean that they are often used with synchronized methods or blocks, and a comparison between them and the operating system’s interprocess communication mechanism reveals their similarities: Synchronized methods, or blocks, provide functionality similar to operating system primitives in that they execute without interference from multithreading, which is equivalent to block and wakeup primitives (both declared synchronized). Their combination enables us to implement a series of sophisticated inter-process communication algorithms (such as semaphore algorithms) on operating systems and to solve various complex inter-thread communication problems.
Wait () and notify() methods The threads that are unblocked by calling notify() are randomly selected from threads that are blocked by calling wait() on this object. It is impossible to predict which threads will be selected, so take special care in programming to avoid problems caused by this uncertainty.
There is a notifyAll() method that performs a similar function. The only difference is that a notifyAll() method unblocks all threads that are blocked by calling the wait() method. Of course, only the thread that acquired the lock can enter the executable state.
You can’t talk about blocking without talking about deadlocks, and a quick analysis shows that deadlocks can occur from calls to both the suspend() method and to wait() methods with no timeout period specified. Unfortunately, Java does not support deadlock avoidance at the language level, and we must be careful to avoid deadlocks in programming.
We’ve looked at the various methods for implementing thread blocking in Java, focusing on wait() and notify() because they are the most powerful and flexible to use, but this makes them less efficient and error-prone. In practice, we should use various methods flexibly in order to better achieve our goals.
Why are wait() and notify()/notifyAll() called in synchronous blocks
This is mandatory by the JDK; both wait() and notify()/notifyAll() must acquire the lock on the object before being called
What is the difference between wait() and notify()/notifyAll() when abandoning object monitors
The difference between wait() and notify()/notifyAll() is that wait() releases the object monitor immediately, while notify()/notifyAll() waits for the rest of the thread code to complete before abandoning the object monitor.
The difference between wait() and sleep(
Both of these have been described in detail above, and here is a summary:
- Sleep () comes from Thread, and wait() comes from Object. The thread does not release the object lock during the call to sleep(). Calling the wait thread releases the object lock
- Sleep () does not allocate system resources after sleep, and wait allows other threads to occupy the CPU
- Sleep (milliseconds) specifies how long it takes to sleep, and it wakes up automatically. Wait () is used with notify() or notifyAll()
The difference between synchronized and ReentrantLock
Synchronized is a keyword like if, else, for, and while. ReentrantLock is a class. This is the essential difference between synchronized and while. Since ReentrantLock is a class, it provides more flexible features than synchronized. It can be inherited, can have methods, and can have a variety of class variables. ReentrantLock has more extensibility than synchronized in several aspects: (1) ReentrantLock can set the waiting time for acquiring locks, so as to avoid deadlocks. (2) ReentrantLock can obtain various locks information. (3) ReentrantLock can flexibly implement multi-way notification. Unsafe Lock (ReentrantLock) refers to the Unsafe park method, whereas synchronized refers to the Mark Word object header.
What is FutureTask
This was actually mentioned earlier, FutureTask represents a task for asynchronous computation. FutureTask can pass in a concrete implementation class of Callable, which can wait for the result of the asynchronous operation, determine whether the task has been completed, and cancel the task. Of course, since FutureTask is also an implementation class of the Runnable interface, it can also be put into a thread pool.
What if a thread has a runtime exception?
If the exception is not caught, the thread stops executing. Another important point is that if this thread holds a monitor for an object, the object monitor is immediately released
How do I share data between two threads
This is done by sharing objects between threads, and then evoking and waiting with wait/notify/notifyAll, await/signal/signalAll. For example, BlockingQueue is designed to share data between threads
How to use wait() correctly? Use if or while?
The wait() method should be called in a loop, because other conditions may not have been met by the time the thread gets to the start of CPU execution, so it is better to loop to check if the conditions have been met before processing. Here is a standard code that uses wait and notify:
synchronized (obj) {
while (condition does not hold)
obj.wait(); // (Releases lock, and reacquires on wakeup)
. // Perform action appropriate to condition
}Copy the code
What are thread-local variables
Thread-local variables are variables that are limited within a thread and are owned by the thread itself and are not shared between multiple threads. Java provides a ThreadLocal class to support thread-local variables as a way to achieve thread-safety. However, be careful when using thread-local variables in a managed environment, such as a Web server, where the life of a worker thread is longer than the life of any application variable. Java applications run the risk of memory leaks if any thread-local variables are not released after work is done.
What does ThreadLoal do?
Simple said ThreadLocal is a kind of to the practice of trading space for time in each Thread maintains a ThreadLocal. ThreadLocalMap isolating data, data is not Shared, nature is no Thread safety issues.
What is the role of the producer-consumer model?
(1) through balancing the producer’s production capacity and consumer spending to improve the operation efficiency of the whole system, this is the most important function of producer-consumer model (2) decoupling, this is a function of producer-consumer model attached, decoupling means the connection between the producers and consumers, contact less is also alone and do not need to receive each other’s constraints
Write a producer-consumer queue
This can be done by blocking queues or by wait-notify.
Use blocking queues to do this
/ / consumer
public class Producer implements Runnable{
private final BlockingQueue<Integer> queue;
public Producer(BlockingQueue q){
this.queue=q;
}
@Override
public void run() {
try {
while (true){
Thread.sleep(1000);// The simulation takes timequeue.put(produce()); }}catch (InterruptedException e){
}
}
private int produce() {
int n=new Random().nextInt(10000);
System.out.println("Thread:" + Thread.currentThread().getId() + " produce:" + n);
returnn; }}/ / consumer
public class Consumer implements Runnable {
private final BlockingQueue<Integer> queue;
public Consumer(BlockingQueue q){
this.queue=q;
}
@Override
public void run() {
while (true) {try {
Thread.sleep(2000);// The simulation takes time
consume(queue.take());
}catch (InterruptedException e){
}
}
}
private void consume(Integer n) {
System.out.println("Thread:" + Thread.currentThread().getId() + " consume:"+ n); }}/ / test
public class Main {
public static void main(String[] args) {
BlockingQueue<Integer> queue=new ArrayBlockingQueue<Integer>(100);
Producer p=new Producer(queue);
Consumer c1=new Consumer(queue);
Consumer c2=new Consumer(queue);
new Thread(p).start();
new Thread(c1).start();
newThread(c2).start(); }}Copy the code
Use wait-notify to do this
This way should be the most classic, here do not explain
What is the concurrency of ConcurrentHashMap?
ConcurrentHashMap concurrency is the size of the segment. The default value is 16, which means that up to 16 threads can operate on ConcurrentHashMap at the same time. This is ConcurrentHashMap’s biggest advantage over Hashtable. Can two threads fetch data from a Hashtable at the same time?
CyclicBarrier is different from CountDownLatch
These two classes are very similar, both under java.util.concurrent and both can be used to indicate that the code is running at a point. The difference is that:
- Once a thread of a CyclicBarrier reaches a certain point, the thread stops running and does not restart until all threads have reached this point. CountDownLatch is not the case. When a thread gets to a certain point, it just gives a value of -1 and the thread keeps running
- CyclicBarrier can only evoke one task, and CountDownLatch can evoke multiple tasks
- CyclicBarrier is reusable, and CountDownLatch is not reusable. If the count is 0, the CountDownLatch is no longer available
Is the ++ operator in Java thread safe?
Not a thread-safe operation. It involves multiple instructions, such as reading variable values, incrementing them, and then storing them back into memory, which can have multiple threads crossing
What are your best practices for multithreaded development?
- Naming a thread
- Minimize synchronization range
- Use volatile in preference
- Use higher-level concurrency tools instead of wait and notify() for thread communication whenever possible, such as BlockingQueue,Semeaphore
- Use concurrent containers in preference to synchronous containers.
- Consider using thread pools
About the volatile keyword
Can Volatile arrays be created?
You can create volatile arrays in Java, but only a reference to the array, not the entire array. Changing the array to which the reference refers is protected by volatile, but not by volatile if multiple threads change the elements of the array simultaneously
Can volatile make a nonatomic operation atomic?
A typical example is having a member variable of type long in a class. If you know that the member variable will be accessed by multiple threads, such as counters, prices, etc., it is best to set it to volatile. Why is that? Because reading a long variable in Java is not atomic and requires two steps, if one thread is changing the value of the long variable, another thread may only see half of the value (the first 32 bits). But reading or writing to a volatile long or double is atomic.
One practice is to use volatile to modify long and double variables so that they can be read and written by atomic type. Double and long are both 64 bits wide, so reads of both types are split into two parts, first reading the first 32 bits and then reading the remaining 32 bits. This process is not atomic, In Java, however, volatile long or double variables are read and written atomically. Another use of volatile fixes is to provide memory barriers, as in distributed frameworks. In simple terms, the Java memory model inserts a write barrier before you write a volatile variable, and a read barrier before you read a volatile variable. This means that when you write a volatile field, you can ensure that any thread can see the value you write, and that any value changes are visible to all threads prior to writing, because the memory barrier updates all other written values to the cache.
What guarantees do volatile variables provide?
Volatile serves two main purposes: instruction reordering avoidance and visibility assurance. For example, the JVM or JIT will reorder statements for better performance, but volatile variables will not be reordered with other statements even if they are assigned without synchronized blocks. Volatile provides a happens-before guarantee that changes made by one thread are visible to other threads. Volatile can also provide atomicity in some cases, such as reading 64-bit data types, such as long and double, which are not atomic (low 32 bits and high 32 bits), but double and long, which are volatile, are atomic.
About the collection
Collections in Java and their inheritance relationships
Everyone should be familiar with the system of collection, especially the principle of List and Map that we often use. Here we can just look at this picture:
See the collection class summary for more
Poll () method and remove() method difference?
Poll () and remove() both fetch an element from the queue, but poll() returns null on failure to fetch an element, and remove() throws an exception on failure.
Differences between LinkedHashMap and PriorityQueue
PriorityQueue is a PriorityQueue that ensures that the highest or lowest priority element is always at the head of the queue, but the LinkedHashMap maintains the order in which the elements were inserted. There is no guaranteed order when traversing a PriorityQueue, but the LinkedHashMap class guarantees that the traversal order is the order in which the elements were inserted.
What is the difference between a WeakHashMap and a HashMap?
WeakHashMap works like a normal HashMap, but uses a weak reference as the key, meaning that the key/value is reclaimed when the key object has no reference.
What’s the difference between ArrayList and LinkedList?
The most obvious difference is that the underlying data structure of ArrrayList is an array, which supports random access, while the underlying data structure of LinkedList is a two-way circular LinkedList, which does not support random access. Using subscripts to access an element, the time complexity of ArrayList is O(1) and LinkedList is O(n).
Default sizes for ArrayList and HashMap?
In Java 7, the default size for ArrayList is 10 elements, and the default size for HashMap is 16 elements (which must be a power of 2). This is a snippet of the ArrayList and HashMap classes in Java 7
private static final int DEFAULT_CAPACITY = 10;
//from HashMap.java JDK 7
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16Copy the code
What’s the difference between Comparator and Comparable?
The Comparable interface is used to define the natural order of objects, while the Comparator is typically used to define user-customized orders. Comparable is always only one, but you can have more than one comparator to define the order of objects.
How to implement set sorting?
You can use ordered Collections, such as TreeSet or TreeMap, or you can use ordered Collections, such as list, and sort through collections.sort ().
How to print the contents of an array
You can print Arrays using the arrays.tostring () and arrays.deepToString () methods. Because Arrays don’t implement toString(), passing Arrays to system.out.println () won’t print out the contents of the array, but arrays.tostring () will print each element.
Is the LinkedList one-way or two-way?
Two-way circular list, specific implementation of their own access to the source code.
TreeMap is the implementation principle
Red black tree implementation, the implementation of their own access to the source code.
How do I properly remove an element while iterating through an ArrayList
The key to this question is whether the interviewer uses the remove() method of ArrayList or Iterator. Here’s a sample code, is to use the right way to realize in the process of traversing remove elements, and won’t appear abnormal ConcurrentModificationException sample code.
What is a ArrayMap? How is it different from HashMap?
ArrayMap is provided with the Android SDK and can be skipped by non-Android developers. ArrayMap uses two arrays to simulate a map, which takes up less memory and is more efficient. See this article for details :ArrayMap VS HashMap
Implementation principle of HashMap
1 HashMap Overview: A HashMap is an asynchronous implementation of the Hashtable-based Map interface. This implementation provides all optional mapping operations and allows null values and NULL keys. This class does not guarantee the order of the mapping, and in particular it does not guarantee that the order is constant. 2 Data structure of HashMap: In Java programming language, the most basic structure is two kinds, one is array, the other is analog pointer (reference), all data structures can be constructed with these two basic structures, HashMap is no exception. A HashMap is actually a “linked list hash” data structure, which is a combination of arrays and lists.
When we put an element into a Hashmap, we first recalculate the hash value based on the hashcode of the key. The hash value is calculated to the element’s location in the array (subscript). If the array already contains other elements at that location, the elements at that location are stored as a linked list, and the new elements are added in the header. The first one goes to the end of the chain. If there is no element at that location in the array, the element is placed directly at that location in the array.
Do you know anything about fail-fast
Fail-fast is a mechanism that allows you to Fail quickly
About the date
Is SimpleDateFormat thread-safe?
Unfortunately, all DateFormat implementations, including SimpleDateFormat, are not thread-safe, so you should not use them in multithreaded sequences unless they are used in an external thread-safe environment. For example, restrict SimpleDateFormat to ThreadLocal. If you don’t, you may get incorrect results when parsing or formatting dates. Therefore, I highly recommend the Joda-time library for all practices in date and time handling.
How do I format dates?
In Java, you can use the SimpleDateFormat class or the Joda-time library to format dates. The DateFormat class allows you to format dates in a variety of popular formats. See the sample code in the answer that demonstrates formatting dates into different formats, such as DD-MM-YYYY or ddMMyyyy.
About the abnormal
Briefly describes the Java exception architecture
More information about exception systems can be found in the vernacular exception mechanism
What is an exception chain
See the vernacular exception mechanism directly for details, without explanation.
Throws and throws
Throw is used to actively throw an instantiation of the java.lang.Throwable class. This means that you can throw an Error or an Exception using the keyword throw, as in: Throw new IllegalArgumentException(” size must be multiple of 2 “). As part of the method declaration and signature, throws an exception so that the caller can handle it. In Java, any unchecked checked exception is forced to be declared in the THROWS clause.
About serialization
The difference between Serializable and Externalizable in Java
Serializable interface Serializable interface is an interface that serializes Java classes so that they can be transferred over the network or their state can be stored on disk. It is the default serialization method embedded in the JVM and is expensive, fragile, and insecure. Externalizable allows you to control the entire serialization process, specify specific binary formats, and add security mechanisms.
On the JVM
The JVM features
Platform independence: A very important feature of the Java language is platform independence. The use of Java virtual machine is the key to achieve this feature. Normal high-level languages need to be compiled into at least different object code if they are to run on different platforms. With the introduction of the Java language VIRTUAL machine, the Java language does not need to be recompiled when running on different platforms. The Java Language Usage Pattern The Java Virtual machine shields platform-specific information, allowing Java language compilers to run on multiple platforms without modification, simply by generating object code (bytecode) that runs on the Java Virtual machine. When the Java virtual machine executes bytecodes, it interprets the bytecodes as machine instructions on a specific platform.
A quick explanation of class loaders
You will be asked about the application scenarios of the four types of classloaders and the parental delegation model. See understanding JVM loaders in depth for more information
Briefly describe the difference between a heap and a stack
The heap and stack belong to different areas of memory in the VM and are used for different purposes. Stacks are often used to hold method frames and local variables, while objects are always allocated on the heap. Stacks are typically smaller than the heap and are not shared between multiple threads, whereas the heap is shared by all threads across the entire JVM.
Describe JVM memory allocation
- Primitive data types are allocated on the stack rather than references to variables and objects
- Heap memory is used to hold objects and arrays created by new
- Class variables (static modified variables). The program allocates memory for class variables in the heap as soon as they are loaded. Memory addresses in the heap are stored on the stack
- Instance variables: When you use the keyword new Java system in the heap is not necessarily a continuous space is assigned to the variable, is based on scattered heap memory address, through the hash algorithm conversion as a long string of Numbers to represent the variable “physical location in the heap,” instance variable life cycle – after the instance variable reference lost, Puts the garbage collector on the recyclable “list”, but does not immediately free up memory in the heap
- Local variable: declared in a method or section of code (such as a for loop), which opens up memory on the stack when executed, and is freed as soon as the local variable is out of scope
other
Is Java big endian or small endian?
Several methods and characteristics of XML parsing
DOM,SAX,PULL three parsing methods:
- DOM: Memory consumption: Read all the XML documents into memory, then use the DOM API to access the tree structure and retrieve the data. This is easy to write, but it consumes memory. If the data is too large, the phone is not cool enough, the phone may directly crash
- SAX: High parsing efficiency, occupies less memory, based on event-driven: To put it more simply, the document is scanned sequentially. When the document begins and ends, the element begins and ends, and the document ends, the event handler is notified, and the event handler does the corresponding actions, and then the same scan continues until the document ends.
- PULL: Similar to SAX, it is event-driven, and we can call its next () method to get the next parsing event (that is, start document, end document, start tag, end tag), You can call XmlPullParser’s getAttributte() method to get the value of the attribute when you are on an element, or you can call its nextText() to get the value of the node.
The JDK 1.7 features
While JDK 1.7 is not as big as JDK 5 and 8, there are a number of new features, such as try-with-resource statements, that allow you to use streams or resources without having to manually close them. Fork-join pooling implements the Java version of Map-Reduce to some extent. Allow String variables and text in Switch. The diamond operator (\<>) is used for type inference and eliminates the need to declare generics on the right side of variable declarations, thus producing stronger, cleaner code that can be read and written
The JDK 1.8 features
Java 8 is a groundbreaking release in Java history. Here are five key features in JDK 8: Lambda expressions, which allow anonymous functions to be passed like objects through the Stream API, take full advantage of modern multicore cpus to write very concise code in the Date and Time API. Finally, there is a stable, simple Date and Time library that you can use to extend methods. Now, Interfaces can have static, default methods. Repeat annotations. Now you can use the same annotation multiple times on the same type.
What’s the difference between Maven and ANT?
While both are build tools for creating Java applications, Maven does more, providing a standard Java project structure based on the concept of convention over configuration while automatically managing dependencies (JAR files that the application depends on). See the answers for more differences between Maven and ANT tools. That’s all the interview questions, right? I can guarantee that if you can answer all the questions on this list, you can easily handle any core Java or advanced Java interview. Although servlets, JSP, JSF, JPA, JMS, EJB and other Java EE technologies are not covered here, and mainstream frameworks such as Spring MVC, Struts 2.0, Hibernate are not included. SOAP and RESTful Web Services are not included either, but this list is also useful for Java developers who are preparing for Java Web development positions, because all of the Java interviews, The initial questions are all about Java basics and JDK apis. If you think I have any popular Java issues that should be on this list and I’ve left them out, feel free to give me suggestions. My goal is to create an up-to-date list of the best Java interview questions from recent interviews.
JDBC Best Practices
- Batch operations are preferred for inserting and updating data
- Use preparedStatements to avoid SQL vulnerabilities
- Use data connection pooling
- Get the result set by column name
Best practices for IO operations
- Use buffered IO classes; do not read bytes or characters individually
- Use NIO and NIO 2 or AIO instead of BIO
- Close the flow in finally
- Use memory-mapped files for faster IO