IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者
首页 / YanyiWu
IT 2020-02-01 15:14:13 / 累计浏览 1,620

美好世界,源自不开心。

这篇讲的是科技史上那些划时代创新背后一个略带反直觉的驱动力:不开心。 作者从Linux之父Linus对迟迟未能工业化的Unix感到不满,到乔布斯对早期智能手机笨拙体验的厌烦,再到雷军、张小龙、王兴等国内创业者各自“忍无可忍”的痛点出发,串联起一系列经典案例。文章罗列了从iPhone、微信、美团到比特币、以太坊等重大产品与技术的诞生,都将起点归因于创造者对现状的强烈不满与情绪低落。这些故事横跨操作系统、移动互联网、社交网络与区块链等多个关键领域。 文章用戏剧化的叙述和排比,提炼出一个核心观点:对现有解决方案的深刻不满,甚至是一种情绪上的“不开心”,恰恰是颠覆式创新的重要火种。它将技术发展与个人情绪体验紧密挂钩,为读者理解创新动机提供了一个生动而富有冲击力的视角。当然,文末也注明了内容属于虚构创作,意在启发而非陈述史实。

本机暂存
IT 2016-04-05 14:57:08 / 累计浏览 2,680

谈谈Go语言的字符串设计

作者从一个实际的内存泄漏问题说起:在使用GoJieba库时,一段测试代码的内存持续增长。经过排查,发现问题出在调用C.CString后未手动释放内存——一个因思维惯性导致的“白痴”Bug。 这个Bug的背后,是Go字符串与C字符串在内存模型上的根本差异。C语言以‘\0’作为字符串终结符,导致字符串无法直接复用父字符串的内存。而Go的字符串采用长度记录,设计上支持高效的子串内存共享。因此,当通过cgo的C.CString将Go字符串转换为C字符串时,必须分配全新的内存空间,这就要求开发者必须负责手动调用C.free进行释放,不能像使用C++的c_str()那样想当然地复用内存。 文章最终回归文档,用cgo官方示例明确了这一“必须释放”的责任。这个小小的踩坑经历,提醒所有涉及跨语言内存管理的开发者:务必理解底层设计差异,严格遵守接口契约。

本机暂存
IT 2016-02-13 23:39:24 / 累计浏览 1,720

由NodeJieba谈谈Node.js异步实现

这篇文章以NodeJieba这个中文分词库的源码为例,深入浅出地拆解了Node.js异步操作的底层实现原理。作者没有停留在理论层面,而是直接打开`cut`函数的C++实现代码,带领读者一步步看清异步调用的“幕后”。 核心思路非常清晰:当我们在JavaScript中调用异步的`cut`函数时,实际是创建了一个`CutWorker`对象并将其推入`NanAsyncQueueWorker`队列。真正的耗时分词操作`segment.cut()`在后台线程的`Execute`方法中静默执行,完成后则通过`HandleOKCallback`回到主线程触发回调。 文章特别点明了两个巧妙而关键的设计:一是`CutWorker`必须用私有成员变量(如`inputStr`)来保持状态,确保后台线程执行时参数依然有效,即使原栈变量已销毁;二是整个异步非阻塞的魔力,正源于“主线程只负责投递任务,后台线程持续轮询队列并执行”这一经典线程池模型。 通过这个具体的例子,作者揭示了Node.js异步的本质其实并不高深,它无非是“状态保存”与“后台队列执行”两个核心环节的组合,为许多初学者揭开了异步编程的神秘面纱。

本机暂存
IT 2016-02-13 22:41:27 / 累计浏览 6,060

如何教会非计算机专业的女友写代码

这篇讲的是一个计算机专业男生如何系统指导金融专业女友转行前端开发并成功就业的完整经历。 作者从自身背景出发,为女友选择了适合入门且“可进可退”的前端方向,并制定了清晰的学习路径:从《Head First》系列和《JavaScript语言精粹》等书籍掌握基础语法,再通过言传身教渗透HTTP协议、网络通信等原理知识。他强调“工欲善其事”,专门为女友购置MacBook Pro以便熟悉Vim、Git等开发工具。 实践环节是关键。作者引导女友在GitHub写博客、开发小作品,并报名参加了筛选制的百度IFE前端技术学院。当基础扎实后,便鼓励她投递简历,通过面试发现不足,最终顺利获得实习Offer。过程中遇到的JS异步、闭包等难点,也被一一攻克。 文章还直面了两个常见偏见:技术是否适合女性,以及互联网行业是否过于繁忙。作者以实例论证,技术岗位对女生同样有吸引力且并不枯燥,互联网公司也存在灵活的工作选择。最后,他用自己的支持与担当,为这段转行之路画上了有温度的句号。

本机暂存
IT 2016-02-13 22:40:31 / 累计浏览 2,280

创业路上的那点事(一周年小记)

这篇是一位创业公司成员的一周年经验记录,分享了几个他观察到的典型现象。作者从“精英与接地气”的取舍谈起,指出创业初期需要的是能解决具体问题、适应不同阶段的“靠谱”人才,而非一味追求顶尖精英;接着强调个人价值最大化的重要性——选择加入的时机,应是自身能力最能匹配公司需求之时。 文章也剖析了创业心态与现状:盲目的乐观虽看似非理性,却比弥漫焦虑更利于团队奔跑;当前融资环境可能隐藏泡沫,而真正顺利的公司往往选择“闷声发大财”,低调发展。此外,从大公司带来的“无知优越感”、工具齐全环境对创造力的限制,都是需要警惕的思维陷阱。 作者最后回归朴素理解:创业就是一群人把一件事做成了,碰巧对社会有益、也对自己有回报。甩开膀子去干,享受过程,尽最大努力也做好最坏打算——这或许才是面对创业最实在的态度。

本机暂存
IT 2016-02-13 22:39:39 / 累计浏览 4,740

分布式存储Seaweedfs源码分析

这篇文章对分布式文件存储系统 SeaweedFS 0.67 版本的源码进行了一次深入的解剖。作者从其基于 Facebook Haystack 论文的架构思想出发,指出 SeaweedFS 实现了“青出于蓝而胜于蓝”的改进。 文章清晰地梳理了项目的核心模块,重点剖析了其两大支柱:拓扑管理与数据存储。在拓扑层面,详解了由 DataCenter、Rack、DataNode 构成的树状结构,这正是其管理分布式 VolumeServer 的核心。而在数据存储层面,则层层递进,解释了文件唯一标识 Fid 的构成(VolumeId, NeedleId, Cookie),并深入到 Volume 文件内部的布局——SuperBlock 与 Needle 的关系。特别值得一提的是,文中对 SuperBlock 中 TTL(Time To Live)功能的实现原理进行了拆解,阐述了如何通过 Volume 级别的超时标记与清理机制来优雅地实现文件的定时删除。 整体来看,这篇文章并未停留在功能介绍,而是直击代码,帮助读者理解 SeaweedFS 如何用简洁的设计实现高性能的对象存储,对于理解分布式存储系统的工程实现很有参考价值。

本机暂存
IT 2016-02-12 17:47:22 / 累计浏览 1,360

开源项目的那点事

作者从近期重构CppJieba、发布NodeJieba的实践出发,分享了自己在开源社区中的几点切身感受与学习开源项目的方法。 他强调,一个重视用户体验的开源项目,往往从“简陋”但无依赖的轻量版本开始,例如他早期的CppJieba和ideawu的SSDB,都坚持不依赖第三方库以实现即装即用。在学习上,他建议开发者善于积累自己的代码片段,将小实验逐步组合成项目;同时也要“站在前人的肩膀上”,优先参考现有分析文档再阅读源码,避免低效硬啃。 作者提出了一个颇具启发性的观点:开源项目的学习价值并非由star数决定,而在于其与学习者当前工作的相关性及代码的可读性。他认为,阅读与自己领域相近、核心逻辑清晰的源码,更能带来实际灵感;而一味追求明星项目或高性能代码,有时反而因牺牲可读性而难以深入。 最后,他呼吁回归开源初衷——即知识的分享与传播,而非过分功利化。整篇文章将个人开发经历与开源学习心得紧密结合,对初入社区或希望提升源码阅读能力的开发者都有切实的参考意义。

本机暂存
IT 2016-02-12 17:46:25 / 累计浏览 3,680

不要总是选择困难模式

这篇文章通过一个研究生的成功转型案例,讨论了技术初学者在职业起步阶段的策略选择。作者从一位非计算机背景、基础薄弱的同学咨询职业规划的邮件切入,该同学明确以iOS开发为切入目标,优先打造竞争力而非全面补基础,最终顺利拿到阿里和腾讯的Offer。 文章由此引出核心观点:技术学习如同游戏,存在“困难模式”(如C/C++基础架构方向)与“简单模式”(如前端、移动端等方向)。对于基础不扎实的应届生,作者建议优先考虑需求量大、机会更多的“简单模式”赛道,而非盲目挑战门槛高、竞争激烈的红海领域。文中以2010年安卓与嵌入式的选择对比为例,指出了盲目追求“高级难度”可能带来的长远遗憾。 作者进一步以多位技术大佬的实际选择为例——如鸟哥专攻PHP性能优化而非GCC、AstaXie用Go开发框架而非Erlang——说明即便是高手,也会精明地选择投入产出比更高的方向。这篇文章并非否定挑战高难度的价值,而是提醒读者:清晰的自我定位和务实的路径选择,有时比一味“迎难而上”更能通向成功。

本机暂存
IT 2016-02-11 14:54:11 / 累计浏览 2,200

JavaScript初体验

这篇文章源于作者一次愉快的阅读体验。在读完《JavaScript语言精粹》后,他结合自己的使用经历,分享了几个对JavaScript印象最深的特点。 作者认为,JavaScript的灵活性是其核心魅力。比如“函数即变量”的特性,为异步和回调提供了天然支持;而JSON作为JS的“最伟大副产品”,极大地简化了数据序列化过程,对比传统语言的RPC工具堪称“酸爽”。他同时指出,抛开“原型继承”、“闭包”等看似高深的标签,JS其实是一门简单的语言,其Array、Object、函数参数等设计都透着直接和灵活。 文章也记录了作者的一些个人疑惑:他质疑JSONP在URL里写回调的方式是否足够优雅,思考Promise之外更佳的异步解决方案,并对Node.js在后端生态的统治地位表达了既批判又看好的复杂态度。在书评部分,他认为本书相比冗长的《权威指南》更为“接地气”。 通篇来看,这更像是一位有经验的开发者,在语言特性、生态现状和学习资源之间穿梭,给出的个人化思考笔记。对于想了解JS本质魅力或资深开发者心得的读者,其中的观察角度很有启发。

本机暂存
IT 2016-02-09 23:11:30 / 累计浏览 4,780

C++线程池实现原理

这篇讲的是C++线程池中一个核心但常被忽略的机制——闭包(Closure)是如何工作的。作者没有一开始就堆砌复杂概念,而是从一段注释丰富的简单示例代码切入,展示了使用线程池的标准写法。 然后,他带读者聚焦到那个让人困惑的`NewClosure`函数。文章的巧妙之处在于,它揭示了这个“闭包”其实是一个简单的模板对象。其核心思路是:通过模板类`ObjClosure1`,将对象指针、成员函数指针以及参数值,这三样东西打包存储起来。当线程池的工作线程取出这个任务时,调用的`Run()`方法内部,再通过`(p_->*fun_)(arg1_)`这样的C++成员函数指针调用语法,把这些元素重新组合起来执行。 文章把这个过程比作“打包”与“拆解执行”,解释得清晰直白。作者的目标是让初学者看完后,从“不明觉厉”变为“原来如此”。对于想了解线程池任务封装原理,却又对模板和函数指针感到头疼的C++开发者来说,这是一篇很好的入门拆解。

本机暂存
IT 2016-02-07 14:33:59 / 累计浏览 7,100

谈谈在校程序员技能培养

这是一篇关于在校程序员技能培养的经验分享,作者结合自身从北邮本科到研究生阶段的经历,给出了几条打破常规却很实用的建议。 文章的核心观点是,在校学习的目标不是“好好上课”,而是高效地掌握知识并投入实践。作者通过考前集中复习保证成绩,从而腾出大量时间用于编程实践,这让他在校招中具备明显优势。在技能培养上,他强调要“适度刷题”——算法基础虽重要,但忽视工程细节(如STL容器的内存管理、线程安全)会成为明显短板。对于实习,作者结合自己和身边人的案例,建议不要盲目追求大厂光环,早期进入能深度参与项目的初创公司,往往能获得更扎实的工程锻炼。此外,他提到要关注行业技术趋势,顺势而为比固守个人偏好更重要。 这篇文章源于作者帮助内推时对行业“人才青黄不接”现象的观察,所有建议都来自他一路走来的切身体会。虽然行业形势在变,但其中关于平衡应试与实践、在实习中追求实质成长的思路,对今天的在校生仍有参考意义。

本机暂存
IT 2016-02-07 14:32:59 / 累计浏览 1,860

谈谈go语言编程的并发安全

这篇讲的是Go并发安全的一个经典认知误区。作者从修复分布式存储项目Weed-FS中的一个非并发安全问题出发,提交了加锁的PR,却意外被维护者以“单写多读场景不需要加锁”为由拒绝。 这挑战了作者基于C/C++开发经验的常识,促使他深入探究Go内存模型。文章梳理了Go官方建议的核心:对多goroutine访问的数据必须序列化(加锁或使用channel),并引用了社区讨论中的警句——“Don't be clever”。最终,通过go-nuts邮件列表的权威讨论,验证了作者“必须保护”的观点是正确的,维护者也接受了修改。 文章特别指出,许多人存在“每次读取都是原子行为”或“数据竞争最多只是读到旧值”的误解,这其实是非常危险的。作者推荐使用`go run/build/test -race`命令来检测这类难以复现的隐患,并提醒大家,即使程序运行正常,也不代表没有并发问题。

本机暂存
IT 2016-02-06 11:04:03 / 累计浏览 4,660

C++之stl::string写时拷贝导致的问题

这篇讲的是作者在实现数据结构序列化时,因滥用 `std::string` 作为缓冲区而踩到的一个隐蔽陷阱。具体来说,作者直接通过 `(char*)s.c_str()` 获取内部指针并使用 `fread` 写入数据,这在多数情况下看似高效且可行。然而,当代码中发生类似 `string s2 = s;` 的拷贝操作后,再对 `s2` 进行同样的 `fread` 操作,原本期望保持不变的 `s` 内容却意外被篡改了。 问题的根源在于部分 STL 实现(如旧版 GCC)采用了“写时拷贝”(copy-on-write)机制来优化 `string` 的拷贝性能。此时,拷贝操作仅共享底层指针,而非进行深拷贝。这就导致通过强制类型转换修改共享内存区的数据时,所有持有该指针的 `string` 对象都会受到影响。文章清晰对比了“写时拷贝”与“立即拷贝”(eager-copy)两种策略的差异与适用场景,并指出该 bug 因其延迟显现的特性而极难定位。 作者最终总结道,尽管将 `string` 作为临时缓冲区的写法在网络上屡见不鲜,但在“写时拷贝”的实现下,这种用法存在严重隐患。对于需要直接操作内存的场景,开发者应意识到 STL 容器的这些实现细节,或考虑使用更明确的缓冲区类型,以避免类似的陷阱。

本机暂存