REJAVA / LEARNING NOTES
课后问答目录
从问题回到课程,看看理解在哪一步发生变化。
根据第 4、5、10–16、18 课真实交流整理
本次更新说明
- 新增第10–16、18课的课后问答,每个问题附在对应课程末尾;本页只提供目录。
按课程回看问题
每个问题只保存在对应课程末尾。这里提供入口,不另外维护一份答案。
synchronized(内置同步关键字)
- 三种写法分别锁谁?
- 同一个方法,不同实例调用,要互相等待吗?
- 静态同步方法和锁住同一类对象的代码块,是否互斥?
- 同步方法和代码块,字节码有何区别?
- 抛异常后会释放吗?为什么示例有两个退出指令?
- reentrancy(可重入)究竟是谁重新进入?
- 我持有锁,能阻止完全不加锁的访问吗?
- 可见性只保证紧接着进入的一个线程吗?
- DCL(双重检查锁定)为什么还需要 volatile(可见性关键字)?
- spin(自旋)为什么有时划算,有时浪费?
- biased locking(偏向锁)优化什么,为什么退出历史舞台?
thread pool(线程池)
- 两个正在执行、三个排队,等于五个执行线程吗?
- 正常运行时,完整接纳顺序是什么?
- 核心2、最大4、队列容量3,连续8次提交且无人完成,去向如何?
- 队列刚好满了,会自动扩容吗?提高最大值会立即扩容吗?
- 空闲回收时间会中止执行很久的工作吗?谁负责创建线程?
- 四种常见 rejection policies(拒绝策略)分别做什么?
- CallerRunsPolicy(调用者执行策略)会让异步变同步吗?
- 静默丢弃与“已受理”的返回,为什么危险?
- Runnable(无返回值的任务接口)能获得 Future(异步结果句柄)吗?
- 拿到句柄后,下载地址在哪里?立即获取结果还是异步吗?
- 等待超时、执行失败和提交拒绝,有何区别?
- shutdown(有序关闭)会做什么?会等现有工作都完成吗?
- shutdownNow(尝试立即关闭)与 cancel(true)(尝试取消并请求中断)能保证立即停吗?
- 取消导出时,请求方和执行方怎样配合?
- return(退出方法语句)、break(跳出循环语句)与 finally(最终清理代码块)在取消中有何区别?
- 休眠收到 InterruptedException(中断异常)后,只打印错误继续行吗?
- 报表和短信隔离后,就能保证短信100毫秒完成吗?
- 下游允许并发10个,每条100毫秒,理想处理速率是多少?
- 允许等待2秒,按100条/秒估算队列容量是多少?
- 下游只有10个并发名额,本地增加到20个有什么问题?
- 验证码满载时,为何可以明确拒绝而非不断扩大队列?
- 两个应用各允许10个,同时满足系统共享上限10吗?
- 怎样完整说短信配置与结果确认?
MySQL(关系型数据库)索引:选型与验证
- 查询条件是部门等值、状态等值、提交时间范围。联合索引按“部门、状态、时间”和按“部门、时间、状态”排列,差别在哪里?
- 二级索引里已有部门、状态、提交时间和主键编号。页面只显示这四项,与页面再加一个申请人姓名,访问上有什么不同?
- 加了索引、用 EXPLAIN ANALYZE(实际执行分析)看过计划,怎样才能说明这个索引确实有效?
- 只有“按部门管理”“按状态查看”这类场景线索时,怎样提出具体的索引候选?加索引的代价应该怎么说?
MySQL(关系型数据库)事务边界与隔离级别
- 更新办件状态和插入审批记录,默认 autocommit(自动提交)下为什么不能保证两步一起保存?第二条插入报普通重复键错误时,事务又该怎样结束?
- A在同一事务里先普通查询,B修改该行并提交,A再普通查询。READ COMMITTED(读已提交)和 REPEATABLE READ(可重复读)下,A第二次各读到什么?为什么?
- 两个经办人可能同时审批同一件办件。普通查询读到“待审批”后直接更新,能防止重复审批吗?应该怎样保护?
- 规则是一件只能审批通过一次、只生成一条通过记录。A、B各自在事务内按主键锁定查询→核对状态→更新→新增记录→提交。A先完成并提交,B取得锁后读到“已通过”。B还要修改吗?B的事务怎样结束?
MVCC(多版本并发控制)与可见版本
- 已有行被改过几次后,普通查询怎样找回旧值?主例中103写出的版本为什么可见?
- A在同一个显式事务里自己不写:第一次普通查询读到9,随后其他事务依次把值改成11、13并提交。A第二次普通查询,读已提交和可重复读各返回什么?
- Read View(读视图)里保存的是上一次的查询结果吗?
- A的旧视图上边界是110。另一个事务的编号恰好是110,后来修改了这行并提交。A复用旧视图、自己不写,能看到这个版本吗?
- 报表在可重复读事务中查完后,事务一直开着等用户操作十分钟,同时别人不断修改数据,会有什么问题?应该怎样调整?
MySQL(关系型数据库)锁范围与等待处理
- [表中只有10、20、30号办件,办件编号是主键。A持有 (10,20] 的X临键锁时,B分别新增15号、修改20号的经办人,各自为什么要等待?如果A只持有 (10,20) 的纯间隙锁呢?](/rejava/lessons/0013-mysql-locks/#q1301)
- A持有10号的锁、等B释放20号;B持有20号的锁、等A释放10号。数据库已开启死锁检测,要先等到锁等待超时才会处理吗?
- 死锁后数据库回滚了A整个事务,业务允许重试。只重跑最后失败的那条更新可以吗?
- A锁定读取20号后不结束事务,等页面用户点确认;B要修改20号,正在等A。这是死锁吗?让双方按同一顺序申请锁能解决吗?
- “展示页面→用户确认→正式修改”的流程,事务应该怎样安排?正式修改包含两条必须一起成功的SQL时又怎样处理?
事务日志与崩溃恢复
- buffer pool(缓冲池)和 log buffer(日志缓冲区)各放什么?断电重启后,数据库从哪里拿到 redo log(重做日志)来补回已提交的修改?
- binlog(二进制日志)是不是数据的备份?要把数据库恢复到上午9点15分,需要哪两样东西、怎样配合?
- undo log(撤销日志)和 redo log(重做日志)各自记的是什么?
- 崩溃时,一笔事务在InnoDB(事务存储引擎)里处于准备状态,完整binlog(二进制日志)事务已经可靠保存。恢复时提交还是回滚?依据是什么?
- 提交时连接断开,应用没有收到成功响应。应用接下来应该怎样处理这次审批?
- 把 innodb_flush_log_at_trx_commit 从1改成2、sync_binlog 从1改成0,会给“成功后不能丢”的业务带来什么风险?评估这项改动前要核对哪些事实?
慢 SQL 定位与优化
- 办件号 case_no 是 VARCHAR(20) 并建了索引,Java代码却把办件号当 Long 传进SQL。为什么索引用不上?
- 联合索引是 (dept_id, status, submitted_at)。查询只给 dept_id = 10、漏传 status 时,索引的哪一部分用不上?会有什么后果?
- SQL写法完全正确,执行计划里 key(实际使用的索引)仍为 NULL,可能是什么原因?
- 改写后怎样证明慢SQL真的变快了?EXPLAIN(查看执行计划的语句)和 EXPLAIN ANALYZE(实际执行并分析)各给什么?上线后还看什么?
- 列表页打开很慢,应该按什么顺序排查?
- deferred join(延迟关联)多了一层子查询,为什么反而能让深分页变快?
Redis(内存数据存储)数据类型与单线程模型
- 存一个办件对象时,用String(字符串类型)存JSON还是用Hash(哈希)?
- Redis(内存数据存储)一个线程照看很多连接,某个连接的数据还没到时,它是排队等这个连接,还是先做别的?
- 为什么一条慢命令(例如KEYS)会让所有客户端都变慢?
- 覆盖一个键的值、又想保留原来的过期时间,SET要加什么选项?
- 举一个会让缓存过期时间丢失的代码写法,应该怎样改?
- 过期的键是怎么被删除的?是靠定期把所有键扫一遍吗?
- 统计整个库里以 case:detail: 开头的键,和取一个几十万成员的集合,分别该用什么?
- 介绍Sorted Set(有序集合)时,应该先说什么?
Redis(内存数据存储)持久化:RDB 与 AOF
- RDB(快照文件)和AOF(追加写日志)都开、appendfsync(追加日志刷盘策略)为no;dump.rdb比AOF(追加写日志)已落盘的内容更新。断电重启后,Redis(内存数据存储)用哪个文件重建数据?
- 正常关闭、Redis(内存数据存储)进程崩溃(或 kill -9)、整机断电,在everysec下各丢多少?为什么不同?
- Redis(内存数据存储) 7.0起,AOF(追加写日志)重写期间的新写入由谁记录?重写完成后怎样切换?
- appendfsync(追加日志刷盘策略)everysec 最多丢多少?是“最多2秒”吗?
- appendfsync(追加日志刷盘策略)always 是不是完全不丢数据?
- 追求最高安全时用 always+RDB(快照文件),主要代价是什么?
- 在一个只开RDB(快照文件)、已有数据的实例上开启AOF(追加写日志),正确步骤和命令是什么?