Mysql架构与索引优化分析
1. 索引优化1.1 索引分析一表
12345678910111213141516171819#建SQLcreate table if not exists `article` (`id` int(11) auto_increment not null,`author_id` int(11) not null,`category_id` int(11) not null,`views` int(11) not null,`comments` int(11) not null,`title` varchar(255) not null,`content` text not null,primary key(id));insert into `article`(`author_id`, `category_id`, `views`, `comments`, `title`, `content`) values (1, 1, 1, 1, '1', '1'),(2, 2, 2, 2, '2', '2'),(3, ...
synchronized优化
JDK6 synchronized优化1. CAS1.1 目标
学习CAS的作用
学习CAS的原理
CAS我在之前大厂面试题中详细讲解过,需要的去看看就行了,
因为这里需要对比一波所以再次复习一波。
1.2 CAS概述和作用- oiuytrCAS的全成是: Compare And Swap(比较相同再交换)。是现代CPU广泛支持的一种对内存中的共享数据进行操作的一种特殊指令。
CAS的作用:CAS可以将比较和交换转换为C原子操作,这个原子操作直接由CPU保证。CAS可以保证共享变量赋值时的原子操作。CAS操作依赖3个值:内存中的值V,旧的预估值X,要修改的新值B,如果旧的预估值X等于内存中的值V,就将新的值B保存到内存中。
CAS和volatile实现无锁并发123456789101112131415161718192021222324252627282930/* 目标:演示原子性问题 1.定义一个共享变量number 2.对number进行1000的++操作 3.使用5个线程来进行 */public class Demo01 & ...
你问我答08
问:现在聊点基础的吧,我现在new两个value为1的Integer对象用==比较返回什么
呃,返回false 用valueOf创建的话==会返回true。Integer,long 这几个封装类型里面会维护一个缓存。用来缓存比较小的值,默认缓存是-128到127这个范围的值。
问:我看你做过订单系统。你这个系统里面的金额用的什么类型啊?
代码里面用BigDecimal,mysql 里面用Decimal
问:为什么不用double 呢?
因为double 会丢精度呃会出现1.00001这种不精确的值。
问:知道为什么会出现这种值吗?
这是因为十进制小数和二进制转化的问题啊。你比如0.8转化成二进制的话,小数部分就是11001100这种无限循环。计算机就只会取前面一部分值进行存储啊,后面循环的部分就丢了,再转化成十进制的时候就丢精度了。
问:那为什么BigDecimal 能表示精准的浮点数呢?
BigDecimal里面说白了就是浮点数转化成整数存储,然后记录小数点的位置在哪里。这个转化成的整数一般都是Long范围内的,所以直接用L ...
你问我答06
问:如何才能让mysql 出现一个死锁呢?
举个例子吧,我们用两个mysql 的客户端,分别起两个事务啊,然后在第一个事务里面去修改id=1的行。呃,然后第二个事务的话就去修改id=2的这一行。呃,这个时候呢呃第一个事务已经拿到了id=1这一行的锁啊,第二个事务呢就已经拿到了id=2这个行的锁。然后呢在第一个事务里面呃再去修改id=2这一行啊,然后再去第二个事务里面去修改id=1这一行啊。这个时候呢第一个事务会尝试拿id=2这一行的锁啊,但是拿不到啊,因为已经被第二个事务锁住了啊。然后第二个事务呢也尝试去拿id=1这一行的锁也拿不到啊。因为被第一个事务锁住了啊,这样的话就形成了死锁。
问:发生了死锁怎么办呢?
呃,我知道的就那么几种,一个是设置锁等待的超时时间。还有一个就是开启mysql 检查死锁的功能。但是这两种方式都不是特别好。要是依靠锁等待超时来解这个死锁的话,这个超时时间不是特别好把握。比如超时时间设置短了,就有可能导致一些正常的事务回滚了。那如果设置长了,就会导致阻塞时间比较长,然后影响系统的性能。那mysql 死锁检查功能的话,性能也不是特别好。它是一个O(n)的算 ...
你问我答07
问:嗯,先来写个题,求一个二叉树里面两个节点之间的路径的最大值,不能走回头路啊。比如这个数里面四到三的路径是最大的,那就是四二一三啊,五到三可以啊,然后返回这个路径上的节点个数啊,比如说四二一三啊就是四。嗯,解释一下你这段代码吧。
我用的是深度优先遍历,要算整个树里面两个节点的最大路径啊,那可以先算左子树的深度啊,然后再算右子树的深度啊,然后再加上根结点啊,就是整个数里面两个节点的最大路径了。然后递归一直往下拆啊,拆到叶子节点啊,然后递归返回的时候,就计算各个子数的最大路径啊,用max 记录一下就可以了。
问:先聊聊你之前做过的项目吧。我看你之前做过订单的模块,你这一天的订单量大概有多少呢?
大概一天十万左右的单吧,具体多少我忘记了。
问:嗯,当时用的什么存储呢?
主要用的是mysql。
问:你们数据库有没有进行分库分表呢?
订单表的话,当时是分了十个库,每个库里面存三十天的订单,然后每天分一百张表。
问:是根据哪个字段进行分库的呢?
按照订单号进行分库分表的,订单号分了三个部分,包含了用户的userId,一个小时级别的时间戳。我记得是距离二零一五年十二月一号的小时 ...
你问我答05
问:,先来写道题吧,用栈来实现一下队列的效果吧。嗯,简单说一下你实现的思路吧。
我是用了两个栈实现的,一个是来模拟队尾,一个是用来模拟队头。入队的时候呢直接进队尾的那个栈就行。然后要出队的那个时候就先查队头的这个栈啊,如果这个栈有数据的话,嗯,就需要直接弹出啊。如果说是没有的话,嗯,就把队尾的那个栈里面的全部数据都弹出来,然后压到队头的栈,等这个队尾的栈弹干净了之后,再从队头栈里面呃数据出栈就可以了。
问:平时用过零拷贝技术吗?说说他为什么比普通的拷贝要快呢?
比如说我把磁盘的数据发送出去,要是按照正常的方式,就需要创建一个byte数组。然后调read 方法读取数据,到这个byte数组里面,这就发生了一次用户态到内核态啊,还有一次内核态到用户态的切换。然后我们的线程再把这个byte数组拷贝到网卡的缓冲区里面啊,这又是两次用户态,还有内核态之间的转化。这种切换其实就是为了进行数据拷贝,其他的啥也没干,就是比较耗资源了。那这个零拷贝呢他就可以直接把磁盘的数据拷贝到网卡缓冲区里面啊。就这样的话就是减少了这些用户态和内核态的切换啊,也减少了数据在缓冲区之间的拷贝了。
问:嗯,你实际用 ...
你问我答01
问 我们先来说一下: HashMap 的工作原理是什么?
HashMap底层是通过数组和单向链表实现的,数组中的每个元素都是一个链表,而链表中的每个节点都是一个Entry对象,它里面存储的才是真正的KV数据,然后我们在存储键值对的时候,会先去调用哈希方法计算Key的哈希值,然后去模这个数组的长度,就能拿到存储Key的数组的下标,然后呢,我们遍历这个下标里面存储的这个单向链表,把里面每一个Key,还有插入的Key进行equal比较,如果在这个时候返回true的话,就直接更新Value值,如果全部比较,都返回了False,那就直接把新的键值对插入到这个链表中,在put的过程中,当哈希表中存储的键值对超过了数组长度乘以负载因子的时候,就会将这个数组扩容两倍,还有就是在插入链表的时候,如果链表长度超过了一个阈值,就会从链表转化成红黑树,然后我们那个时候阈值默认是8,在查询KV数据的时候,我们会先调用哈希方法计算Key的哈希值,然后去模数组的长度,这样就能拿到存储Key的数组下标,然后呢我们在遍历其中的链表,进行equa比较,得到Value 值,那哈希表的核心原理呢 ,其实就是hash值过滤 ...
你问我答03
问: 就是我现在有一个字串,希望找出它的最长不重复子串的长度。我举个例子啊,就是这个组串,其中最长的不成的组串长度是三。那比如说abcabca啊,这些都是它的最长不重复的串啊,abca呢这就不是因为这个a 有两个重复了。好吧,再把写到这个版本上。
嗯,好的。嗯,我写完了。
问: 嗯,行,那简单说一下你这道题的思路吧。
嗯,可以的,我用了一个滑动窗口,滑动窗口每次都会向右扩张一个字符。然后检查这个字符在滑动窗口里面呢,是不是存在的。要是不存在的话呢,就会继续向右扩张。要是存在的话,窗口左侧呢就会开始收缩。直到收缩到这个新字符没有重复。然后这个i 我是用来记录窗口的最大长度啊,这个长度呢就是要求的最长不重复子串的长度。
问: 你在项目里面用redis 是做缓存呢,还是做存储呢?
嗯,主要是用来做缓存的,
问: 主要是用来缓存什么数据呢?
这个是用来缓存一些商品信息。
问: 在你这个小店第一次上线的时候,Redis有没有进行过预热呢?
进行了一个简单的预热。我们在上线之前预测了一些热点的商品,然后就把这些商品信息添加到了redis 里面。然后随着用户不断请求我们的服务,会 ...
你问我答02
问:我们先聊一下Java基础知识吧,在你工作的时候,用过哪些并发的工具类呢?
我在工作的时候用过Atomiclnteger,AtomicReference这些原子类,也用过 ReentrantLock 、还有ReadWrtteLock这两种锁,然后还用过CountDownLatch
问: 简单介绍一下 Aomiclnteger底层的原理吧
Atomiclnteger底层是通过一个volatile 修饰的lnt值还有CAS操作实现的,CAS 操作的这个含义呢就是JVM的一个原子性操作,它具体是比较一个值,和我们预期的值是不是一致的,在这个时候如果一致的话就表示没有其他线程,并发去修政这个值。这样的话我们就可以安全的把这个值替换成我们的目标值
问: 为什么不能使用volatile关键字,必须使用Atomiclnteger呢?
当时我的场景是需要把一个值进行加一操作,这样的话,就必须使用Atomiclnteger,因为volatile关键字它只能保证可见性、顺序性和读写操作的原子性。我先简单说一下volatile 的这几个特性吧,可见性就是一个线程修改了volatile关键字修饰 ...
你问我答04
问: 你常用的集合类有哪些呢?
我常用的有ArrayList ,LinkedList ,HashMap,TreeMap,还有HashSet,treeSet,然后支持并发的用过ConcurrentHashMap,CopyOnWriteArrayList,ConcurrentSkipListMap大概就是这些
问: 问:你是在什么场景下用的CopyOnWriteArrayList这个集合呢?
当时的情况是这样的,当时我们的监控系统做了一个动态加载的功能。动态加载的这些扩展模块,都会生成一个对应的model 对象,然后放到CopyOnWriteArrayList里面去。这些扩展模块,主要就是接收我们监控系统的一些消息啊,就比如说有的是用来发异常报警的,而有的是用来持久化这些报警信息的。然后在我们的监控系统里面,就会起一个线程去定期检查这些动态模块的目录。嗯,如果发现新的模块的jar包,那就直接加载上来。然后把这个放到CopyOnWriteArrayList 里面。这个变更一般都是比较少的,所以说是比较符合这个CopyOnWriteArrayList的使用场景啊,毕竟它是比较适合那种读 ...




