前言:
求职季在即,技巧千万条,硬实力才是关键,听说今年疫情大环境不好,更要好好准备才行。MySQL是Java程序员面向高级的必备技能,很多朋友在面试时经常在这里折戟沉沙,饮恨不已。熟练掌握MySQL知识,在实践中具有很强的操作性,尤其是在互联网行业,不仅要写好代码、实现功能,而且还要在高并发的情况下能够正常运转。
这篇文章总结了许多关于MySQL方面的知识总结,以及面试多家总结出来的常问面试题,希望对大家有所帮助。
static class BitKeeper {
/** 记录最大的低位0的长度 */
private int kmax;
public void random() {
// 生成随机数
long value = ThreadLocalRandom.current().nextLong(2L << 32);
int len = this.lowZerosMaxLength(value);
if (len > kmax) {
kmax = len;
}
}
/**
* 计算低位0的长度
* 这里如果不理解看下我的注释
* value >> i 表示将value右移i, 1<= i <32 , 低位会被移出
* value << i 表示将value左移i, 1<= i <32 , 低位补0
* 看似一左一右相互抵消,但是如果value低位是0右移被移出后,左移又补回来,这样是不会变的,但是如果移除的是1,补回的是0,那么value的值就会发生改变
* 综合上面的方法,就能比较巧妙的计算低位0的最大长度
* @param value
* @return
*/
private int lowZerosMaxLength(long value) {
int i = 1;
for (; i < 32; i++) {
if (value >> i << i != value) {
break;
}
}
return i - 1;
}
}
static class Experiment {
/** 测试次数n */
private int n;
private BitKeeper bitKeeper;
public Experiment(int n) {
this.n = n;
this.bitKeeper = new BitKeeper();
}
public void work() {
for(int i = 0; i < n; i++) {
this.bitKeeper.random();
}
}
/**
* 输出每一轮测试次数n
* 输出 logn / log2 = k 得 2^k = n,这里的k即我们估计的kmax
* 输出 kmax,低位最大0位长度值
*/
public void debug() {
System.out.printf(“%d %.2f %d\n”, this.n, Math.log(this.n) / Math.log(2), this.bitKeeper.kmax);
}
}
public static void main(String[] args) {
for (int i = 0; i < 100000; i++) {
Experiment experiment = new Experiment(i);
experiment.work();
experiment.debug();
}
}
}
我们可以通过修改main函数中,测试的轮次,再根据输出的结果来观察,n=2^kmax这样的结果还是比较吻合的。
3.5 代码实现-HyperLogLog
接下来根据HyperLogLog中采用调和平均数+分桶的方式来做代码优化,模拟简单版本的HyperLogLog算法的实现,其代码如下:
package com.lizba.pf;
import java.util.concurrent.ThreadLocalRandom;
/**
*
* HyperLogLog 简单实现
*
* @Author: Liziba
* @Date: 2021/8/18 10:40
*/
public class HyperLogLogTest {
static class BitKeeper {
/** 记录最大的低位0的长度 */
private int kmax;
/**
* 计算低位0的长度,并且保存最大值kmax
* @param value
*/
public void random(long value) {
int len = this.lowZerosMaxLength(value);
if (len > kmax) {
kmax = len;
}
}
/**
* 计算低位0的长度
* 这里如果不理解看下我的注释
* value >> i 表示将value右移i, 1<= i <32 , 低位会被移出
* value << i 表示将value左移i, 1<= i <32 , 低位补0
* 看似一左一右相互抵消,但是如果value低位是0右移被移出后,左移又补回来,这样是不会变的,但是如果移除的是1,补回的是0,那么value的值就会发生改变
* 综合上面的方法,就能比较巧妙的计算低位0的最大长度
* @param value
* @return
*/
private int lowZerosMaxLength(long value) {
int i = 1;
for (; i < 32; i++) {
if (value >> i << i != value) {
break;
}
}
return i - 1;
}
}
static class Experiment {
private int n;
private int k;
/** 分桶,默认1024,HyperLogLog中是16384个桶,并不适合我这里粗糙的算法 */
private BitKeeper[] keepers;
public Experiment(int n) {
this(n, 1024);
}
public Experiment(int n, int k) {
this.n = n;
this.k = k;
this.keepers = new BitKeeper[k];
for (int i = 0; i < k; i++) {
this.keepers[i] = new BitKeeper();
}
}
/**
* (int) (((m & 0xfff0000) >> 16) % keepers.length) -> 计算当前m在keepers数组中的索引下标
* 0xfff0000 是一个二进制低16位全为0的16进制数,它的二进制数为 -> 1111111111110000000000000000
* m & 0xfff0000 可以保理m高16位, (m & 0xfff0000) >> 16 然后右移16位,这样可以去除低16位,使用高16位代替高16位
* ((m & 0xfff0000) >> 16) % keepers.length 最后取模keepers.length,就可以得到m在keepers数组中的索引
*/
public void work() {
for (int i = 0; i < this.n; i++) {
long m = ThreadLocalRandom.current().nextLong(1L << 32);
BitKeeper keeper = keepers[(int) (((m & 0xfff0000) >> 16) % keepers.length)];
keeper.random(m);
}
}
/**
* 估算 ,求倒数的平均数,调和平均数
* @return
*/
public double estimate() {
double sumBitsInverse = 0.0;
// 求调和平均数
for (BitKeeper keeper : keepers) {
sumBitsInverse += 1.0 / (float) keeper.kmax;
}
double avgBits = (float) keepers.length / sumBitsInverse;
return Math.pow(2, avgBits) * this.k;
}
}
/**
* 测试
* @param args
*/
public static void main(String[] args) {
for (int i = 100000; i < 1000000; i+=100000) {
Experiment experiment = new Experiment(i);
experiment.work();
double estimate = experiment.estimate();
// i 测试数据
// estimate 估算数据
// Math.abs(estimate - i) / i 偏差百分比
《一线大厂Java面试真题解析+Java核心总结学习笔记+最新全套讲解视频+实战项目源码》开源
Java优秀开源项目:
- ali1024.coding.net/public/P7/Java/git
写在最后
还有一份JAVA核心知识点整理(PDF):JVM,JAVA集合,JAVA多线程并发,JAVA基础,Spring原理,微服务,Netty与RPC,网络,日志,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存,Hadoop,Spark,Storm,YARN,机器学习,云计算…
.abs(estimate - i) / i 偏差百分比
《一线大厂Java面试真题解析+Java核心总结学习笔记+最新全套讲解视频+实战项目源码》开源
Java优秀开源项目:
- ali1024.coding.net/public/P7/Java/git
写在最后
还有一份JAVA核心知识点整理(PDF):JVM,JAVA集合,JAVA多线程并发,JAVA基础,Spring原理,微服务,Netty与RPC,网络,日志,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存,Hadoop,Spark,Storm,YARN,机器学习,云计算…
[外链图片转存中…(img-Am4AJmxl-1649663061049)]