深入理解JUC02
Volatile关键字为什么要使用volatile关键字,它有什么作用?
首先我们需要了解volatile的作用,volatile其实解决的就是上一节讲到的可见性和有序性的问题。 也就是说被volatile修饰的数据在多线程情况下是对其他线程可见的,并且编译器和处理器不能对其进行重排序(但这只是相对的,后面我们会讲到)
为什么volatile可以保证可见性和有序性呢?
保证可见性
JMM规定当某个线程修改了被volatile修饰的数据时,其他引用了该数据的线程需要重新从主存中访问该数据。其底层实现就是,当某个CPU修改了某个volatile数据并写入缓存时,数据在总线上传输的时候会被其他CPU监听到,CPU缓存中对应的数据就会失效。(感觉还是有概率发生线程安全问题,比如两个CPU同时操作某数据,同时在总线上传输,不过概率很小)需要注意的是volatile只能保证可见性,不能保证原子性,比如:
1234volatile int i = 0;public void add(){ i++;}
以上代码依然会发生线程安全问题,因为i++底层是由三个操作组 ...
详解ArrayList
#####起因
这是详解集合系列文章中的第一篇,至于为什么要写该系列的文章,想必大家都很清楚。java中提供的这些集合,不论是在工作还是日常刷算法题,都会大量的使用。因此作为一个java程序员我们必须熟悉它们的底层实现原理。
ArrayList底层源码实现12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758/** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. Any * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA * will be expanded to DEFAULT_C ...
深入理解JUC01
起因 java中的JUC不仅是面试的高频考点,也是java中比较难的知识点,其中包含大量的设计技巧,内容庞大复杂。希望借该系列文章加深对JUC的理解。
为什么要学习JUC 由于java是支持多线程编程的,因此会发生线程安全问题,JUC是java.util.concurrent包的简称,即Java并发编程工具包,目的是为了更好地支持高并发任务,让开发者进行多线程编程时有效减少竞争条件和死锁线程。也就是说如果想要使用java进行并发编程,那么一定离不开JUC。
你可能会问为什么会发生线程安全问题,这是一个相对复杂的问题,涉及计算机的底层设计。
为什么会发生线程安全问题 为了提高系统的性能,CPU往往是支持线程并发执行的,也就是在单核CPU情况下,如果当前运行的线程被阻塞,操作系统会调度一个新的线程,从而充分利用CPU资源。
可见性
在java中为了规定硬件架构与java语言的内存模型,引入JMM(java memory model)。需要注意的是JMM是一套规范,并不存在具体的代码。
在java中每创建一个线程,jvm都会为该线程分配一个工作内存(线程栈),这是该线程私有 ...
详解ThreadLocal
起因
为什么要写这篇文章?作为一个java程序员,你会发现在很多项目中都会使用这个工具,不仅如此,ThreadLocal还是面试经常被问到的一个考点,由此可见ThreadLocal的重要性。我自己也在学习的过程中使用过ThreadLocal,但只停留在别人教我这里要使用,我就使用的层面,对于为什么要使用ThreadLocal以及它的工作原理都是懵懵懂懂的状态。因此想要借此文章系统整理一下关于ThreadLocal的知识点,从而加深对它的理解
问题:ThreadLocal有什么用?
当你看到别人使用ThreadLocal时,你可能会问,为啥要使用ThreadLocal呢?因此,我们第一步需要知道ThreadLocal有什么用,它能解决什么问题。
ThreadLocal最主要的用途就是用来保证线程间数据的相互隔离。什么意思呢?简单来说就是在多线程环境下,每个线程从ThreadLocal中获取的数据都是自己之前存放进去的数据,而不会是其他线程的数据。基于此特性,在很多场景下都能使用ThreadLocal,比如层与层间进行参数传递,这样只要在一层中向ThreadLocal中存入数据 ...
思维
已知a + b + c + …+ n的和sum,求abc..n乘积的最大值
结论:尽可能让a,b,c…=3;
解题思路:设将长度为 n 的竹子切为 a 段:
n=n1+n2+…+na
本题等价于求解:
max(n1×n2×…×na)以下数学推导总体分为两步:(1) 当所有绳段长度相等时,乘积最大。(2) 最优的绳段长度为 3 。
数学推导:以下公式为“算术几何均值不等式” ,等号当且仅当 n1=n2=…=na时成立。
$\frac{n_1 + n_2 + … + n_a}{a} \geq \sqrt[a]{n_1 n_2 … n_a}$
推论一: 将竹子 以相等的长度等分为多段 ,得到的乘积最大。
设将竹子按照 x 长度等分为 a 段,即 n=ax,则乘积为 x^a^ 。观察以下公式,由于 n 为常数,因此当$x^{\frac{1}{x}}$取最大值时, 乘积达到最大值。
$x^a = x^{\frac{n}{x}}={x^{\frac{1}{x}}}^n$
根据分析,可将 ...
短链接--短链接跳转
问题:如何获取gid?
问题:为什么会发生缓存击穿问题?如何解决缓存击穿问题?
问题:什么是缓存预热?项目中哪里使用了缓存预热?为什么需要缓存预热?
短链接--修改短链接
修改短链接
针对短链接的修改操作,有以下两种情况。
只修改短链接的基本信息,包括:需要跳转的长连接、有效期类型、有效期、是否启用、描述以及网站图标。针对这类修改,我们只需要更新数据库中对应的行即可。具体做法:
修改短链接所属的分组,针对这类修改,我们需要先删除掉原来的短链接数据,再将短链接添加到对应的分组下(短链接以gid作为分片件,因此在进行增删改查时都需要带上gid,gid变化短链接所在的表就会发生改变,需要删除该短链接原来表中对应的数据)
需要注意的是,本项目中的短链接不支持修改域名,在小码短链接平台更是连分组都不能修改
分库分表
#####起因
为什么要写这篇文章?最近在跟着某个大佬做项目,由于这是一个模拟高并发海量数据的项目,因此在学习的过程中会经常使用分表操作。借此机会,想要系统学习一下关于分库分表的知识,用此文章记录自己的学习过程。
#####问题:为什么要分库分表?[使用场景]
在学习新知识之前,我们首先要弄清楚它的作用,这样当我们遇到类似的问题时就可以使用对应的解决方案。
首先我们需要清楚的是我们通常所说的分库分表其实包含了三种操作:只分库不分表、只分表不分库以及分库又分表。
只分库不分表(又称分库)
分库操作主要解决的是并发量大的问题,由于单个数据库的连接数是有上限的(MySQL5.5、MySQL5.6和MySQL5.7的最大连接数上限为100000,但默认的最大连接数都是151),虽然这个上限可以手动调控,但当并发量不断增大时,可能需要反复调控。一种更加方便的做法就是进行分库操作,分库就是将一个数据库中的数据分散到多个数据库中,不仅减少了单个数据库中的数据量,同时增加了系统的并发量(数据库增多)。
只分表不分库(又称分表)
分表操作主要解决的是单张表数据量过大的问题,通过分表将 ...
短链接--短链接管理之查询短链接
–解答:
根据gid分页查询短链接Service层代码
12345678910public Result getShortLinkByPage(ShortLinkPageReqDTO requestParam){ Page<ShortLinkDO> shortLinkDOPage = new Page(requestParam.getCurrent(), requestParam.getSize()); LambdaQueryWrapper<ShortLinkDO> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(ShortLinkDO::getGid,requestParam.getGid()); Page<ShortLinkDO> pages = shortLinkMapper.selectPage(shortLinkDOPage, queryWrapper); pages.convert(each -> Bea ...
短链接--短链接管理之新增短链接
问题:什么是短链接?有什么作用?
问题:短链接是如何实现页面跳转的?
问题:如何生成短链接?短链接生成算法是什么?
问题:为什么使用这种算法?
问题:为什么短链接表要以gid作为分片件?
–解答:这里主要是方便进行分页查询
问题:哈希冲突怎么解决?
–解答:重试,随机一个UUID继续生成。
问题:为什么使用UUID作为生成短链接?
–解答:每次重试的时候,由于UUID是随机生成的,冲突的概率更小
问题:为什么建议Spring使用构造注入?
问题:为什么一个表中往往有两个id字段?
问题:为什么使用布隆过滤器?
–解答:这里的目的是我们在生成一个短链接后需要查看数据库中是否已经存在该短链接。一种最直接的实现方案是直接查询数据库,但面对海量用户时,这种方案不仅性能低,而且由于数据库存在最大连接数,无法支持海量用户。布隆过滤器可以快速的判断出数据库是否存在此短链接,性能高。
问题:为什么不使用set来判断是否存在短链接呢?
–解答:布隆过滤器本身是由一个二进制位数组和多个哈希函数组成,工作原理是将key通过哈希函数映射到二进制数组的对应位置,因此所需要的内存是非常小的。s ...