Let’s talk about the interview process: The headhunter first contacted me and asked me whether I had the intention of going to netease for an interview. I agreed to do so in order to mix interview experience. Three days after the headhunter contacted me, netease arranged the first technical interview. The interview was conducted remotely and took an hour and a half. Let’s analyze the technical side of the content (I forgot some questions, here are the ones I have an impression of) :
Interviewer’s questions:
- What is the structure of an ArrayList? How to ensure efficient array expansion? What is the time complexity of ADD if you consider expansion?
- What is the structure of a HashMap? Is there any other structure for a HashMap besides arrays and linked lists?
- List
, List? Extend T>, Enum
What types of objects can be added to 1 and 2, and what types of objects can be retrieved?
- What native thread pools does Java have? What are the parameters passed to build these thread pools? What do these parameters do?
- How are classes loaded? How does ClassLoader work? Can a class be loaded by two different classloaders?
- Tell me about a big feature you’ve worked on recently.
Title explanation:
Netease technology one side of the test questions are not difficult, the comparison of the foundation and true. Mainly around the candidate’s basic knowledge of the direction to take an examination, there are not too many very partial difficult problems. If you want to answer these questions well and leave a good impression on the interviewer. Then you can not only answer the question itself when answering, to answer the depth and expand more knowledge points you are sure of, such as: say the principle of knowledge behind the question and design philosophy; Speak out their own experience and experience, I only do some knowledge background introduction to the question itself, you can think about when you face these questions, what kind of answer is to make yourself satisfied with the answer.
-
ArrayList (Interviewing old partners)
- The bottom layer uses arrays to store ordered data. Each time add determines whether the array length is sufficient. If the array length is insufficient, expand the capacity, and then insert data to the last bit of the current position. The remove process does not reduce the size of the data set. If there is any data following the remove location, it copies the data following the previous location and leaves the last location empty.
- Create an expanded array first, then use the System. Arraycopy method to shallow copy the data object, finally get the expanded array
- We can basically view each expansion as doubling the array size, so the time of add is log2
-
HashMap (Interview old partner)
- Structure: An array plus a linked list. The hash value of the key determines the position of the key-value pair in the array. If there is a duplicate position (collision), the position is stored as a linked list (or red-black tree).
- There is no other structure of the Map: tree + linked list form is also ok. In theory, as long as the key can be used to quickly locate the key-value pair in the structure, the tree structure is to search the key location in the tree to find the key-value pair.
-
Generics (Generics, together with class inheritance and interface implementation, can effectively expand the use of generics)
- List
: The element that can be added is T or an Object of T’s superclass (any element added can be directly converted to any superclass of T), and the extracted Object is of type Object. Meaning: Lits generics accept T, or objects that contain T in their parent class (if there is multiple inheritance, as long as the parent class chain contains T). List
is a generic designed to add data, and can only add elements of type T or its subclass type. The following code makes this easier to understand.
class Car {} class Bus extends Car {} void genSuperTest(a) { List<? super Car> carList = new ArrayList<>(); List<? super Bus> busList = new ArrayList<>(); fatherList.add(new Car()); // The compiler passes fatherList.add(new Bus()); // Add a List sonList.add(new Car()); // compilation error - Car cannot be converted to Bus object sonList.add(new Bus()); // The compiler passes } void test(List<? super Bus> list) { Object obj = list.get(0); // The compiler passes, notice that the Object is erased as Object } Copy the code
- List
: can’t add objects to this list, here why can’t add objects ———— list
such that any element in the queue is A subclass of T, that is, there cannot be both A and B (both are subclasses of T). And the object type is T. List
is a generic type designed to read data and of type T.
private static void genExtendTest(a) { List<? extends Car> fatherList = new ArrayList<>(); List<? extends Bus> sonList = new ArrayList<>(); fatherList.add(new Car()); List add object fatherList.add(new Bus()); List add object sonList.add(new Car()); List add object sonList.add(new Bus()); List add object } private static void test(List<? extends Bus> list) { Bus bus = list.get(0); // The object is Bus } Copy the code
About the List
and List
For more information: blog.csdn.net/qq_33591903…- About the Enum < E the extend Enum > : segmentfault.com/a/119000003…
- List
-
Java native thread pool (the following four primary thread pool) : at first I understand Java native thread pool is Java. Util. Concurrent. The Executors of several public static method to generate the thread pool. So I will briefly describe the contents of the thread pool (brief introduction and purpose) :
FixedThreadPool
: a thread pool with a fixed number of threads. The number of threads in the pool does not exceed the specified number of threads. Maximum length of a task queue: integer. MAX_VALUE (avoid OOM). The implementation classes are:ThreadPoolExecutor
;SingleThreadExecutor
: a single-threaded thread pool in which at most one thread can exist. Maximum length of a task queue: integer. MAX_VALUE (avoid OOM). The implementation classes are:ThreadPoolExecutor
;CachedThreadPool
: Thread pool for cacheable threads. If the thread pool is idle, idle threads are reclaimed according to a certain policy (the lifetime of idle threads is 60 seconds). When there are no free threads in the thread pool, it creates a new thread to perform the new task (it does not queue up the task for execution). The implementation classes are:ThreadPoolExecutor
;ScheduledThreadPoolExecutor
: Supports thread pools for scheduled and periodic tasks. The number of threads in the thread pool does not exceed the number of threads specified by the user. The implementation classes are:ScheduledThreadPoolExecutor
;
These were the main answers I gave during the interview to questions about what native thread pools Java has. But when I looked back after the interview, I realized that my answer might not have been what the interviewer was looking for. These thread pools are all ThreadPoolExecutor, just different strategies. FixedThreadPool; SingleThreadExecutor; CachedThreadPool works the same way for thread creation and task execution. If you think more deeply, I think the answer is ForkJoinPool. ScheduledExecutorService; ThreadPoolExecutor would make more sense. Here is an introduction to the three thread pool implementation classes:
ForkJoinPool
: This thread pool is implemented by splitting large tasks into smaller tasks (fork process), and then summarizing the results of small tasks to get the final result (join process). The idea of divide and conquer, providing a thread pool to solve large-scale computing problems;ScheduledExecutorService
: This thread pool is inThreadPoolExecutor
On the basis of, added the scheduled task and periodic task execution function;ThreadPoolExecutor
: common thread pool;
Java native thread pool interface, class implementation inheritance diagram:
On the thread pool to recommend an article: tech.meituan.com/2020/04/02/… Provides a thorough and systematic explanation of thread pools.
- Class loading (the flow of the code you write into the JVM) :
- How classes are loaded:
- Compilation: first, the compiler compiles the source files (usually xxx.java files) into.class files, which are completed in the compiler.
- Loading: Loading the. Class file into memory, done in the JVM;
- Validation: Verifies that the loaded.class file conforms to the vm specification (this step is also done by a normal compiler, but the vm must be correct). This is done in the JVM.
- Preparation: Allocating memory (space occupied by static variables, etc.) for the class, done in the JVM;
- Parsing: Parsing class, method, field name references (called by reference when a method is called) in the JVM;
- Initialization: Static variable assignment, static module execution, done in the JVM;
- How ClassLoader works: Here I use the source code to explain:
protectedClass<? > loadClass(String className,boolean resolve) throwsClassNotFoundException { Class<? > clazz = findLoadedClass(className);// 1. Check whether the ClassLoader has loaded the class if (clazz == null) { ClassNotFoundException suppressed = null; try { clazz = parent.loadClass(className, false); // 2. Delegate your own parent loader to load } catch (ClassNotFoundException e) { suppressed = e; } if (clazz == null) { try { clazz = findClass(className); // 3. If the parent loader is not loaded, load it by yourself } catch (ClassNotFoundException e) { e.addSuppressed(suppressed); throwe; }}}return clazz; } Copy the code
- Can a class be loaded by two different classloaders? The answer is yes. When determining whether two classes are identical, the JVM determines not only whether they have the same class name, but also whether they were loaded by the same ClassLoader instance (a ClassLoader object). The JVM considers two classes to be the same only if they both satisfy.
This is the validation code (need to use third-party packages: com. Itranswarp: the compiler: 1.0) :
public class ClassLoaderTest { static final String JAVA_SOURCE_CODE = "package com.test; public class Test {}"; @Test public void test(a) throws Exception { JavaStringCompiler compiler = new JavaStringCompiler(); // Parse the source code into a binary stream for ClassLoader loading (the same source code, the binary stream is the same) Map<String, byte[]> results = compiler.compile("Test.java", JAVA_SOURCE_CODE); // Custom classLoader loads the classClass<? > clazz = compiler.loadClass("com.test.Test", results); JavaStringCompiler compiler1 = new JavaStringCompiler(); Clazz and clazz1 are loaded by different ClassLoader objectsClass<? > clazz1 = compiler1.loadClass("com.test.Test", results); assertNotEquals(clazz, clazz1); assertNotEquals(clazz.newInstance().getClass(), clazz1.newInstance().getClass()); }}Copy the code
- How classes are loaded:
- According to their own actual situation. It is recommended not to be opportunistic and say that the function you did not participate in is completed by yourself.
Personal Summary:
This interview is relatively smooth, the topic difficulty is relatively low but the interviewer likes to dig, there are a few times even asked very partial source code implementation. Because the epidemic is not completely over, remote methods are used. Two personal tips for job interviews:
- If you want to succeed in an interview with a top company in the industry, the best advice I can give is: your level must reach the level of the company, now the interview level is not a few years ago, it is difficult to pass without real ability.
- The cliche — EVEN if you’re not looking to change jobs, I recommend going to a couple of interviews a year to help you stay alert. It’s easy to forget the cruelty of the Internet after working in a stable company for too long. Interviewing, especially with a large company, is one of the cheapest and most profitable ways I can think of to stay alert.
One final quip: Remote interviews are really awkward.