edyang

我干了什么 究竟拿了时间换了什么
技术分享时间线软件开发、设备接入、视觉与运维实践

透彻学习 JDK 7:HashMap 的桶、冲突与扩容

研究 HashMap 要固定版本。

研究 HashMap 要固定版本。Java 7 的冲突处理不能直接套用后续版本的树化机制。 本文使用JDK 7,示例为方法体或类定义片段。源码学习需要区分语言规则、公共接口约定与某个版本的实现。本文把讨论范围固定在 Java 7,不把后续版本的集合结构或语法写进来。 1. 从现象推到机制 键的散列值参与桶下标计算,同桶多个元素还需要逐个比较键。负载因子决定触发扩容的阈值,容量与元素数是...

透彻学习 JDK:ArrayList 扩容与遍历删除

列表增加元素通常很快,但扩容时需要复制数组。

列表增加元素通常很快,但扩容时需要复制数组。理解均摊成本,也要留意迭代器的修改约束。 本文使用JDK 7,示例为方法体或类定义片段。源码学习需要区分语言规则、公共接口约定与某个版本的实现。本文把讨论范围固定在 Java 7,不把后续版本的集合结构或语法写进来。 1. 从现象推到机制 ArrayList 的连续引用数组支持按下标访问,插入到中间则需要移动后续元素。扩容带来的复制是偶发成本...

透彻学习 JDK:equals 与 hashCode 必须一起设计

把自定义对象放进 HashSet 后,明明相等却仍然重复,通常需要检查散列契约。

把自定义对象放进 HashSet 后,明明相等却仍然重复,通常需要检查散列契约。 本文使用JDK 7,示例为方法体或类定义片段。源码学习需要区分语言规则、公共接口约定与某个版本的实现。本文把讨论范围固定在 Java 7,不把后续版本的集合结构或语法写进来。 1. 从现象推到机制 相等对象必须返回相同散列值,散列相同却不代表相等。容器先利用散列缩小查找范围,再用相等判断匹配;只覆盖 eq...

透彻学习 JDK:String 相等与常量池

String 看起来一样,引用却可能不同。

String 看起来一样,引用却可能不同。判断业务文本相等时,需要先分清值相等与对象身份。 本文使用JDK 7,示例为方法体或类定义片段。源码学习需要区分语言规则、公共接口约定与某个版本的实现。本文把讨论范围固定在 Java 7,不把后续版本的集合结构或语法写进来。 1. 从现象推到机制 字符串字面量可进入常量池,new 创建的对象并不因此与字面量有相同引用。equals 比较字符内容...

软考复习:策略、工厂和适配器不要混用

设计模式名称记得很多,遇到题目仍可能选错。

设计模式名称记得很多,遇到题目仍可能选错。有效的判断入口是“变化发生在哪里”,而不是看到接口就套策略模式。 本文使用经典算法与关系数据库的纸面例题。复习时把概念放进一个可手算的小问题:先声明假设,再列状态变化,最后检查反例。题目中的边界条件往往比公式本身更容易失分。 1. 从现象推到机制 策略封装可以替换的行为,工厂集中对象创建,适配器转换不兼容接口。一套支付演示可以同时包含三者:选择...

软考复习:关键路径与总时差怎样手算

项目中最耗时的任务未必在关键路径上。

项目中最耗时的任务未必在关键路径上。关键路径由依赖关系和累计工期决定,不能按单项任务排序得到。 本文使用经典算法与关系数据库的纸面例题。复习时把概念放进一个可手算的小问题:先声明假设,再列状态变化,最后检查反例。题目中的边界条件往往比公式本身更容易失分。 1. 从现象推到机制 先正向计算最早开始和最早完成,再反向计算最迟开始和最迟完成。汇合节点必须等所有前置完成,所以正向取最大值;反向...

软考复习:从订单表拆出函数依赖与第三范式

订单表里同时放客户地址和商品名称,查询看起来方便,修改时却会出现多个版本。

订单表里同时放客户地址和商品名称,查询看起来方便,修改时却会出现多个版本。范式首先解决的是事实重复保存的问题。 本文使用经典算法与关系数据库的纸面例题。复习时把概念放进一个可手算的小问题:先声明假设,再列状态变化,最后检查反例。题目中的边界条件往往比公式本身更容易失分。 1. 从现象推到机制 先确定一行代表什么,再写函数依赖。订单明细的候选键可以是订单号与行号的组合,商品名称依赖商品号...

软考复习:补码、溢出与位运算边界

补码计算容易把“二进制结果”与“它代表的有符号整数”混在一起。

补码计算容易把“二进制结果”与“它代表的有符号整数”混在一起。先固定字长,才能判断溢出。 本文使用经典算法与关系数据库的纸面例题。复习时把概念放进一个可手算的小问题:先声明假设,再列状态变化,最后检查反例。题目中的边界条件往往比公式本身更容易失分。 1. 从现象推到机制 八位有符号补码的范围是不对称的,最小负数的绝对值无法用同样位数的正数表示。进位位不等于有符号溢出位:两个正数相加得到...

软考复习:用迷宫理解栈、队列与搜索

栈和队列都能保存待访问节点,差别会直接改变搜索顺序。

栈和队列都能保存待访问节点,差别会直接改变搜索顺序。用一个小迷宫比较,比孤立记忆定义更有效。 本文使用经典算法与关系数据库的纸面例题。复习时把概念放进一个可手算的小问题:先声明假设,再列状态变化,最后检查反例。题目中的边界条件往往比公式本身更容易失分。 1. 从现象推到机制 深度优先搜索保存尚未完成的路径,适合用栈回退;广度优先搜索按层扩展,适合用队列。在无权图中,首次按层到达终点的距...

软考复习:时间复杂度到底在数什么

同一个双重循环,内层边界不同,增长速度可能完全不同。

同一个双重循环,内层边界不同,增长速度可能完全不同。复习复杂度时,先把输入规模和基本操作说清楚。 本文使用经典算法与关系数据库的纸面例题。复习时把概念放进一个可手算的小问题:先声明假设,再列状态变化,最后检查反例。题目中的边界条件往往比公式本身更容易失分。 1. 从现象推到机制 顺序执行的两段循环取较大增长阶,嵌套循环则需要求和。若内层从零走到外层下标,总次数是等差数列,不是凭代码里有...