赞
踩
堆的分区
标记-清除算法
标记-复制算法
标记-整理算法
参考: link
参考: link
key计算hashcode后需要和数组长度进行位与运算,可以保证数组元素均匀分布
当两个线程同时设置数组元素,恰好key发生哈希碰撞,就会出现value相互覆盖
参考: link
class Buffer { private final Lock lock; private final Condition notFull; private final Condition notEmpty; private int maxSize; private List<Date> storage; Buffer(int size){ //使用锁lock,并且创建两个condition,相当于两个阻塞队列 lock=new ReentrantLock(); notFull=lock.newCondition(); notEmpty=lock.newCondition(); maxSize=size; storage=new LinkedList<>(); } public void put() { lock.lock(); try { while (storage.size() ==maxSize ){//如果队列满了 System.out.print(Thread.currentThread().getName()+": wait \n");; notFull.await();//阻塞生产线程 } storage.add(new Date()); System.out.print(Thread.currentThread().getName()+": put:"+storage.size()+ "\n"); Thread.sleep(5000); notEmpty.signalAll();//唤醒消费线程 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ lock.unlock(); } } public void take() { lock.lock(); try { while (storage.size() ==0 ){//如果队列满了 System.out.print(Thread.currentThread().getName()+": wait \n");; notEmpty.await();//阻塞消费线程 } System.out.print(Thread.currentThread().getName()+": take:"+storage.size()+ "\n"); Date d=((LinkedList<Date>)storage).poll(); Thread.sleep(5000); notFull.signalAll();//唤醒生产线程 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ lock.unlock(); } } } class Producer implements Runnable{ private Buffer buffer; Producer(Buffer b){ buffer=b; } @Override public void run() { while(true){ buffer.put(); } } } class Consumer implements Runnable{ private Buffer buffer; Consumer(Buffer b){ buffer=b; } @Override public void run() { while(true){ buffer.take(); } } } public class Main { public static void main(String[] arg){ Buffer buffer=new Buffer(10); Producer producer=new Producer(buffer); Consumer consumer=new Consumer(buffer); for(int i=0;i<3;i++){ new Thread(producer,"producer-"+i).start(); } for(int i=0;i<3;i++){ new Thread(consumer,"consumer-"+i).start(); } } }
参考: link
参考: link
public class MergeSortTest { public static void main(String[] args) { //测试数据 int A[] = { 1, 6, 4, 5, 2, 9, 7, 23, 56, 43, 99 }; // 排序前 System.out.println("排序前:"); for (int a : A) { System.out.print(a + " "); } System.out.println(); // 排序 mergeSort(A); // 排序后 System.out.println("排序后:"); for (int a : A) { System.out.print(a + " "); } System.out.println(); } // 排序入口 public static void mergeSort(int[] A) { sort(A, 0, A.length - 1); } //递归 public static void sort(int[] A, int start, int end) { if (start >= end) return; // 找出中间索引 int mid = (start + end) / 2; // 对左边数组进行递归 sort(A, start, mid); // 对右边数组进行递归 sort(A, mid + 1, end); // 合并 merge(A, start, mid, end); } // 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序 public static void merge(int[] A, int start, int mid, int end) { int[] temp = new int[A.length];// 临时数组 int k = 0; int i = start; int j = mid + 1; while (i <= mid && j <= end) { // 从两个数组中取出较小的放入临时数组 if (A[i] <= A[j]) { temp[k++] = A[i++]; } else { temp[k++] = A[j++]; } } // 剩余部分依次放入临时数组(实际上两个while只会执行其中一个) while (i <= mid) { temp[k++] = A[i++]; } while (j <= end) { temp[k++] = A[j++]; } // 将临时数组中的内容拷贝回原数组中 (left-right范围的内容) for (int m = 0; m < k; m++) { A[m + start] = temp[m]; } } }
int binarysearch(int array[], int low, int high, int target) {
if (low > high) return -1;
int mid = low + (high - low) / 2;
if (array[mid] > target)
return binarysearch(array, low, mid - 1, target);
if (array[mid] < target)
return binarysearch(array, mid + 1, high, target);
return mid;
}
// 前序遍历
public void preOrderTraverse1(TreeNode root) {
if (root != null) {
System.out.print(root.val + "->");
preOrderTraverse1(root.left);
preOrderTraverse1(root.right);
}
}
public class LRUCache<K, V> {
private Map<K, V> map;
private final int cacheSize;
public LRUCache(int initialCapacity) {
map = new LinkedHashMap<K, V>(initialCapacity, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > cacheSize;
}
};
this.cacheSize = initialCapacity;
}
}
public class Singleton { private volatile static Singleton singleton; public static Singleton getSingleton() { if (singleton == null) { // 这里方法是static的,所以synchronized不能锁住this对象 // 只能锁住class对象 synchronized (Singleton.class) { if (singleton == null) { /** * 这就是为什么要家volatile关键字原因 * 1 防止对象没有初始化完成,其他线程使用未初始化的对象 * 2 相当于是禁止了指令重排 * */ singleton = new Singleton(); } } } return singleton; } }
参考: link
参考: link
参考: link
参考: link
为什么重写equals方法,就要重写hashCode方法
先看看object默认的equals方法
public boolean equals(Object obj) {
return (this == obj);
}
默认的equals直接比较的是内存地址,我们想要的效果是类的某些属性相等,这样就需要重写equals方法
在hashmap中对象作为key,equals返回ture,hashcode方法也需要返回相同的值,这样才可以找到map正确的位置
final, finally, finalize的区别。
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集 时的其他资源回收,例如关闭文件等
mybatis原理
feign超时时间设置
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。