实习太久了,很久没碰过八股和其余信息,感觉自己已经不适应面试了。
比较简单的问题,现在较为常用的分布式锁就是Redis 的SetNX key_exp thread_id+count PX 30000
在这行命令里,已经设置了一个锁,就是key_exp,目前获得它的线程我们记为thread_id,和进入次数count拼接一下,就组成了value
为什么要这么设计呢,目的是为了锁的可重入性,也是就是同一个线程获取同一把锁的时候不会死锁
需要关注的问题
第一点之前已经说过了,在value里记录线程信息和进入次数,序列化为string即可
第二点,自动续约机制我们可以使用看门狗的方法,启动一个后台线程,每次sleep 10s,10s后修改redis里的过期时间
第三点,过期自动释放,PX已经做到了
题目的具体描述是
select * from table where a=100 and b>10 and b<100 order by d asc limit 19
有这样一条sql,为了它的查询效率,该如何建索引。
select会用到索引这是无疑的,同时根据最左匹配原则,显然需要建立(a,b)的联合索引,这样可以快速找出符合的是数据。
但是需要将d加入联合索引吗,我觉得是两可的。对于确定的a,b对,则d是有序的,但是对于确定的a,多个b,在每个b内,d是有序的,如果d有序这样可以使用多路归并排序来快速排序d。
但是这样新增是有意义的吗?建立索引是需要额外的资源的,所以真的需要这么建立吗?需要按照场景来考虑。
如果是读多写少的场景,显然建立一个(a,b,d)的联合索引是值得的,
场景 | 推荐索引 | 理由 |
---|---|---|
返回数据量小(< 1000 行),且系统写频繁 | (a, b) | 排序开销小,避免索引膨胀 |
返回数据量大,且 ORDER BY d 经常导致慢查询 | (a, b, d) | 消除 filesort ,提升查询稳定性 |
d 是主排序字段,且有分页需求(如 LIMIT 10 ) | (a, b, d) | 可快速取前 N 条,无需全排序 |
存在大量类似查询,且 d 排序是刚需 | (a, b, d) | 长期收益大于索引成本 |
当时没有思考到这么多,所以说,答案应该是建立(a,b,d)的联合索引
事务的四大特性:ACID,原子性、一致性、隔离性、持久性
A:事务是不可分割的,同时成功同时失败。
C:事务执行前后,必须保持完整性约束,确保数据从一个有效状态转换为另一个有效状态。
I:并发的事物之间互相隔离,操作互不干扰。
D:事务一旦提交,就不会丢失。
那么事务的隔离级别都有什么呢?
脏读
事务A未提交的变更能够被事物B读取到
不可重复读
事务A第一次读数据1和第二次读数据1的值不相同
幻读
事务A多次查询相同查询条件的数量不同
简单题,没什么好说的。
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
type Node struct {
Val int
Next *Node
}
func merge(list1, list2 *Node) *Node {
fakeHead := &Node{}
pre := fakeHead
for list1 != nil && list2 != nil {
if list1.Val < list2.Val {
pre.Next = list1
list1 = list1.Next
} else {
pre.Next = list2
list2 = list2.Next
}
pre = pre.Next
}
if list1 != nil {
pre.Next = list1
} else {
pre.Next = list2
}
return fakeHead.Next
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
line := strings.Split(scanner.Text(), ",")
list1 := &Node{}
pre := list1
for _, cr := range line {
node := &Node{}
num, _ := strconv.Atoi(cr)
node.Val = num
pre.Next = node
pre = node
}
scanner.Scan()
line = strings.Split(scanner.Text(), ",")
list2 := &Node{}
pre = list2
for _, cr := range line {
node := &Node{}
num, _ := strconv.Atoi(cr)
node.Val = num
pre.Next = node
pre = node
}
list1 = list1.Next
list2 = list2.Next
list := merge(list1, list2)
for list != nil {
fmt.Println(list.Val)
list = list.Next
}
}
业务、流程时间