Data integration and answers of the latest Java collection interview questions of major factories in 2022

Posted by Beatnik on Fri, 04 Feb 2022 05:27:17 +0100

Question 1: What are the differences between Iterator and Enumeration interfaces?

The version of traversing the interface of jdmap1 and ArrayList.2 is supported. Iterator supports the fail fast mechanism. When multiple threads operate on the contents of the same collection, a fail fast event may be generated.

The Iterator has three method interfaces. The Iterator can read the set data and delete the data, while the Enumeration has only two method interfaces. The Enumeration can only read the set data without modifying the data.

The processing performance of the Enumeration interface is twice that of the iterator and the memory usage is less. However, the iterator interface is much safer than the Enumeration interface, mainly because other threads cannot modify the objects in the collection being traversed by the iterator. At the same time, iterator allows the caller to delete the elements in the underlying collection, which is impossible for the Enumeration interface.

Iterators replace Enumeration in the Java collection framework. Iterators allow callers to remove elements from the collection, whereas Enumeration cannot.

Enumeration is an interface added in JDK version 1.0. The method interface of enumeration provides traversal interfaces for classes such as Vector and Hashtable. The enumeration itself does not support synchronization, but synchronization is added when the Vector and Hashtable implement enumeration.

Question 2: What are the differences and connections between Vector and ArrayList?

Similarities:

1) The implementation principle is the same, and the bottom layer uses array.

2) The functions are the same, and the methods of adding, deleting, modifying and querying are similar.

3) Are variable length array structures, which can be used with each other in many cases.

difference:

1) Vector is provided by earlier JDK versions, and ArrayList is a new version to replace vector.

2) Vector thread safety, ArrayList heavy speed light safety, thread non safety.

When the length needs to be increased, the Vector is doubled by default and the ArrayList is increased by 50%.

Question 3: How to judge the "java.util.LinkedList" string in Java to implement the List interface?

Format: judge whether a class implements an interface

if(Object name instanceof Interface name){
 
}

Example: judge the "java.util.LinkedList" string to implement the List interface

String classes = "java.util.LinkedList";

if(Class.forName(classes).newInstance() instanceof List) {
	System.out.println(true);
}else {
	System.out.println(false);
}

Question 4: What are the usage scenarios for generics?

When the reference data type to be operated in the class is uncertain, in jdk1 Before version 5, use Object to complete the extension, jdk1 After 5, it is recommended to use generics to complete the extension and ensure security at the same time.

Question 5: How to create and traverse a single linked list in Java?

public class LinkList {
	public Node head;
	public Node current;

	//Method: add data to the linked list  
	public void add(int data) {
		// Judge whether the linked list is empty
		if (head == null) {// If the head node is empty, it means that the linked list has not been created, then assign the new node to the head node
			head = new Node(data);
			current = head;
		} else {
			// Create a new node and put it behind the current node (associate the new node with the linked list)
			current.next = new Node(data);
			// Move the current index of the linked list backward one bit
			current = current.next; // After this step is completed, the current node points to the newly added node
		}
	}

	//Method: traverse the linked list (print out the linked list). The parameter of the method means to traverse from node node  
	public void print(Node node) {
		if (node == null) {
			return;
		}

		current = node;
		while (current != null) {
			System.out.println(current.data);
			current = current.next;
		}
	}

	class Node {
		//Note: the permissions of the two member variables here cannot be private, because the permission of private is only for this class.  
		int data; // Data domain
		Node next;// Pointer field

		public Node(int data) {
			this.data = data;
		}
	}

	public static void main(String[] args) {
		LinkList list = new LinkList();
		//Add data to LinkList  
		for (int i = 0; i < 10; i++) {
			list.add(i);
		}

		list.print(list.head);// Traverse the output from the head node
	}

}

results of enforcement

0
1
2
3
4
5
6
7
8
9

Looking at the above code, the Node node is represented by an internal class. The biggest advantage of using internal classes is that they can access each other for private operations with external classes.

The characteristics of internal class access are: internal classes can directly access the members of external classes, including private classes; An object must be created before an external class can access members of an internal class.

To facilitate the operation of adding and traversing, add a member variable current in the LinkList class to represent the index of the current node.

In the method of traversing the linked list, the parameter node indicates that the traversal starts from the node node, not necessarily from the head node.

Question 6: JDK1. What are the optimizations for HashMap and ConcurrentHashMap in 8?

JDK1. Before 8, its data structure was array and linked list. JDK1. After the optimization, the data structure becomes array + linked list + red black tree

When there are too many nodes in the linked list, query a node in jdk1 Before 8, you need to traverse the whole node with an efficiency of O(n). And in jdk1 8, if the node reaches the threshold treeify_ When threshold (the default value is 8), the linked list structure will be transformed into a red black tree structure. In this way, if the first node of the array is a tree structure, the tree query algorithm will be adopted, and the efficiency is O(logn). Otherwise, the linked list will be traversed. See jdk1 8 source code

When there are too many nodes in the tree, the threshold is UNTREEIFY_THRESHOLD (6 by default) will perform tree to linked list operation. As for why it is not 8, it is to prevent ordinary tree linked list conversion.

final Node<K,V> getNode(int hash, Object key) {
    Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
    if ((tab = table) != null && (n = tab.length) > 0 &&
        (first = tab[(n - 1) & hash]) != null) {
        if (first.hash == hash && // always check first node
            ((k = first.key) == key || (key != null && key.equals(k))))
            return first;
        if ((e = first.next) != null) {
            // The first node is the red black tree
            if (first instanceof TreeNode)
                return ((TreeNode<K,V>)first).getTreeNode(hash, key);
            // Otherwise, traverse the linked list
            do {
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    return e;
            } while ((e = e.next) != null);
        }
    }
    return null;
}

2,JDK1. Before 8, ConcurrentHashMap divided the whole Map into N (16 by default) segments, and the segments inherited from ReentrantLock, and realized thread safety by locking each Segment. And in jdk1 After 8, we abandoned this implementation method and adopted CAS + Synchronized to lock the chain header node to achieve thread safety. Refer to jdk1 8 source code

final V putVal(K key, V value, boolean onlyIfAbsent) {
    if (key == null || value == null) throw new NullPointerException();
    int hash = spread(key.hashCode());
    int binCount = 0;
    for (Node<K,V>[] tab = table;;) {
        Node<K,V> f; int n, i, fh;
        if (tab == null || (n = tab.length) == 0)
            tab = initTable();
        else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
            if (casTabAt(tab, i, null,
                         new Node<K,V>(hash, key, value, null)))
                break;                   // no lock when adding to empty bin
        }
        else if ((fh = f.hash) == MOVED)
            tab = helpTransfer(tab, f);
        else {
            V oldVal = null;
            // Here f is the head node of the linked list
            synchronized (f) {
                if (tabAt(tab, i) == f) {
                    if (fh >= 0) {
                        binCount = 1;
                        for (Node<K,V> e = f;; ++binCount) {
                            K ek;
                            if (e.hash == hash &&
                                ((ek = e.key) == key ||
                                 (ek != null && key.equals(ek)))) {
                                oldVal = e.val;
                                if (!onlyIfAbsent)
                                    e.val = value;
                                break;
                            }
                            Node<K,V> pred = e;
                            if ((e = e.next) == null) {
                                pred.next = new Node<K,V>(hash, key,
                                                          value, null);
                                break;
                            }
                        }
                    }
                    else if (f instanceof TreeBin) {
                        Node<K,V> p;
                        binCount = 2;
                        if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
                                                       value)) != null) {
                            oldVal = p.val;
                            if (!onlyIfAbsent)
                                p.val = value;
                        }
                    }
                }
            }
            if (binCount != 0) {
                if (binCount >= TREEIFY_THRESHOLD)
                    treeifyBin(tab, i);
                if (oldVal != null)
                    return oldVal;
                break;
            }
        }
    }
    addCount(1L, binCount);
    return null;
}

Question 7: Can I use generics in Java arrays?

Array does not support generics because it causes type safety problems at compile time.

When Java templates stay in the compilation layer, the information of these templates will be erased. This approach in Java does not need to modify the JVM, which reduces the risk of potential significant changes, but it may reflect the inherent deficiencies of Java Bytecode specification at the beginning of design.

In Java, the Object [] array can be the parent class of any array, or any array can be transformed upward into an array of the parent class of the element type specified by it at the time of definition. If the storage is different from the original data type but meets the later use of the parent type, there will be no problem in compiling, but the type of the Object added to the array will be checked at run time, An ArrayStoreException is thrown.

For example, the following code will throw an ArrayStoreException.

String[] arrays = new String[20];
Object[] obj = arrays;
obj[0] = new Integer(1); // throws ArrayStoreException at runtime

Note that List can provide type safety assurance at compile time, while Array cannot.

Question 8: What are the ways to traverse the List collection in Java?

List<String> list = new ArrayList<>();

for (int i = 0; i < list.size(); i++) {
	System.out.println(list.get(i));
}

//Using a for each loop
for(String obj : list){
	System.out.println(obj);
}

//Using iterator iterator
Iterator<String> it = list.iterator();
while(it.hasNext()){
  String obj = it.next();
  System.out.println(obj);
}

When traversing the List collection, the iterator method is used for thread safety, which can ensure that the traversed collection elements are not modified. Otherwise, an exception ConcurrentModificationException will be thrown.

Question 9: How to avoid concurrent modificationexception for iterative collections in Java?

When traversing a collection, you can use the concurrent collection class to avoid the ConcurrentModificationException exception.

For example, use the CopyOnWriteArrayList collection instead of the ArrayList collection.

Question 10: Why is the HashMap length to the power of 2?

The default length of HashMap is 16, and the expansion is to the nth power of 2.

In order to access HashMap efficiently, it is necessary to minimize collisions. Generally speaking, it is necessary to distribute the data evenly as much as possible. The length of each linked list is roughly the same. This implementation is an algorithm to store the data in which linked list.

Modulus taking is hash%length. The efficiency of direct remainder in the computer is not as good as that of displacement operation. The JDK source code has made corresponding optimization hash & (length-1). The premise of hash%length = = hash & (length-1) is that length is the nth power of 2;

For example, 10% 8 = 2,10 binary is 1010, and 8 binary is 0100

0000 1010
0000 1000

This remainder operation corresponds to the power of 2, which is actually the value of the divisor. The data before is divided, and the remainder after is the value with the remainder of the divisor being 1.

Divide 0000 1010 by 0000 1000 and erase the high position of 0000 1000 and yourself, leaving 0000 0010. The operation of and (&) is to take n (divisor) - 1 and the divisor, and the result of remainder "(n-1) & hash".

Why can this be evenly distributed to reduce collisions?

The N-power real of 2 is 1, followed by N zeros, and the n-power-1 of 2 is n ones;

For example, when the length is 9, 3 & (9-1) = 0, 2 & (9-1) = 0, all on 0, collide;

For example, when the length is 8, 3 & (8-1) = 3 2 & (8-1) = 2. There is no collision at different positions.

In fact, when "and" by bit, each bit can &1, that is, and 1111... 1111111.

The range of Hash values is - 2147483648 to 2147483647, which adds up to about 4 billion mapping space. As long as the Hash function is mapped evenly and loosely, it is difficult to collide in general applications. But the problem is that memory can't store this kind of quantity level array, so this Hash value can't be used directly. Modular operation can be performed for the length of the array, and the remainder can be used for the location to be stored, that is, the corresponding array subscript. The subscript of this array is calculated as "(n-1) & Hash". This explains why the length of HashMap is to the power of 2.

Question 11: how to ensure that a set cannot be modified in java -

Question 12: how to find intermediate nodes in a single linked list in java

Question 13: hashmap - why does multithreading lead to dead loops

Question 14: how to merge two ordered single linked lists in java

Question 15: jdk1 8 - and - jdk1 What is the initial capacity of 7-medium-arraylist

Question 16: what is java iterator iterator

Question 17: what are the differences between iterator and listiterator

Question 18: what are the root interfaces in the java collection

Question 19: what is hashmap

Question 20: talk about the use and principle of hashset

Question 21: what is the meaning of -etkv and other markers in java generics

Question 22: what is the difference between comparable - and - comparator

Question 23: find the number of nodes in the single linked list in java

Question 24: arrays Aslist () - what are the restrictions

Question 25: why does the - map interface not inherit the - collection interface


Topics: Java Interview