但行好事,莫问前程
阿里的测试开发面试难度较高。
PS:要求自行设计LinkedList数据结构,不要外部类库和辅助函数来处理。
LinkedList采用链表存储。
简单的模拟 ,小白写法,其他大佬有更完善的写法。
package DataTest; public class LinkedListTest { Node head; Node tail; public int counter = 0; class Node{ Node next; Integer val; public Node(Integer val){ this.val = val; } } public void add(Integer val){ if(head == null){ head = new Node(val); tail = head; counter++; }else{ Node node = new Node(val); tail.next = node; tail = tail.next; counter++; } } public void remove(int index){ if(head ==null) return; if(index>=counter||index<0){ System.out.println("数组越界"); return; } Node temp = head; int num = 0; // 删除首节点 if(index == 0){ head = head.next; return; } // 删除指定下标节点 while (temp.next != null){ if(num ==index-1){ // 删除尾巴节点 if(temp.next.next==null){ temp.next = null; counter--; return; }else{ temp.next = temp.next.next; counter--; return; } } num++; } } public static void main(String[] args) { LinkedListTest listTest = new LinkedListTest(); listTest.add(1); listTest.add(2); listTest.add(3); listTest.remove(2); listTest.remove(2); listTest.remove(3); } } //console //数组越界 //数组越界
每⼀个类都有⼀个对应它的类加载器。系统中的 ClassLoder 在协同⼯作的时候会默认使⽤ 双亲委派 模型 。即在类加载的时候,系统会⾸先判断当前类是否被加载过。已经被加载的类会直接返回,否则 才会尝试加载。加载的时候,⾸先会把该请求委派该⽗类加载器的 loadClass() 处理,因此所有的 请求最终都应该传送到顶层的启动类加载器 BootstrapClassLoader 中。当⽗类加载器⽆法处理 时,才由⾃⼰来处理。当⽗类加载器为null时,会使⽤启动类加载器 BootstrapClassLoader 作为 ⽗类加载器
双亲委派模型保证了Java程序的稳定运⾏,可以避免类的重复加载(JVM 区分不同类的⽅式不仅仅根据 类名,相同的类⽂件被不同的类加载器加载产⽣的是两个不同的类),也保证了 Java 的核⼼ API 不 被篡改。如果不⽤没有使⽤双亲委派模型,⽽是每个类加载器加载⾃⼰的话就会出现⼀些问题,⽐如我 们编写⼀个称为 java.lang.Object 类的话,那么程序运⾏的时候,系统就会出现多个不同的 Object 类。
为了避免双亲委托机制,我们可以⾃⼰定义⼀个类加载器,然后重载 loadClass() 即可。
除了 BootstrapClassLoader 其他类加载器均由 Java 实现且全部继承⾃ java.lang.ClassLoader 。如果我们要⾃定义⾃⼰的类加载器,很明显需要继承 ClassLoader
ConcurrentHashMap的size()
方法都是线程安全的,都是准确的计算出实际的数量,但是这个数据在并发场景下是随时都在变的。
ArrayBlockingQueue 是阻塞式的队列,底层以循环数组的形式保存数据。常用操作有 add、offer、put、remove、poll、take、peek。
它有边界,意味着要指定一个队列的大小。
先进先出。
// 入队 public boolean offer(E e) { checkNotNull(e); final ReentrantLock lock = this.lock; lock.lock(); try { if (count == items.length) return false; else { enqueue(e); return true; } } finally { lock.unlock(); } } public void put(E e) throws InterruptedException { checkNotNull(e); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == items.length) notFull.await(); enqueue(e); } finally { lock.unlock(); } } // 出队 public E poll() { final ReentrantLock lock = this.lock; lock.lock(); try { return (count == 0) ? null : dequeue(); } finally { lock.unlock(); } }
package DataTest; public class NumTest { public int numCollection(){ int[] nums = {1,2,3,4}; int res =0; for(int i =0;i<nums.length;i++){ for(int j = 0;j<nums.length;j++){ for(int z = 0;z<nums.length;z++){ if(i!=j&&i!=z&&j!=z){ System.out.println(nums[i]*100+nums[j]*10+nums[z]); res++; } } } } return res; } public static void main(String[] args) { NumTest numTest = new NumTest(); System.out.println(numTest.numCollection()); } }