
1. 这两门课在入试里到底考什么先交代背景。我是在备考日本大学院情报系修士课程笔试专门科目里数据库和软件工程基本上是出镜率最高的两门。这个系列已经写到了第6期前几期分别整理了算法、计算机组成原理、网络和操作系统这期把数据库データベース和软件工程ソフトウェア工学一起收尾。为什么把这两门放在一起练因为它们在入试笔试里有一个共同特点看起来是文科实际上是理科。数据库考的是规范化理论、关系代数、事务并发这些有标准答案的东西软件工程表面上在考概念背诵但真正拉开差距的是UML补图、测试用例设计、需求分析题这种需要你动手写答案的部分。很多考生复习时把这两门课当成“背完就完事”的科目结果栽在计算题和应用题上。先说数据库。日本大学院入试的数据库题目主流出题方向非常固定关系代数表达式、SQL查询、函数依赖与范式分解1NF到BCNF、事务的ACID特性与隔离级别、并发控制锁、时间戳、MVCC、B树索引与查询优化。其中关系代数和范式分解是几乎所有学校都考的一些上位校东大、京大、东工、阪大这类还会追加事务隔离级别的场景判断题和基于成本的优化选择题。软件工程则不同它的题型更依赖学校风格。有的学校偏传统考瀑布模型、软件开发过程、项目管理、COCOMO成本估算有的学校偏现代考敏捷开发、Scrum、DevOps有的学校喜欢考UML让考生补全类图、时序图或者从一段需求描述里识别用例还有的学校会考设计模式GoF23种里最常见的那几个——单例、工厂、观察者、策略、软件测试的覆盖度计算语句覆盖、分支覆盖、路径覆盖。这一期我就按“高频考点典型例题错题分析”的方式来做每个科目挑重点题型拆解一遍最后再单独讲一下过去问的使用方法和答题时间分配。2. 数据库问题训练从关系代数到事务隔离2.1 关系代数与SQL的换算练习关系代数题目在大学院入试里几乎是必出内容而且出题方式很固定要么给你关系模式和查询需求让你写关系代数表达式要么给你关系代数表达式让你解释它查的是什么要么同时让你写SQL和关系代数互相对照。第一个高频题型选择σ、投影π、连接⋈的组合使用。这里的核心难点不是记住符号而是搞清楚两个最容易被忽略的细节选择σ是筛选行的条件是写在右下角的投影π是筛选列的属性列表写在右下角。很多同学在写表达式的时候把σ的下标写成了要查询的属性列把π的下标写成了条件这个一颠倒整个题意就错了。自然连接和条件连接的区别。自然连接会自动去掉重复的同名列条件连接θ连接保留全部属性。入试里99%的题目用的是自然连接但如果你遇到一道题既写了⋈又写了具体条件要意识到这是θ连接写结果时别把重复列合并了。举个实际例题。教务系统有三张表学生学籍番号氏名学科 科目科目番号科目名単位数 履修学籍番号科目番号成績需求是“查询选修了‘数据库’这门课且成绩在80以上的学生姓名和学籍号”。关系代数写法π[学籍番号, 氏名]( σ[科目名数据库 ∧ 成績80]( 学生 ⋈ 履修 ⋈ 科目 ) )这里有几个考试中容易踩的坑。第一先做选择再做连接的效率更高所以正确的习惯是先对科目表做σ[科目名数据库]缩小了参与连接的关系大小再去做连接。虽然笔试不强制要求写优化后的表达式但改了卷子多的教授看到先σ再⋈的写法会认为你有基本的优化意识印象分会好一点。第二三个表连接时连接顺序怎么确定最稳妥的做法是找共同属性学生表和学生表的共同属性是学籍番号履修表和科目表的共同属性是科目番号。所以两个两两连接都能连上写成(学生⋈履修)⋈科目或者学生⋈(履修⋈科目)都是对的。第三成绩80这个条件注意它只作用于履修表跟科目表无关。所以可以先对履修表做σ[成績80]这样在连接前就已经把不满足成绩条件的数据排除了。这一点在答题时写清楚阅卷老师会觉得你的思路很清晰。关系代数和SQL互转这个题型我自己练下来觉得最重要的是把SQL语句拆成“先FROM、再WHERE、再GROUP BY/HAVING、再SELECT”的结构去理解而不是按SELECT出现的顺序去读。比如上面那个查询SQL就是SELECT s.学籍番号, s.氏名 FROM 学生 s JOIN 履修 r ON s.学籍番号 r.学籍番号 JOIN 科目 c ON r.科目番号 c.科目番号 WHERE c.科目名 数据库 AND r.成績 80;写SQL的时候注意是三表连接最容易漏掉中间那张履修表变成学生和科目直接JOIN这在语义上就错了——学生和科目之间是多对多关系不能直接连接。2.2 范式分解的套路1NF到BCNF范式的计算题是数据库笔试里区分度最高的一块。不是因为它难而是因为很多同学只背了范式的定义没消化“分解的判定条件”一到实际分解就不知道从哪下手。我建议把范式判断按这样一个流程来走找候选键。这是所有范式判断的前提。候选键是能唯一标识元组的最小属性集合。找候选键的方法有两种如果函数依赖关系图简单直接标出哪些属性不被其他属性决定这些必然在候选键里然后再去验证闭包如果依赖关系复杂就用属性闭包算法逐一尝试。判断1NF。这个最简单所有关系模式默认都是1NF即属性都是原子的、不可再分的。判断2NF。2NF要求消除部分依赖即非主属性不能依赖于候选键的某个真子集。这里的前提是候选键必须是组合键如果候选键只有一个属性那这个关系模式天然满足2NF。判断3NF。3NF要求消除传递依赖即非主属性不能传递依赖于候选键。判断BCNF。BCNF要求每个非平凡函数依赖的左侧都包含候选键。考试中最爱考的是让你把一个关系模式分解到3NF或BCNF。分解的标准方法是无损连接分解和保持函数依赖分解算法用到了属性闭包和最小函数依赖集。拿一道典型的题目来演示。已知关系模式R(A, B, C, D, E)函数依赖集F {A→B, B→C, AB→D, D→E}问它是否满足3NF如果不满足就分解到3NF。第一步求候选键。看哪个属性不在任何函数依赖的右侧A出现在右侧了吗没有。B出现在右侧吗没有——等等B在A→B和AB→D的右侧都出现了所以B是依赖于A的不能单独作为候选键。逐个看C只在右侧B→CD只在右侧D→EE只在右侧。所以唯一的候选键是A不对还需要验证A的闭包A→BB→C所以A {A,B,C}。然后AB→D此时A已经包含B所以A扩展为{A,B,C,D}。D→EA再扩展为{A,B,C,D,E}。所以A确实是候选键且是唯一的候选键。第二步判断是否符合BCNF。候选键是A看每个函数依赖A→BA包含候选键OK。B→CB不包含候选键A违反BCNF。AB→DAB包含候选键AOK。D→ED不包含候选键A违反BCNF。所以不符合BCNF。再判断是否符合3NF3NF允许函数依赖的右侧是主属性。这里C、E不是主属性而B→C和D→E的左侧B、D都不是超键所以也不满足3NF。第三步做3NF分解。先对函数依赖集做最小化处理然后按依赖分组{A,B}由A→B产生{B,C}由B→C产生{A,B,D}由AB→D产生{D,E}由D→E产生。合并有相同左侧的分组后得到如下候选分解R1(A,B) 依赖A→BR2(B,C) 依赖B→CR3(A,B,D) 依赖AB→DR4(D,E) 依赖D→E注意这里的R1和R3有重叠属性A和B可以合并成R3(A,B,D)但保留R1也不是错只是分组冗余。考试中一般要写成4个模式然后说明哪些可以合并如果直接合并成3个说明能识别冗余分数会更高。这个题型做题的关键就是一步步写清楚候选键→违反哪条范式→分解→验证无损和依赖保持。别跳步阅卷是按过程给分的。2.3 事务与并发控制隔离级别、锁、MVCC事务这块的考题很少让你写代码更多是场景判断题。最常见的出题方式有两种给你一个并发调度的执行顺序问你它是否可串行化、有没有脏读/不可重复读/幻影读或者问你给定隔离级别下某个事务会不会出问题。判断可串行化的标准工具是优先图precedence graph。我建议你考试时一定把这个图画出来哪怕题目没要求它也是你推理的基础。画法很简单每个事务是一个节点如果事务T1的一个操作在T2的某个冲突操作之前执行且它们作用于同一数据项就画一条T1→T2的边。冲突操作就是读-写或写-写对。最后看有没有环有环就不可串行化没环就是冲突可串行化的。至于脏读、不可重复读、幻影读我的记忆方法是脏读读到别人没提交的数据别人回滚了就变成读了个寂寞。不可重复读同一事务内两次读同一行结果不一样因为别的已提交事务改了这行。幻影读同一事务内两次执行范围查询结果的行数不一样因为别的已提交事务插入了新行。隔离级别和这几个异常的对应关系几乎每年都考隔离级别脏读不可重复读幻影读Read Uncommitted可能可能可能Read Committed不会可能可能Repeatable Read不会不会可能InnoDB下通过间隙锁可避免Serializable不会不会不会MySQL InnoDB里Repeatable Read实际上通过间隙锁Gap Lock和Next-Key Lock基本杜绝了幻影读这也是面试和笔试里都喜欢挖的细节。不过入试如果只考教科书Silberschatz那种标准定义就按上表答审题时要留意有没有“InnoDB”这个词出现。并发控制机制的选择题里还常考锁的相容性。**共享锁S和排他锁X**的相容矩阵必须刻在脑子里S和S相容其他都互斥。升级锁意向锁的相容性则容易混淆记住“意向锁之间相容但意向X和普通X不兼容”就基本够用了。MVCC多版本并发控制这些年出现在入试的频率越来越高尤其是有数据库方向教授的出题组。考法主要是为什么MVCC能提高并发度答案要点是读操作不阻塞写操作读历史版本写操作仍需要加锁。考试时别忘了提“读不加锁”这个核心特性。2.4 索引与查询优化B树与执行计划索引的考查范围集中在这几块B树索引的结构理解、聚簇索引与非聚簇索引的区别、索引失效的场景、执行计划中索引选择的基本逻辑。B树部分最常考的是计算题给定数据量、每个节点能容纳的键数量求树高、IO次数、或者叶子节点数量。做题的公式很简单非叶子节点的扇出乘方就是它能索引的最大区间的数量。比如扇出为100的3层B树根中间层叶子层可以索引约100万条记录。还有一点要注意B树的叶节点之间用链表相连所以范围查询只需要找到起始叶节点然后顺序遍历后续叶节点不需要回到根节点重新查找——这是B树优于B树做范围查询的核心优势考试经常把这个作为简答题。聚簇索引和非聚簇索引的区别要记清楚聚簇索引叶子节点直接存储整行数据或聚集索引键行数据表数据的物理顺序和索引顺序一致。每张表只能有一个聚簇索引。非聚簇索引叶子节点存储索引键指向数据行的指针主键值每张表可以有多个非聚簇索引。查询优化最容易考的是让你根据一个SELECT语句和几张表的统计信息判断哪种连接策略最优。核心思路就是比较嵌套循环连接Nested Loop Join、排序合并连接Sort-Merge Join、哈希连接Hash Join的成本。当数据量小时嵌套循环可能更快数据量大时哈希连接通常是最优解这个判断逻辑在笔试里要会写出来不要只说结论。3. 软件工程问题训练不只是背概念3.1 开发流程与工程方法的选择题陷阱软件工程的笔试选择题考的不是知识面而是概念的精确边界。举个例子瀑布模型的特点是“阶段间有反馈回路吗”教科书标准定义说瀑布模型各阶段是线性顺序、文档驱动、阶段间有反馈。有的同学看到“反馈”两个字就觉得矛盾其实瀑布模型并非完全没有反馈只是反馈的范围局限于相邻阶段不允许跨阶段大步回退。入试选项里如果出现“瀑布模型各阶段完全独立、无反馈”这种绝对化表述那肯定是错的。敏捷这块考的是对宣言的理解。个别学校教授喜欢出“以下哪个不是敏捷开发实践”这种题选项中混入“严格的预先设计Big Design Up Front”和“持续交付”前者不是敏捷实践后者是。这类题只要你真跑过一个敏捷项目基本秒选但如果没经历过就要靠记忆区分敏捷实践和传统实践的特征列表。COCOMO成本估算模型是软件工程里少数需要计算的题。基础COCOMO的工作量公式是E a × (KLOC)^b其中a和b的取值取决于项目是组织型organic、半分离型semi-detached还是嵌入型embedded。考试时公式通常会给你或者让你背常数表。但括弧中的陷阱是KLOC和LOC的单位换算有的题给的是1000行代码有的给的是万行不换算就错。软件质量的McCall模型、ISO 9126/25010质量特性也常出匹配题。建议把ISO 25010的八大特性——功能性、性能效率、兼容性、易用性、可靠性、安全性、可维护性、可移植性——和各自的定义对应起来特别是“可移植性”和“兼容性”很容易混前者是换环境跑的能力后者是同一环境下协同工作的能力。3.2 UML图的识图与补图UML是日本大学院入试软件工程科目的重头戏基本上占了三分之一的分值。考的题型很固定给你一段需求描述让你补全用例图或类图给你一个类图让你解释各关系的含义或者给你一段时序图让你补消息顺序。用例图Use Case Diagram补全题我自己总结了一个“三步走”原则找参与者Actor从需求文本里找出所有和系统交互的角色包括人和外部系统。找用例Use Case每个业务目标是一个用例注意“登录”“注册”这种通常不是独立用例而是被 包含的公共功能。确定关系用例之间用 表示“一定会包含的子流程”用 表示“可选扩展流程”。这两者的区别是必考点——include是主流程的一部分没有它用例不完整extend是可选分支比如“下单”这个用例可以extend出“使用优惠券”。类图补全题的考点更集中多重性的标注是考试最容易踩坑的地方。给你一段业务描述比如“一个顾客可以下多个订单一个订单只能属于一个顾客”如果不加思考直接画顾客1对多订单多数情况下没问题但有些学校喜欢考关联类和反射关联比如“一个员工可以管理多个员工”这种自关联多重性标注就要小心了。时序图题则是考消息的排列顺序和返回消息。答题时注意“同步消息用实心箭头、返回消息用虚线箭头”这个标准在UML2.x里是这样规定的但有的教材用的是UML1.x画法审题时先看清学校用哪版不确定就在答题时用文字补充说明。3.3 设计原则与模式的应用题这几年设计模式题目在入试中明显变多了原因很实际——教授们希望招到能写代码、能设计系统的学生而不是只会背书的人。考察方式通常是给你一个具体场景问你“哪种设计模式最适合”比如需要在系统里为某个类的实例保持唯一性答案是单例Singleton当算法族可能在运行时切换时用策略Strategy当对象状态改变时需要通知一组依赖对象时用观察者Observer需要在不修改现有类的前提下扩展功能时用装饰器Decorator或适配器Adapter。这些不是背名称而是能解释为什么。SOLID原则单一职责、开闭、里式替换、接口隔离、依赖倒置也是考得高频的内容。题目一般有两种第一种是判断一个设计违反了哪个原则比如在一个类里既做业务逻辑又做持久化显然是违反了单一职责第二种是给你一段重构前后的代码让你判断符合了哪些原则。答题的时候建议用“违反了/遵循了什么原则原因”的格式不要只写一个词。这里有个值得注意的冷门考点设计模式不是万能的。个别教授在改卷时会期待你指出“模式的应用有时会增加不必要的复杂度”。如果题目问“这个场景适合用什么模式”你可以在回答里补充一句“也可以用XX模式但会在YY方面引入额外开销”这种回答反而更容易拿高分因为它展示的不是知识储备而是工程判断力。3.4 测试策略与质量指标的换算软件测试在入试里属于“会就是送分不会就是送命”的题目因为它的题型极其标准但计算容易出错。白盒测试的覆盖度计算题几乎是必考核心概念是语句覆盖每个语句至少执行一次、分支覆盖每个判断的真假分支都至少走一次、路径覆盖每条可能的执行路径至少走一次。做题方法就是先把程序的控制流图画出来然后给输入用例按图走路径统计哪些语句、哪些分支、哪些路径被覆盖了最后算比例。我练这些题的时候总结出一个口诀先画图再标记后统计。画控制流图时每个判断框的连接线要标上T/F统计时语句覆盖和分支覆盖可以一起标记路径覆盖则要单独数从入口到出口的不同路径数。单元测试的JUnit/参数化测试、集成测试的驱动桩、系统测试的黑盒边界值分析Boundary Value Analysis也是高频考点。边界值分析最容易考的是“输入范围是1到100合法边界值和非法边界值各是什么”答案是0、1、100、101这四个都要测。等价类划分则是把输入划分成有效类和无效类每类取一个代表值去测。4. 实操题怎么练过去问的用法与时间分配4.1 过去问搜集与优先级备考大学院笔试最重要的一件事就是把过去问搞到手。日本大学的过去问公开情况分三种直接在研究科网站挂出来随便下载这样的学校越来越多比如东京大学情报理工学系研究科。需要到学校图书馆或者事务室复印办理入馆手续即可。完全不公开遇到这种学校就只能靠前辈回忆版或者塾里的复现题。我的建议是确定目标校之后先把过去三年份的过去问全部下载打印然后做一次“出题倾向分析”。比如你发现某校数据库每年固定考一道范式分解大题一道SQL一道并发控制简答那么复习时范式分解就必须练到闭着眼睛都能写而索引的B树计算题如果三年都没出过可以适当降低优先级但不要完全不看因为第四年可能就出了。4.2 答题顺序与时间分配笔试专门科目一般是60分钟到90分钟题量通常是2到4个大题。这里我分享一个自己试过多次的顺序先做会做的大题里分值最高的那道。为什么要这样因为入试笔试的分数来源不是“你会多少”而是“你最后写出来的正确答案有多少”。先做高价值题目能确保你拿到基本盘剩下来时间再啃难题哪怕没做出来过程写得工整也能拿步骤分。如果是6选3这种选答题型务必先浏览完全部题目再做选择。1995年左右开始不少学校的选答是“4问中选2问解答”这种题型的时间分配策略是第一遍用5分钟快速判断哪几问问得最顺手然后直接略过难题。千万别看完第一题就开始写写了十分钟才发现这题其实特别耗时后面两道简单题就来不及了。4.3 记笔记的方法备考笔记这个事我的经验是不要做“抄书笔记”。我在备考前期做过一个蠢事用了一整本A4笔记本把数据库教科书的章节标题、概念定义、图全部重新抄了一遍。结果回头看这些笔记跟教科书完全没区别复习时还得翻教科书笔记形同虚设。真正有用的笔记是出错题本。每次练习模考、过去问、参考书习题时把错题和犹豫题记录下来格式固定为四栏题目来源、我的错误答案、正确答案、错误原因分析。错误原因分析是关键不能只写“记错了”“算错了”要写“函数的闭包求错了漏掉了传递依赖AB→D推出A→D这步”第三遍复习时一眼看到就能精准击中自己的薄弱点。我还习惯每周做一次知识结构图手写的不是画正式的图把一周学的所有知识点用箭头连接成一张大网标注“会了”和“还有点模糊”的区域。这种自测比做新题更能暴露问题——做题时蒙对的题在结构图里会暴露成“模糊区”。5. 实战常见错误与备考心得5.1 我踩过的坑第一个大坑是复习范围过广、往深里钻。数据库和软件工程这两门课看似范围无限大数据库有分布式数据库、NoSQL、NewSQL软件工程有软件架构、微服务、安全工程。如果每块都学透时间是绝对不够的。我后来才想明白大学院入试是应试不是做研究目标应该是“覆盖80%的出题范围并做到90%的正确率”而不是“100%的内容都掌握”。第二个坑是不写过程、只看答案。我在练范式分解的时候有一阵子因为步骤太熟练直接在草稿纸上写个分解结果就对了答案正确率看起来还行。但等到做整套过去问时发现正式答题卡上需要写清楚“为什么这个分解是无损的”“为什么函数依赖被保持了”如果不练这个过程描述到考场上会不知道怎么写才能让阅卷老师信服。第三个坑是忽视日语术语的表记。报考日本大学院笔试是日语答题很多术语要写片假名或汉字。我身边有朋友在面试和笔试里因为写了中文简体字“数据”而不是“データ”被扣分了。这不是歧视简体字而是答题规范的问题——教授改卷时看到不规范的术语会认为你不够认真。备考时建议把每章的核心术语做一张中日对照表比如关系代数関係代数、函数依赖関数従属、范式正規形、事务トランザクション、并发控制並行制御、用例图ユースケース図、类图クラス図、设计模式デザインパターン。5.2 推荐工具与资源数据库这块我推荐用实际数据库环境来验证SQL题。我在备考期间电脑上装了MySQL和SQLite两个环境遇到不确定的SQL写法的题直接在本地跑一下比翻书猜靠谱得多。特别是涉及LEFT JOIN、子查询、聚合函数加GROUP BY的场景实际执行一下答案的语义边界就清楚了。软件工程这块没有类似的“运行环境”但我发现一个好方法用画图工具把UML图练熟。我在平板上用draw.io画用例图和类图把每个学校过去问里的图和自己的答案都画一遍既练了画图速度又练了识图能力。叫我在纸上用手画UML画得歪歪扭扭不说连接关系经常被自己涂改到看不清用工具画完再看打印版连多重性标注的方向错误都能一眼看出来。还有一个强烈推荐的资源过去问解答的博客和笔记。搜索“大学名専門科目解答”往往能找到已经入学的前辈写的解答PDF。这些解答虽然不是官方标准答案但至少能告诉你解题思路和答案布局。同一道题看两个人以上写的解答还能发现不同的解题角度这对于拓展思维很有帮助。5.3 冲刺阶段的复习策略从我的个人经验来看考前一个月应该是这样安排的第一周到第二周把过去问从旧到新做一遍第一遍不计时目的是吃透第三周做第二遍最新年份的过去问严格计时模拟考场第四周停止做新题全力复习错题本和知识结构图。冲刺期最重要的一步是模拟整套笔试、完整答题。我模拟时会把答题纸也用起来——用A4纸按考试要求画好答题区域把全部答案写上而不是在题目旁边写几个关键词就算了。这样做的好处是能训练答题速度。我第一次模拟软件工程试卷时发现一套题居然写了将近70分钟才写完离考试结束只剩20分钟后面的题只能简写。练过几次后时间就从容多了。考试前一天我不建议再刷题只需要做两件事把错题本从头到尾看一遍把知识结构图上标“还有点模糊”的区域翻教科书确认一遍。这两件事做完比刷十道新题都管用。最后分享一个实际的体会数据库和软件工程这两门课的备考效率其实比算法和网络高很多因为它们的题型高度套路化。只要把关系代数、范式分解、并发控制、UML补图、设计模式这几类核心题型练到“见题就能写”的程度再做整套过去问时心态会稳很多。我在第5次模拟的时候数据库部分提前二十分钟写完软件工程部分也只超时了三分钟那种“每道题的考点都在掌握范围内”的感觉就是备考后期的正常状态。如果你现在做题还在不断犯错别慌把错题本好好整理出来按上面的方法再过一轮正确率自然会上去。