IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者
首页 / 梦想风暴
IT 2014-12-02 23:32:03 / 累计浏览 2,060

战斗HTTP

作者从一个棘手的线上问题出发,讲述了一场与HTTP协议“战斗”的完整经历。他的同事在使用Mock工具Moco进行测试时,遇到了连接莫名挂住的怪象,且现象时有时无,极难复现。 排查过程一波三折。从最初怀疑测试框架本身,到单步跟踪发现“挂住”发生在Netty框架层面,甚至怀疑是框架缺陷。直到作者注意到Moco代码中一句强制关闭连接的逻辑,而客户端请求却带着 `Connection: keep-alive`,才初窥门径。问题在于,当服务器不支持长连接却强行关闭,而客户端期望保持连接并继续读取数据时,双方就陷入了“死锁”。 但故事并未结束。修复后,另一个单元测试又“挂”了。通过反复比对,作者最终发现了问题的核心:当服务器支持keep-alive时,如果响应中没有 `Content-Length` 头,客户端将无法得知需要读取多少数据,从而无限等待。最终的解决方案是:在保持连接的响应中,若缺少该字段则主动补全。 这篇记录展现了排查复杂问题的典型路径:从现象到假设,再由新线索推翻假设,循环逼近真相。它不仅剖析了HTTP协议中连接与数据读取的交互细节,也凸显了团队协作与刨根问底精神的价值。

本机暂存
IT 2013-09-23 13:36:30 / 累计浏览 3,140

打开视野

这篇讲的是作者在ThoughtWorks做面试官时,观察到一种普遍的成长瓶颈。许多在原公司表现不错的程序员,面试时却在宏观思考和问题陈述上显得零散,因为他们长期只负责执行被“嚼碎”的具体问题,视野被日常项目所限。 作者指出,视野的局限会让程序员误把“局部峰值”当成自己的水平。他给出的解药是主动打破环境限制:通过互联网接触更广阔的天地和高手的思维方式;阅读经典书籍进行系统学习;以及走出去参加技术聚会,以近乎零成本的方式与不同经验的人交流。 文章最后,作者用自己早年的故事做了印证:当他在东软感到能力“过饱和”时,正是凭借对外部世界的好奇和探索,最终加入了能持续激发成长的ThoughtWorks。他想提醒的是,具体学什么、怎么学是后话,程序员最怕的是固步自封,第一步永远是把视野打开。

本机暂存
IT 2013-08-21 13:18:12 / 累计浏览 3,080

你应该更新的Java知识之Optional

这篇讲的是Java中一个常见却恼人的痛点:空指针异常(NPE)。作者从“Null Sucks”这句名言切入,指出传统上为了防御NPE而编写的判空代码,不仅冗余,还极易因疏忽而遗漏,导致程序崩溃。 文章的核心是介绍一种更优雅的解决方案:Optional。它并非简单替代if-null检查,而是通过封装可能为null的对象,强制调用者在使用前必须处理其“存在与否”的状态。作者具体展示了如何使用Optional.absent()、Optional.of()等方法创建对象,并演示了其链式调用如何轻松实现“若为空,则使用默认值”的逻辑,例如`person.or(manager).doSomething()`。 与需要为每个类定制的“空对象模式”相比,来自Guava库的Optional方案更为通用和轻量。虽然代码行数没有减少,但它将“是否为空”的判断从隐式的编程习惯,提升为了显式的、由类型系统保障的编码规范,从而在根源上提升了代码的健壮性。

本机暂存
IT 2013-05-01 17:42:26 / 累计浏览 1,300

从Moco谈程序库设计

这篇讲的是Moco这个Mock服务器框架背后的设计思考,核心问题是如何让一个程序库既强大又易用。 作者从Moco的两个基本任务切入:如何启停服务器,以及如何设置请求与响应。在启停服务器上,Moco没有让用户在每个测试中手动写try-finally来管理生命周期,而是通过一个`running`方法将细节封装,让接口保持简洁。 在设置请求响应时,作者非常强调DSL(领域特定语言)的价值。为了让API读起来像自然语言,Moco使用了`uri`、`method`这样的函数来包装对象创建,避免直接使用`new`打断表达的连贯性。同时,为了处理复杂的请求条件匹配,文章引入了“函数组合”的思路。在Java没有一等函数的情况下,Moco利用函数对象(functor)以及`and`、`or`运算符,让用户可以像搭积木一样组合多个匹配条件。 此外,文章还分享了利用类型系统进行安全设计的实践。例如,通过引入`ContentResource`子类型来区分需要与不需要Content Type的场景,让错误在编译期暴露。另一个巧妙之处是分离了公开接口`Setting`与内部实现`BaseSetting`,通过隐藏实现方法来防止用户误操作。 文章最后总结,好的程序库设计应当致力于简化用户接口、精心设计DSL、充分利用静态类型系统,并清晰地区分公开与内部接口。这些原则都是为了降低使用者的心智负担,提升开发体验。

本机暂存
IT 2013-03-07 13:54:53 / 累计浏览 4,000

实践中的重构

这篇讲的是,许多程序员对“重构”这件事怀有误解,而作者的核心观点是:重构绝非特殊阶段的“大工程”,而是贯穿日常编码的微习惯。 作者从日常工作切入,指出重构应和写代码、测试一样,是每个开发者的常规动作。他特别澄清了“重构”与“重写”的混淆——调整模块设计可能需要沟通技术债,但执行时仍需遵循重构原则。一个关键的前提是:“没有测试的重构就是耍流氓”,必须先为代码补足测试保障。 那么如何安全地重构?文章给出的标准是:能够“随时随地停下来,且不破坏任何测试”。这依赖于“小步重构”的实践——将大刀阔斧的修改拆解为一系列可验证的微小步骤。作者坦言,这需要刻意练习,与内心急于“一路劈杀”的冲动对抗。 重构易知难行,其精髓正在于将这种小步快跑的纪律,内化为肌肉记忆般的编码习惯。

本机暂存
IT 2013-01-18 13:53:13 / 累计浏览 6,620

你应该更新的Java知识之构建工具

这篇文章直指现代Java开发中一个常被忽视但至关重要的环节:构建工具的演进与选择。作者从早期的Ant和Maven谈起,精准地指出了它们的痛点——Ant过于手工化,而Maven在扩展性和灵活性上存在“致命伤”,以至于项目复杂后常需回归脚本编写。 随后,文章引出了新一代构建工具Gradle和Buildr。与Maven的XML不同,它们允许使用Groovy或Ruby这类更优雅的程序设计语言来编写构建脚本,极大地提升了灵活性和表现力。其中,Gradle被着重介绍:它拥有详尽的文档、商业公司的支持,并在尚未发布1.0版本时就已获得Spring大奖及Spring官方项目转投,证明了其强大的实力和社区认可度。 文章通过一个简洁的build.gradle脚本示例,直观展示了使用Gradle进行Java项目构建的清晰与便捷。作者的观点很明确:对于今天的Java项目,Gradle因其易用性、强大的扩展能力和活跃的生态,已成为更值得拥抱的现代构建方案。

本机暂存
IT 2013-01-16 14:18:14 / 累计浏览 3,600

Travis CI:专为开源项目打造的持续集成环境

这篇讲的是如何为GitHub上的开源项目接入Travis CI持续集成环境。作者以Java项目Moco为例,详细演示了从创建配置文件到最终在README中添加状态标识的全流程。 核心步骤非常清晰:首先在项目根目录添加`.travis.yml`文件,指定语言(如java)和需要测试的JDK版本(如Oracle JDK 7和OpenJDK 6/7)。Travis CI会自动识别如Gradle这样的构建工具,并执行标准的检查任务。接着,用GitHub账号登录Travis CI并同步项目,开启对应项目的构建钩子。这样,每次提交代码到GitHub,Travis CI就会自动在多个JDK环境下运行测试,确保兼容性。 文章还指出了一个实用技巧:可以在项目的README文件中嵌入Travis CI的构建状态徽章,让其他开发者一目了然地看到项目的构建状态。对于使用标准工具链的项目来说,整个配置过程确实“简单得一塌糊涂”,是开源项目实现自动化测试与集成的一个高效选择。

本机暂存
IT 2012-11-01 13:20:04 / 累计浏览 4,280

当我加入项目时,我要了解什么

这篇文章讲述了一位经验丰富的技术人员在频繁加入新项目时,如何快速把握全局并投入工作的核心方法。作者认为,理解项目应从三个层面循序渐进:首先是业务,目标不是纠缠细节,而是能在五分钟内清晰说明“这个系统是做什么的”,避免将技术细节与业务混杂讲解。 在技术层面,作者主张先宏观后微观。先确认整体技术栈(如Java或.NET),再借助一张系统架构图理清外部集成与内部模块划分。对于模块和层次,作者特别指出很多系统的问题在于模块职责模糊、依赖混乱,而清晰的分层结构是现代系统的关键。深入细节时,应从集成点入手(如了解MQ中传输的是XML),再探查源码目录结构,但不必在初始阶段过于深入。 最后,团队运作方式同样重要,例如站会、迭代会议的时间安排,是否存在常规的Code Diff或Session分享墙,以及与客户是否有定期沟通机制。作者通过这些问题往往能快速识别团队协作中的潜在问题。整体来看,这套结合业务、技术与团队维度的系统性了解路径,能帮助开发者在一到两天内建立对项目的完整认知,为后续高效协作打下基础。

本机暂存
IT 2012-09-10 22:58:53 / 累计浏览 7,620

聊聊ThoughtWorks面试

这篇分享的是一位应聘者亲历ThoughtWorks面试的全过程与深度思考。文章细致梳理了从技术笔试、一对一技术面、案例讨论到小组情景模拟的完整流程,清晰呈现了每个环节如何考察应聘者的不同维度。 作者特别指出,ThoughtWorks的面试并非单纯考察编码能力或特定技术栈的掌握程度。例如,现场编程题更注重思维过程的清晰与沟通,案例讨论则看重对业务价值的理解与权衡。整个流程被设计成一次综合性的职业能力评估,尤其侧重考察应聘者解决开放性问题的思路、协作沟通能力以及对软件工程价值观的理解。 这种面试设计的底层逻辑,实际上是将未来的工作场景前置,让面试官在真实互动的动态过程中判断候选人是否适合公司的文化与工作模式。对于读者而言,无论是否目标为ThoughtWorks,这篇文章都提供了关于现代技术公司面试趋势的洞察——即对综合思维与软性技能的重视正日益凸显。

本机暂存
IT 2012-09-02 21:22:49 / 累计浏览 2,520

基础设施之殇

这篇文章描述了一次典型的基础设施“雪崩”事件。作者从团队深夜被紧急呼叫、核心服务集群突然不可用说起,一步步回溯排查过程。最终发现,根因并非复杂的系统漏洞,而是一个看似微不足道的配置变更——在某个依赖服务的健康检查参数调整后,触发了静默的连接池耗尽,进而引发了级联故障。 文章细致还原了故障期间的排查思路:如何从纷繁的日志和监控图表中,识别出异常指标与变更时间线的重合点;团队如何在压力下协作,逐步隔离问题范围。作者并未止步于解决本次故障,更深入探讨了这种“小改动引发大灾难”的内在逻辑,指出许多基础设施的脆弱性正隐藏在看似合理的默认配置和缺乏全局审视的局部优化之中。 最终,他们不仅回滚了配置,更推动建立了一套关键变更的自动化影响评估与灰度发布流程。这篇复盘提醒我们,对基础设施复杂性的敬畏,以及建立系统性的变更治理机制,远比单纯的“打地鼠”式修复更为重要。

本机暂存
IT 2012-08-27 12:40:54 / 累计浏览 2,300

翻译杂思

这篇讲的是作者从2009年半开玩笑地参与《ThoughtWorks文集》翻译开始,如何一脚踏进了图书翻译的河流,并持续沉浸其中的故事。文章没有泛泛而谈翻译理论,而是通过这段个人经历,引出了对技术翻译这一独特工作的真切感悟。 作者分享了从“玩票”到“入行”的心态转变,以及翻译过程中那些不足为外人道的细节——它远不止是语言转换,更像是在两种思维体系间搭建一座既精准又流畅的桥梁。这种沉浸式的工作,迫使译者对技术的理解必须掰开揉碎、再清晰重组,其收获往往超越了单纯的“完成一本书”。 对于从事技术写作、文档翻译,或是任何需要精准传递复杂信息的读者而言,这篇文章提供了一个内行人的视角:它揭示了这项工作背后的耐力、苛刻与独特的成就感。这种源于深度参与和反复锤炼的体会,或许比任何翻译技巧的条目都来得生动。

本机暂存
IT 2012-07-19 12:22:40 / 累计浏览 2,880

实战遗留代码

作者从一个更犀利的角度重新定义了“遗留代码”:它与时间戳无关,而在于是否拥有自动化测试。没有测试的代码,哪怕昨天才写就,也已步入遗留的行列。 这个观点切中了许多团队的痛点——我们常抱怨历史代码难改,却忽略了新代码也可能因缺乏保障而迅速老化。文章引导我们反思的,不仅是修复既有代码,更是建立“防老化”的开发习惯。通过为代码补充测试,我们实则在为其延续可维护的生命。 真正的实战,或许始于承认:每一个没有测试覆盖的函数,都已经是一份需要小心对待的“遗留”资产。

本机暂存
IT 2012-06-05 00:02:38 / 累计浏览 2,200

聊聊Code Review

这篇讲的是Code Review,但切入点有点不一样——它从一个关于“那一点的调用”的评论讨论出发。作者hopesfish的提问,指向了一个更实际也更常被团队忽视的问题:代码评审到底在评什么? 文章的核心观点很明确,它认为一次有效的Code Review,重点不应仅仅是发现表面的代码错误。更深层次的价值在于,它是团队成员之间一次“思维同步”的机会。比如,通过讨论一个调用的设计,其实是在对齐对业务逻辑的理解、对架构意图的共识,甚至是对“好代码”标准的认同。这种交流能避免后续开发中因理解偏差导致的返工。 作者由此引申开,探讨了Review文化中的常见困境:比如,审查者是只抓细枝末节,还是关注整体设计?被审查者是感到被挑战,还是看作共同学习的机会?这篇文章没有给出标准答案,而是通过一个具体的讨论案例,启发读者去反思自己团队中Code Review的实际状态和潜在价值。 它提醒我们,技术实践的效果,往往取决于背后团队协作与沟通的“那一点”微妙之处。

本机暂存
IT 2012-05-28 13:27:35 / 累计浏览 3,900

从Go看,语言设计(二)

这篇接着上一篇,深入探讨Go语言的设计哲学。作者从Go的核心设计原则出发,聚焦于其独特的并发模型(goroutine与channel)和精简的语法如何影响程序构建与团队协作。 文章将Go与传统多线程模型(如Java线程)进行了对比,指明Go的并发原语如何以更轻量级的方式,降低了并发编程的复杂度与资源开销。作者也提到了Go的快速编译、垃圾回收机制以及对组合优于继承的坚持,这些选择共同塑造了其清晰、高效的代码风格。 最终,文章阐述了这些设计决策的适用边界:Go尤其适合构建需要高并发、快速迭代和易于维护的网络服务与基础设施。它可能不适用于所有场景,但其明确的设计取舍为开发者提供了一种可靠且高效的工程化路径。

本机暂存
IT 2012-05-28 13:26:40 / 累计浏览 6,160

从Go看,语言设计(一)

Go语言正式版的发布标志着它从一个实验性项目走向了成熟可用。这篇讲的是作者拿到正式版后上手体验,着重从语言设计的角度,分享了其中几个令人印象深刻的特点。文章没有停留在语法的简单介绍,而是深入探讨了Go在并发模型(goroutine和channel)、接口的隐式实现、以及“少即是多”的设计哲学上如何做出取舍。作者通过具体的代码片段和场景,展示了这些设计如何影响日常编码的思维方式,比如用组合代替继承,以及显式错误处理带来的代码清晰度。对于关注编程语言演进或正在评估技术选型的开发者来说,这篇基于实际体验的观察,提供了一个理解Go核心优势与设计权衡的窗口。

本机暂存
IT 2012-05-28 13:21:05 / 累计浏览 2,160

构造函数沉思录

这篇文章深入探讨了构造函数这一编程基础概念,但它并非在复述语法规则。作者从“构造函数是什么”这个看似简单的问题出发,层层剖析其设计哲学与历史演变。文章对比了在 Java、C++、JavaScript 以及现代新兴语言中,构造函数迥异的形态与职责,揭示了它如何从一个简单的初始化函数,演变为承载类型创建、资源管理、依赖注入甚至设计模式表达的关键角色。 核心在于,文章并未止步于技术对比,而是引导读者思考“为何如此设计”。它剖析了不同选择背后的权衡,比如构造函数的重载与链式调用、与静态工厂方法的博弈,以及在无类语言中“构造”概念的消解与重构。对于开发者而言,理解这些设计初衷,远比记住几条语法规则更能提升架构设计能力,帮助我们在面对不同语言和场景时,做出更贴近本质的决策。

本机暂存