Java实现:在N个乱序的数组中找第K大的数
思想:维护一个k大小的最小堆,对于数组中的每一个元素判断与堆顶的大小,若堆顶较大,则不管,否则,弹出堆顶,将当前值插入到堆中。时间复杂度O(n * logk)。
思想:利用快速排序的思想,从数组S中随机找出一个元素X,把数组分为两部分Sa和Sb。Sa中的元素大于等于X,Sb中元素小于X。这时有两种情况:
1. Sa中元素的个数小于k,则Sb中的第k-|Sa|个元素即为第k大数;
2. Sa中元素的个数大于等于k,则返回Sa中的第k大数。
public class disorderSearchBin {
public static int quickSortOneTime(int[] array, int low, int high){ //一趟快速排序
int key = array[low];
while(low < high){
while(key < array[high] && low < high) high--;
array[low] = array[high];
while(key > array[low] && low < high) low++;
array[high] = array[low];
}
array[high] = key;
return high;
}
public static int Select_k(int[] array, int low, int high, int k) {
int index;
if(low == high) return array[low];
int partition = quickSortOneTime(array, low, high);
index = high - partition + 1; //找到的是第几个大值
if(index == k) {
return array[partition];
}else if(index < k) {//此时向左查找
return Select_k(array, low, partition-1, k-index); //查找的是相对位置的值,k在左段中的下标为k-index
}else {
return Select_k(array, partition+1, high, k);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = new int[] {92, 5, 88, 13, 80};
int index = Select_k(array, 0, array.length-1, 2);
System.out.print(index);
}
}
kafka
Kafka主要设计目标如下:
- 以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间的访问性能。
- 高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒100K条(也就是100000条——十万)消息的传输。
- 支持Kafka Server间的消息分区,及分布式消费,同时保证每个partition内的消息顺序传输。
- 同时支持离线数据处理和实时数据处理。
redis丢弃算法。
Redis缓存淘汰策略
常用的淘汰算法:
FIFO:First In First Out,先进先出。判断被存储的时间,离目前最远的数据优先被淘汰。
LRU:Least Recently Used,最近最少使用。判断最近被使用的时间,目前最远的数据优先被淘汰。
LFU:Least Frequently Used,最不经常使用。在一段时间内,数据被使用次数最少的,优先被淘汰。
https://flychao88.iteye.com/blog/1977653
es
1)分布式的搜索引擎和数据分析引擎
2)全文检索,结构化检索,数据分析
Elasticsearch的特点
可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据,服务大公司;也可以运行在单机上
Elasticsearch不是什么新技术,主要是将全文检索、数据分析以及分布式技术,合并在了一起,才形成了独一无二的ES
对用户而言,是开箱即用的,非常简单,作为中小型的应用,直接3分钟部署一下ES,就可以作为生产环境的系统来使用了,数据量不大,操作不是太复杂
常用垃圾收集器
1) 标记-清除收集器 Mark-Sweep
2) 复制收集器 Copying
3) 标记-压缩收集器 Mark-Compact
4) 分代收集器 Generational
垃圾回收算法
垃圾回收算法 https://www.cnblogs.com/guozhenqiang/p/5621665.html
算法一:引用计数法。
算法二:标记清除法。
算法三:标记压缩清除法(Java中老年代采用)。
算法四:复制算法(Java中新生代采用)。
核心思想是将内存空间分成两块,同一时刻只使用其中的一块,在垃圾回收时将正在使用的内存中的存活的对象复制到未使用的内存中,然后清除正在使用的内存块中所有的对象,
然后把未使用的内存块变成正在使用的内存块,把原来使用的内存块变成未使用的内存块。很明显如果存活对象较多的话,算法效率会比较差,并且这样会使内存的空间折半,但是这种方法也不会产生内存碎片。
算法五:分代法(Java堆采用)。
主要思想是根据对象的生命周期长短特点将其进行分块,根据每块内存区间的特点,使用不同的回收算法,从而提高垃圾回收的效率。
比如Java虚拟机中的堆就采用了这种方法分成了新生代和老年代。然后对于不同的代采用不同的垃圾回收算法。
新生代使用了复制算法,老年代使用了标记压缩清除算法。
算法六:分区算法。
数据库锁。
数据库的锁机制:
共享锁
由读表操作加上的锁,加锁后其他用户只能获取该表或行的共享锁,不能获取排它锁,也就是说只能读不能写
排它锁
由写表操作加上的锁,加锁后其他用户不能获取该表或行的任何锁,典型是mysql事务
根据锁的范围,可以分为
表锁
给整张表加锁
行锁
给行数据加锁
因此锁可以分为表级共享锁、行级共享锁、表级排它锁、行级排它锁。
数据库隔离机制
引起的问题。
public static void main(String[] args) {
String[] num = {"1", "2", "3", "4", "5", "6"};
for (int i = 0; i <= num.length / 2 - 1; i++) {
String temp1 = num[i];
String temp2 = num[num.length - i - 1];
num[i] = temp2;
num[num.length - i - 1] = temp1;
}
System.out.println(Arrays.asList(num).toString());
}
数据库原子性。
事务原子性
上面说了事务的原子性是保证:事务内的一组操作全部成功(或者全部失败),为了实现原子性,就需要通过日志:将所有对数据的操作都写入日志,如果事务中的一部分操作已经成功,但后面部分操作,因为系统断电,操作系统崩溃等问题而没有成功执行,那么就要通过回溯日志,将前面已经成功执行的操作撤销,从而达到"全部执行失败"的效果。
双重校验的单例
public class SingletonDoubleCheck {
static volatile SingletonDoubleCheck singleton;
public static SingletonDoubleCheck getInstance() {
if (singleton == null) {
// 此处控制了锁的粒度,效果就是后续获取实例不用争抢锁
synchronized (SingletonDoubleCheck.class) {
if (singleton == null) {
singleton = new SingletonDoubleCheck();
}
}
}
return singleton;
}
}