- 限流算法中,计数器方法,可以如何优化
滑动窗口
先说一下原来正常算法的弊病,我们假设qps是100,最后10ms过来100个请求,下一秒的前10ms又过来100个请求,那么就会在某一秒中一次性接受到200个请求,那肯定会出问题。
但是其实本质原因是,分割时间的粒度太粗了,我们可以按照情况给窗口划分更细的粒度。比如,10ms一个小窗口,然后因为我们总窗口是1秒,那么我们就做一个累加计算,当然了,越细粒度对我们的业务场景肯定更友好,但是也肯定会对cpu密集型计算导致的压力也会增大。
不过本质就是为了在接收到第101个请求之前要触发限流,而不是都接受到了200个请求,我才知道,哦,我得限流,那就晚了。
- session和cookie的区别
session保存在服务端,会过期,session可以保存各种各样格式的数据比如json string list map Integer····
cookie保存在客户端,保留时间会很长,Cookie中只能保管ASCII字符串
- ssh的端口号
22
- cpu由什么组成
CPU它的内部元件主要包括:控制单元,逻辑单元,存储单元三大部分。
算术逻辑运算单元(ALU)的基本功能为加、减、乘、除四则运算,与、或、非、异或等逻辑操作,以及移位、求补等操作。
控制器分组合逻辑控制器和微程序控制器,两种控制器各有长处和短处。组合逻辑控制器设计麻烦,结构复杂,一旦设计完成,就不能再修改或扩充,但它的速度快。
存储单元:在存储单元中,同时连接了控制线和数据线,当控制线片选了某个区域的存储单元,这个区域的数据就被激活了,然后数据线就会参照控制线的指令模式,复制存储单元的逻辑信号到cpu缓存区,最后,复制的数据在cpu芯片内部的缓存区进行逻辑运算。这就是cpu和存储单元的数据交换过程。
- redis的zset数据结构是什么
zset为有序(有限score排序,score相同则元素字典序),自动去重的集合数据类型,其底层实现为 字典(dict) + 跳表(skiplist),当数据比较少的时候用ziplist编码结构存储。
同时满足以下两个条件采用ziplist存储:
有序集合保存的元素数量小于默认值128个
有序集合保存的所有元素的长度小于默认值64字节
- AtomicInteger是如何解决ABA问题的
在JDK中提供了AtomicStampedReference类来解决这个问题,思路是一样的。这个类也维护了一个int类型的标记stamp,每次更新数据的时候顺带更新一下stamp。
下面我们通过代码演示来看一下AtomicStampedReference的使用:
package com.wangjun.thread;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;
public class ABA {
// 普通的原子类,存在ABA问题
AtomicInteger a1 = new AtomicInteger(10);
// 带有时间戳的原子类,不存在ABA问题,第二个参数就是默认时间戳,这里指定为0
AtomicStampedReference<Integer> a2 = new AtomicStampedReference<Integer>(10, 0);
public static void main(String[] args) {
ABA a = new ABA();
a.test();
}
public void test() {
new Thread1().start();
new Thread2().start();
new Thread3().start();
new Thread4().start();
}
class Thread1 extends Thread {
@Override
public void run() {
a1.compareAndSet(10, 11);
a1.compareAndSet(11, 10);
}
}
class Thread2 extends Thread {
@Override
public void run() {
try {
Thread.sleep(200); // 睡0.2秒,给线程1时间做ABA操作
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("AtomicInteger原子操作:" + a1.compareAndSet(10, 11));
}
}
class Thread3 extends Thread {
@Override
public void run() {
try {
Thread.sleep(500); // 睡0.5秒,保证线程4先执行
} catch (InterruptedException e) {
e.printStackTrace();
}
int stamp = a2.getStamp();
a2.compareAndSet(10, 11, stamp, stamp + 1);
stamp = a2.getStamp();
a2.compareAndSet(11, 10, stamp, stamp + 1);
}
}
class Thread4 extends Thread {
@Override
public void run() {
int stamp = a2.getStamp();
try {
Thread.sleep(1000); // 睡一秒,给线程3时间做ABA操作
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("AtomicStampedReference原子操作:" + a2.compareAndSet(10, 11, stamp, stamp + 1));
}
}
}
可以看到使用AtomicStampedReference进行compareAndSet的时候,除了要验证数据,还要验证时间戳。
如果数据一样,但是时间戳不一样,那么这个数据其实也被修改过了。
- Spring如何进行依赖注入的
构造器,xml,注解,集合(List Set Map …) ,setter
- 线程池如何销毁
shutdown/shutDownNow
- InnoDB如何保证事务的执行的
(WAL)redo log和undo log
- volatile的缺点
频繁更改、改变或写入volatile字段 有可能导致性能为题。
- explain filesort
其实意思就是,你sql写完了,filesort会给你整理一下语序,比如联合索引,你查BA,他会给你整成AB
- order by会不会让索引失效
不会