外部排序
如何排序10G个元素 (扩展的归并排序)
将数据分为左右两半,分别归并排序,再把两个有序数据归并。
[1,3,6,7],[1,2,3,5] 1
[3,6,7],[1,2,3,5] 1
[3,6,7],[2,3,5] 2
- push(2);push(1);push(3);push(4)
- pop() == 1
- 当某路数字拿完了,再去外部存储中拿缓冲区大小的数据。
归并使用Iterable接口
- 可以不断获取下一个元素的能力
- 元素存储/获取方式被抽象,与归并节点无关
归并数据来自Iterable.next()
- 如果缓冲区空,读取下一批元素放入缓冲区
- 给出缓冲区第一个元素
- 可配置 缓冲区大小,如何读取下一批元素
多线程死锁分析
- 在任何地方都可以线程切换
- 尽力设想对自己最不利的情况
- synchronized(from) -> 别的线程在等待from
- synchronized(to) -> 别的线程已经锁住了to
- 可能死锁:transfer(a,b,100) 和 transfer(b,a,100) 同时进行
死锁条件必须同时满足
- 互斥等待 -》 一般无法破除
- hold and wait -》一次性获取所有资源 (先获取from锁,马上获取to锁,获取不到就释放from锁)
- 循环等待 -》按顺序获取资源 (比如让id小的用户先拿锁)
- 无法剥夺的等待 -》加入超时
线程池
google beautifu num问题 — 解决大数据换算
思路:
N->r进制->1111…(k个)
N=r^(k-1)
+r^(k-2)
+…+r+1
k=64…2
public static void main(String[] args) {
Scanner in = new Scanner(
new BufferedReader(new InputStreamReader(System.in))
);
int cases = in.nextInt();
for (int i = 1; i <= cases; ++i) {
long n = in.nextLong();
System.out.println("Case #" + i + ": "
+ beautiful(n));
}
}
private static long beautiful(long n) {
for (int bits = 64; bits >= 2; bits--) {
long radix = getRadix(n, bits);
if (radix != -1) {
return radix;
}
}
throw new IllegalStateException("Should not reach here.");
}
/**
* Gets radix so that n is 111...1 (bits 1 in total) in that
* radix.
*
* @return the radix. -1 if there's no such radix.
*/
private static long getRadix(long n, int bits) {
long minRadix = 2;
long maxRadix = n;
while (minRadix < maxRadix) {
long m = minRadix + (maxRadix - minRadix) / 2;
long t = convert(m, bits);
if (t == n) {
return m;
} else if (t < n) {
minRadix = m + 1;
} else {
maxRadix = m;
}
}
return -1;
}
/**
* Returns the value of 111...1 (bits 1 in total) in radix.
*/
private static long convert(long radix, int bits) {
long component = 1;
long sum = 0;
for (int i = 0; i < bits; i++) {
if (Long.MAX_VALUE - sum < component) {
sum = Long.MAX_VALUE;
} else {
sum += component;
}
if (Long.MAX_VALUE / component < radix) {
component = Long.MAX_VALUE;
} else {
component *= radix;
}
}
return sum;
}