面试复盘
mysql死锁:
1.在数据库中,“资源”通常指的是数据行、间隙(Gap)或索引记录上的锁。
2.死锁产生的必要条件
死锁的产生必须同时满足以下四个条件,缺一不可:
- 互斥条件:一个资源每次只能被一个事务持有。
- 请求与保持条件:一个事务在持有至少一个资源的情况下,又去请求新的资源。
- 不剥夺条件:事务已获得的资源,在未使用完之前,不能被其他事务强行剥夺。
- 循环等待条件:多个事务之间形成一种首尾相接的循环等待资源关系。
MySQL的InnoDB引擎默认就满足了前三个条件(因为它使用锁来保证数据一致性),所以只要发生了循环等待,死锁就产生了。
第二种分析:
- 两个事务都持有一个共享的间隙锁(彼此不冲突)。
- 但当它们都想在这个被锁定的间隙内插入数据时,发生了互相等待。
- 这种死锁在 READ-COMMITTED 隔离级别下不会发生,因为该级别不使用间隙锁。
死锁变体: 如果此时有第三个事务C也在等待同一个唯一键,当A回滚时,B和C会同时被唤醒去争取这个排他锁,但只有一个能成功,另一个会因死锁失败(因为大家都等待同一个资源,但该资源一次只能给一个事务)。
四、MySQL如何处理死锁?
- 死锁检测:InnoDB默认开启了死锁检测(innodb_deadlock_detect = ON)。它会主动扫描等待锁的事务,如果发现循环等待,就会立即介入。
- 牺牲者选择:InnoDB会选择一个事务作为“牺牲者”,强制其回滚。这个选择基于回滚成本,通常选择修改数据量较小、回滚日志较少的事务。
- 错误返回:被选为牺牲者的事务会收到一个 ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction 错误。应用程序必须能够捕获并处理这个错误,通常的策略是重试整个事务。
五、如何避免和减少死锁?
- 保持一致的访问顺序:如前所述,这是最重要的原则。确保所有事务都以相同的顺序访问数据行。
- 减小事务粒度,及时提交:尽量让事务小一些,做完操作后立刻提交,避免在一个事务中做过多的操作和过长的等待,从而减少锁的持有时间。
- 为查询使用合适的索引:如果 UPDATE 或 DELETE 语句没有用到索引,会进行全表扫描,可能锁定很多甚至全部记录,大大增加死锁概率。
- 降低隔离级别:如果业务允许,将隔离级别从 REPEATABLE-READ 降到 READ-COMMITTED,可以避免很多因间隙锁导致的死锁。
- 使用 SELECT ... FOR UPDATE 而非 LOCK IN SHARE MODE:如果需要更新数据,直接使用排他锁,可以减少锁升级带来的死锁风险。
如何统计 很大一个文件1TB这样大,里面全是IP地址,我要统计出现次数最多的50个ip 我只有512MB的内存
重点:没想到hash 分片hash后把同一ip的放到同一文件,读取,统计频率,才可以
如果还超内存的话,可以再次分片hash
第一步:分割大文件
- 创建2048个小文件(假设为part_0000, part_0001, ..., part_2047)。
- 读取大文件,对每个IP,计算哈希值:hash(IP) % 2048,然后写入对应的小文件。
相同IP一定会被分到同一个文件中(因为哈希值相同);通过选择合适的N,确保每个临时文件大小 < 512MB
第二步:统计每个小文件
- 对于每个小文件,读取整个文件(因为每个小文件大约500MB,小于512MB),使用一个哈希表统计IP出现的次数。
- 将统计结果(IP和次数)写入一个中间文件(每个小文件对应一个中间文件,中间文件名为stat_0000, stat_0001, ...)。
第三步:合并统计结果,找出Top50
- 初始化一个最小堆,大小为50。
- 依次读取每个中间文件,对于每个中间文件中的每行(格式为:IP 次数),将次数转换为整数,然后与堆顶比较,如果大于堆顶,则替换堆顶。
- 最后,堆中就是Top50的IP。
中间文件可能仍然很大,无法一次性加载到内存。我们需要使用外部排序,然后使用一个最小堆来获取Top50。
这种方法是大数据处理中的经典"分治+归并"策略,能够有效解决内存不足情况下的大规模统计问题。
hashmap是怎么执行contains的
在HashMap中,contains方法实际上是通过containsKey和containsValue来实现的。我们通常使用containsKey来检查是否包含某个键,使用containsValue来检查是否包含某个值。
- containsKey:HashMap首先根据键的hashCode值计算出数组索引(桶的位置),然后在该桶对应的链表或红黑树中,使用equals方法比较键是否存在。具体步骤:如果键为null,则检查null键所在的桶(HashMap中null键存储在索引0的位置)。否则,计算键的哈希值,找到对应的桶。遍历桶中的节点(可能是链表或红黑树),用equals方法比较键。如果找到相等的键,返回true,否则返回false。
- containsValue:HashMap需要遍历所有的值来检查是否包含指定的值。由于值没有索引,所以必须遍历整个哈希表的所有节点,逐个比较值。因此,containsValue的时间复杂度为O(n),而containsKey的平均时间复杂度为O(1)。
nginx 负载均衡:负载均衡负载均衡是将请求分发到多个服务器上,以达到平衡负载、提高系统处理能力、增加吞吐量、提高可用性的目的。
有无做过web开发是指?web开发是指开发web应用程序,也就是通过浏览器访问的应用程序。这包括前端(HTML、CSS、JavaScript等)和后端(如Java、Python、PHP等服务器端语言)的开发。web开发也涉及数据库、服务器、网络协议等多个方面。
正向代理和反向代理:正向代理:正向代理是位于客户端和原始服务器之间的服务器。客户端为了从原始服务器获取内容,向代理服务器发送请求并指定目标(原始服务器),然后代理服务器向原始服务器转发请求并将获得的内容返回给客户端。正向代理的典型用途是为在防火墙内的局域网客户端提供访问Internet的途径。正向代理还可以使用缓冲特性减少网络使用。同时,客户端可以隐藏自己的真实IP地址。例子:VPN、科学上网工具等。
反向代理:反向代理正好相反,它代理的是服务器。客户端向反向代理发送请求,反向代理将请求转发到内部网络上的服务器,并将从服务器上得到的结果返回给客户端。客户端并不知道真正的服务器是谁。反向代理的用途:隐藏真实服务器的地址和结构,提高安全性。负载均衡,将请求分发给多个服务器。提供缓存,加速访问。提供SSL加密等。例子:nginx作为web服务器的反向代理,接收用户请求,然后转发给后端的Tomcat、Jetty等应用服务器。
查看23道真题和解析