-
秒杀系统设计
1.解决超卖问题 使用version方式的分布式锁,这样当并发的情况下,根据version字段作为条件来控制并发 2.解决限流问题 a.漏桶算法,有固定大小的容器,请求来了先缓存在容器中,然后以恒定速度进行处理,多余溢出的丢弃(单机限流) b.Google的Guava工具包中就提供了一个限流工具类——RateLimiter--RateLimiter是基于“令牌通算法”来实现限流, (单机限流) c.Sentinel方式(分布式限流) d.基于redis方式(分布式限流) 详情请看[限流方案](https://www.cnblogs.com/luoxn28/p/11793251.html)
-
分表分库生成ID
1.专门建一张表,用来根据数据库自增id,来获取到一个全局id,然后分配给不同的表 (库压力大,导致分库分表; 数据量大,导致分表) 2.uuid方案,不太建议使用,导致主键长,本身都分库了,需要提高检索速度 3.snowflake算法(雪花算法)
-
数据库读写分离
-
数据库读写分离问题
-
线程池拒绝策略
条件: coreSize线程使用完毕,任务队列已经满了,maxsize也使用完 1.默认 AbortPolicy 直接抛出异常拒绝,被拒绝的任务丢失 2.DiscardPolicy 不关心,不处理,实现是空方法 3.CallerRunsPolicy 由调用的线程来处理拒绝任务,会阻塞调用线程 4.DiscardOldestPolicy 丢弃老的任务,新拒绝任务进行retry 测试代码: public class RejectPolicyTest { public static void main(String[] args) { LinkedBlockingQueue<Runnable> runnables = new LinkedBlockingQueue<>(10); //AbortPolicy拒绝策略 /*ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 5, 0L, TimeUnit.MILLISECONDS, runnables);*/ //DiscardPolicy拒绝策略 /*ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 5, 0L, TimeUnit.MILLISECONDS, runnables, Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardPolicy());*/ //CallerRunsPolicy拒绝策略 /*ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 5, 0L, TimeUnit.MILLISECONDS, runnables, Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());*/ //DiscardOldestPolicy拒绝策略 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 0L, TimeUnit.MILLISECONDS, runnables, Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardOldestPolicy()); for(int i=0;i<20;i++){ try { Object1 object1 = new Object1(); threadPoolExecutor.execute(new Runnable() { @Override public void run() { try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(); System.out.print("当前处理线程:"+Thread.currentThread().getName()+"=="); System.out.print("当前剩余任务:"+runnables.size()+"=="); System.out.print("当前处理任务:"+object1); System.out.println(); } }); }catch (Exception e){ e.printStackTrace(); System.out.println("任务"+(i)+"被拒绝"); } System.out.println("添加任务"+i+"成功"); } //threadPoolExecutor.shutdown(); }} class Object1 { private static int j=0; private int i=0; public Object1() { this.i = j++; } @Override public String toString() { return "Object1{" + "i=" + i + '}'; } }
- 如何给大表加个字段
1.几百万的表不算大表直接加字段索引就好了 2.千万级别的表,创建个临时表B,加索引字段直接在B表加好,然后将原表A的数据直接靠到B表 注意是分批拷贝过来,差不多要十多分钟,拷贝前记录一个时间t1. 拷贝完后, 在t1时间后肯定还有新数据 进来,这个时候找出这些数据,一次性拷贝过来就好. 3.停服务 问题:方案2拷贝新数据的期间还有新数据进来怎么办 我的方案是最后新数据拷贝量很少, 可以加表锁,然后拷贝,renametable,释放表锁
面试题之常见解决方案
猜你喜欢
转载自blog.csdn.net/weixin_38312719/article/details/107074246
周排行