IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

最新文章

采集自各技术站点的近期文章。

IT 后端/ 2013-06-17 23:54:29 / 累计浏览 3,803

了解模块化开发

这篇从前端工程师小A的日常困扰讲起。他为了避免冲突,把公共函数封装到`_`对象里,结果还是和第三方库的`_`撞了车。接着,团队协作中又暴露了另一个大麻烦:组件`tabs.js`依赖另外两个文件,但使用者不仅要手动补全引用,还容易搞错加载顺序。更令人头疼的是,当`tabs.js`新增一个依赖后,所有引用它的页面都得跟着修改。 文章通过这两个具体场景,层层剥开传统前端开发中的痛点:全局变量污染就像房间里的“地雷”,而隐式依赖和脆弱的手动管理,则让代码维护变成了“排雷”与“走钢丝”的混合挑战。作者没有停留在问题表面,而是指向了模块化这个解药——它正是为了实现依赖的清晰声明与自动化管理,从而让代码结构更健壮、团队协作更顺畅。对于仍在为文件加载顺序和命名冲突头疼的开发者来说,理解这些“为什么”至关重要。

本机暂存
IT 后端/ 2013-06-17 23:49:02 / 累计浏览 2,638

说说会话串号

这篇讲的是大型网站(以淘宝为例)中一种令人头疼的故障——“会话串号”,即用户意外登录到他人账号的现象。作者基于亲身的运维经历,剖析了几起真实案例。 文章首先区分了两种串号场景:一种是系统BUG导致的,用户不仅能看到别人页面,还能进行操作;另一种是缓存导致的,用户只能看到别人的页面但无法操作。重点在于前两种技术性串号:第一起源于Jboss的Tomcat在解析Request参数时存在BUG,可能读取到脏数据导致登录串号;第二起则是店铺系统在静态化改造时,缓存服务器错误地缓存了包含Set-Cookie的HTTP头,导致用户获得了一个他人的SessionID。 排查这类问题周期很长,因为难以重现且不易定位根因。为此,文章提出了一种主动防御思路:在Cookie中增加一个签名值,并在服务端会话框架中校验该签名。一旦检测到客户端与服务端的签名不一致,就清空会话并强制用户重新登录。这套机制旨在快速发现并阻断串号,将被动排查转为主动防御。

本机暂存
IT 算法/ 2013-06-17 23:45:27 / 累计浏览 4,180

cpp智能指针的简单实现

这篇讲的是如何从零开始实现一个C++智能指针。文章直指C++没有垃圾回收导致的内存管理痛点——手动配对`new`和`delete`极易出错和内存泄漏,随后切入智能指针如何通过引用计数来自动化这一过程。 作者的实现核心在于一个巧妙的设计:使用一个在栈上自动管理生命周期的包装类`Ptr`,其内部持有一个指向堆上辅助类`SmartPtr`的指针。这个辅助类负责记录引用计数和实际的数据。当`Ptr`对象被复制时,引用计数增加;当其析构时,引用计数减少。只有当引用计数降为零,意味着没有`Ptr`实例再指向它时,辅助类及其管理的内存才会被释放。 这种“栈对象包装堆对象”的思路,正是智能指针将语言特性(栈自动回收)与手动内存管理相结合的关键。文章通过一段可运行的代码清晰地展示了引用计数的增减时机,让抽象的原理变得直观。理解了这个手动实现,也就真正理解了智能指针在C++内存模型中的运作基石。

本机暂存
IT 后端/ 2013-06-09 13:34:53 / 累计浏览 3,268

不同SSD盘组合搜索引擎单机性能测试[2013年版]

作者从搜索引擎单机性能优化的需求出发,在一台配置了24核Xeon E5 CPU、近50GB内存的Linux服务器上,对不同SSD盘组合策略下的HA3引擎性能进行了系统测试。测试数据规模可观,索引达59G,摘要73G。 文章详细对比了多种方案:从全内存基准、单盘SSD,到由两块或三块盘组成的RAID 0、RAID 1,以及不使用硬件RAID而采用软连接或数据分片的方式。测试严格控制了IO调度、预读、线程数等变量,并通过abench工具获取峰值QPS。 核心发现颇具实用价值:当索引量翻倍时,性能近似减半,表明IO是关键瓶颈。单纯增加RAID 0的磁盘数对搜索引擎引擎性能提升有限,瓶颈会转移至CPU锁开销。最引人注目的结论是,两块SSD盘不使用硬件RAID,而是通过软件将数据按term哈希键分片存储,能达到约18%的性能提升,优于RAID 0的12%提升,也远超传统的多段软连接方式。 文章最终给出了分层建议:在CPU性能制约时,应重点解决IO瓶颈(如采用多盘按term切分);当磁盘增多后,则需关注CPU锁优化。对于写入场景,也提出了普通盘与SSD搭配的实践方案。

本机暂存
IT 前端/ 2013-06-09 13:20:27 / 累计浏览 3,535

Javascript 装载和执行

这篇讲的是浏览器如何处理JavaScript文件的装载和执行问题。作者从JavaScript两大特性——“载入后立即执行”且“执行时阻塞页面”——出发,通过一系列具体示例,对比了多种解决方案的差异与适用场景。 传统将script标签放在head中会导致页面渲染被完全阻塞。即便使用document.write动态插入,对整个页面来说仍然是同步阻塞的。HTML5的async属性虽允许并行下载,但脚本执行时机不可控;而IE的defer属性能延迟执行且不阻塞DOM渲染,不过浏览器兼容性有限。 作者重点推荐了“动态创建DOM元素”的方式,这已成为异步加载的常用模式。进一步地,为了解决“何时执行”的问题,可以将脚本加载绑定到window.onload或特定交互事件上。文章还探讨了预加载脚本但不立即执行的进阶需求,介绍了利用object或iframe标签进行缓存的变通方法。 最终,作者通过对比演示,清晰地展现了每种方案在执行顺序、阻塞行为和浏览器支持上的权衡,为开发者在实际项目中选择合适的脚本加载策略提供了实用参考。

本机暂存
IT 移动开发/ 2013-06-09 13:18:17 / 累计浏览 2,364

有趣的下拉刷新

这篇讲的是,一个看似普通的交互动作——下拉刷新,如何从功能性操作演变为品牌表达与创意设计的舞台。文章从Twitter获得下拉刷新专利的事件切入,梳理了这项由Tweetie创始人发明的操作如何风靡移动应用。 但作者没有停留在功能层面,而是敏锐地指出:下拉刷新已跳出基础功能,成为一种表现品牌和设计感的元素。文中将这些有趣的实践分为三类:与应用类型巧妙结合的,如拍照应用Cheeze中,下拉会唤出一只老鼠并拍照;与品牌元素深度绑定的,如Flickr的经典双色转圈、Google系产品围绕品牌色的动画、蚂蜂窝“嗡嗡”里振翅的小马蜂;以及完全结合应用整体风格进行创新的。 这篇文章带我们回溯了这个经典交互的源头,并展示了它在当下如何成为设计师的画布——一个小小的下拉手势,竟能承载如此多的巧思与品牌个性。

本机暂存
IT 数据库/ 2013-06-09 13:16:28 / 累计浏览 3,034

PL/SQL的那些事儿

这篇讲的是PL/SQL在Oracle数据库中的正确使用姿势,作者通过对比两种常见场景,点明了优化的核心。 文章清晰地划分了PL/SQL的两类使用场景:一类是作为“胶水”,串联一系列SQL分析语句,性能瓶颈主要在SQL引擎;另一类是用游标逐行处理数据,进行过程化计算。作者指出一个关键现象:即便优化后者,性能提升也有限;但若将其重写为前者纯SQL驱动的模式,性能常能获得成百上千倍的提升。这揭示的根本原则是:务必优先利用数据库核心的SQL引擎能力,而非用过程化代码(无论是Java还是PL/SQL)去替代它。 当然,PL/SQL并非一无是处。文章也强调了其不可替代的价值,例如实现数据库内部监控工具。作者用了一个形象的类比:将监控代码部署在数据库内部,就像把监控脚本直接放在被监控主机上,避免了网络开销,能获取更精确的数据。文中推荐的工具Session Snapper,就是一个典型的、高效运行在数据库内部的PL/SQL诊断范例。 因此,PL/SQL是一把宝剑,用于数据库管理与扩展时锋利无比;但若当作处理数据的“菜刀”来过度使用,则可能事倍功半。

本机暂存
IT 安全/ 2013-06-09 13:13:05 / 累计浏览 4,360

一个绝妙的 exploit

这篇讲的是 Linux 内核一个经典的提权漏洞分析。漏洞源于 `perf_swevent_init` 函数中,`event_id` 被定义为带符号的 `int`,而后续检查仅校验了其上界。当传入一个高位为1的负数时,该值能绕过检查并导致 `perf_swevent_enabled[]` 数组越界访问。 作者详细剖析了 exploit 的巧妙思路:利用数组越界,分别对一个内核地址和一个用户空间地址(通过精心计算 `mmap` 得到)执行原子加一和原子减一操作,从而探测出数组基地址。更精妙的是,作者选择了修改中断描述符表(IDT)中某个条目的高32位偏移地址。这个地址原本固定为 `0xffffffff`(内核空间),通过一次原子加一,它被变为 `0x00000000`,从而指向了用户空间。如此一来,触发对应的中断(`int 0x4`)便会跳转到攻击者预先布置好的、用于修改进程 uid/gid 的用户代码,最终获得 root shell。 整个攻击链条的核心,就是一个看似微小的类型符号不一致问题,经过层层推导和内存布局计算,最终转化为强大的攻击能力,令人印象深刻。

本机暂存
IT 设计/ 2013-06-08 23:42:14 / 累计浏览 4,440

代码里的命名规则:错误的和正确的对比

这篇讲的是代码命名中容易被忽视的关键细节。作者从“代码即文档”的理念出发,指出好的命名能让代码自我解释,而糟糕的命名则会埋下理解的坑。 文章通过七组具体的正反案例,直观对比了命名时的常见陷阱与推荐实践。比如,变量 `d` 的意图全靠注释,而 `elapsedTimeInDays` 一目了然;使用 `customerList` 命名一个数组会误导读者,改为 `customers` 则清晰准确。核心差异在于:好的命名能准确揭示意图、避免歧义、长度适中、遵循团队规范、概念一致,并贴合业务领域与上下文。 作者强调,这不仅仅是风格偏好,而是关乎代码可维护性和团队协作效率的根本。通过遵循这些具体的命名原则,程序员可以让代码在“无注释”的情况下也能被轻松读懂,从而真正实现高效沟通。

本机暂存
IT DevOps/ 2013-06-08 23:38:39 / 累计浏览 11,594

Linux命令行里的“瑞士军刀”

这篇讲的是那些能用一行命令完成复杂任务的Linux“瑞士军刀”级技巧。作者分享了一组来自Quora的高效单行脚本,它们能用极简的语法替代大段的代码,威力惊人。 比如,要计算两个文本文件的交集、并集和差集,只需`cat a b | sort | uniq`的几种变体即可轻松搞定,无论文件多大。汇总一列数字的和,一条`awk`命令就能完成,比用Python写循环快3倍且代码量更少。想要快速查看目录下所有文件的大小和修改时间?`find . -type f -ls`比递归的`ls -lR`输出更清晰。 文章还展示了`xargs`的惊人力量——它能将标准输入转化为命令参数,用于批量处理,比如从文件读取主机名列表并并行执行SSH命令。另一个实用场景是分析Web日志:一行命令就能统计日志中特定参数(如`acct_id`)的请求次数,并按频率排序。 这些技巧的共同点是极致的效率与简洁,充分体现了Unix哲学中组合小工具完成大任务的思想。对于系统管理员或后端开发者来说,掌握这些单行命令,能让你在文本处理、系统运维等任务上如虎添翼。

本机暂存
IT 开发者/ 2013-06-08 23:37:17 / 累计浏览 8,079

腾讯敏捷开发及快速迭代

这篇讲的是腾讯如何从2006年开始,在研发规模膨胀的背景下,将敏捷开发从理念落地为一套独特的、适合自身的实践体系——TAPD。 文章梳理了腾讯从引入ThoughtWorks培训、试点到全面推广敏捷的完整历程,并坦诚分享了过程中遇到的挑战:产品线多元、团队规模差异大、长周期项目(如QQ客户端)的适配问题,以及大量新人融入的难题。正是这些挑战,催生了腾讯混合吸收XP、Scrum和FDD精髓的“并行迭代”模式。 在具体实践上,文章细节很多。产品侧采用类似FDD的“特性驱动”,由产品经理滚动定义需求;项目管理借鉴Scrum,但强调每日晨会、规划游戏和时间盒的灵活运用;开发侧则落实了持续集成、自动化测试和“全员测试”文化。最具腾讯特色的创新点包括使用“故事墙”可视化进度、推行“自运转团队”以减轻项目经理负担,以及大规模应用“灰度发布”来安全快速地验证产品。 整篇文章展示了一个大型互联网公司如何将敏捷“本土化”,在规范化与灵活性之间找到平衡,最终服务于快速迭代的产品目标。

本机暂存
IT 安全/ 2013-06-08 23:36:19 / 累计浏览 4,053

使用Http-only Cookie来防止XSS攻击

这篇文章从Cookie在维持HTTP会话状态中的关键作用切入,揭示了XSS攻击窃取Cookie的典型手法——攻击者只需注入一段简单脚本,就能通过`document.cookie`获取敏感信息并外传。针对此威胁,文章分析了几种常见防护思路的缺陷:与User-Agent绑定易被同步窃取,与IP绑定则影响ADSL等动态IP用户的体验。 核心方案聚焦于**Http-only Cookie**。一旦该属性被设置,浏览器就不会将对应的Cookie暴露给客户端脚本,从根源上切断了XSS攻击读取Cookie的路径。文章具体展示了Http-only的设置语法,并指出ASP.NET等主流框架已提供便捷的配置接口。同时强调,这并非一劳永逸的解决方案——它不能阻止攻击者进行AJAX提交等恶意操作,因此实际部署中必须与其他安全策略组合使用,例如微软的Web Protection Library。 简言之,文章厘清了“为何需要Http-only”以及“它如何工作”,并提醒开发者将其作为纵深防御体系的一环,而非唯一防线。

本机暂存
IT 后端/ 2013-06-03 23:00:04 / 累计浏览 3,974

页缓存概述

这篇讲的是Linux内核中一个关键性能优化组件——页缓存的工作原理与实现。作者将它比作硬件缓存的软件实现,核心思想是利用快速的主存来缓存慢速的磁盘数据,以此大幅减少I/O等待。 文章首先解释了页缓存的读写机制:读取时先查缓存,若未命中则加载并可能长期驻留;写入时则直接修改缓存中的“脏页”,并不立即写回磁盘,而是采用延迟写回的策略来合并多次修改。 实现上,内核面临两大挑战:如何快速找到特定缓存页,以及如何统一管理来自不同源(如文件、设备)的数据。文章深入剖析了address_space结构如何巧妙地解决这两个问题。它内部维护一棵radix优先搜索树,将所有属于同一所有者的缓存页组织起来,支持高效的查找、插入和删除。同时,通过a_ops钩子函数集,为不同数据源定义了统一的操作接口(如readpage、writepage),让上层逻辑与底层具体设备解耦。 最后,文章列出了内核提供的基本操作函数,如查找、分配、添加和移除缓存页,构成了操作页缓存的程序接口。整体来看,这篇文章从概念到实现,清晰地梳理了Linux内存管理中这一精巧的中间层设计。

本机暂存
IT 后端/ 2013-06-03 22:59:02 / 累计浏览 6,413

malloc()之后,内核发生了什么?

作者从一个常见的用户空间操作出发,即进程调用 `malloc()` 后尝试访问内存,一路追踪到内核空间的真实发生过程。文章的核心在于揭示,用户感知到的“内存分配”在内核层面主要通过 `brk` 系统调用来实现,其背后是一套从修改堆描述符到最终响应缺页异常的精密机制。 讲解路径非常清晰:首先,`malloc()` 会触发 `brk` 系统调用,通过 `SYSCALL_DEFINE1(brk,...)` 服务例程来调整进程的堆边界。文中展示了该例程如何检查资源限制、对齐地址,并根据是扩大还是缩小堆,分别调用 `do_brk()` 或 `do_munmap()`。 文章的巧妙之处在于指出,此时内核通常并未立即分配物理内存。`do_brk()` 的核心工作是在进程的虚拟地址空间中分配或合并一个线性区间(VMA),为后续可能的操作“预留地盘”。真正的魔法发生在第二步:当进程首次访问这块新地址时,CPU 会因页表项无效而触发缺页异常。文章接着深入异常处理流程,从 `page_fault` 入口,到 `do_page_fault()` 判断异常类型,最终由 `handle_mm_fault()` 接手。 在 `handle_mm_fault()` 中,内核才开始真正“分配”物理内存——它确保页目录结构完整,然后调用 `handle_pte_fault()` 完成页框的分配与映射。整个过程生动地体现了 Linux 内存管理中“延迟分配”的核心思想:先给予虚拟承诺,待实际使用时再兑现物理资源,从而优化了内存使用效率。这对于理解内存分配的全链路至关重要。

本机暂存
IT DevOps/ 2013-06-03 22:57:37 / 累计浏览 3,445

RPM包的管理

这篇讲的是Linux世界里RPM包管理的那些事儿。文章从RPM(Red Hat Package Manager)这个Red Hat系发行版里的“老大哥”说起,它把软件预编译打包成标准格式,装起来是省心,但也被批评为不够灵活——你的系统环境得和打包时完全一致才行。 为了补上这块短板,SRPM(Source RPM)就登场了。它不光带源码,还贴心附上了依赖说明,安装时能自己检查缺啥。不过对于大多数用户,更常用的其实是YUM这个在线升级神器。它背后连着个服务器仓库,把所有软件和它们“谁依赖谁”的关系图都理得清清楚楚,一键安装就能自动摆平依赖链,和Debian系的apt-get解决的是同一类痛点。 文章后半段还聊了聊怎么自己动手打包RPM。核心工作是写好spec这个“配方文件”,软件叫啥、版本多少、安装时该跑什么命令都得写明白。至于找spec模板,优先级也说得很明白:先翻源码包,不行就找社区现成的改改,实在没有才自己从头写起。整个过程把RPM生态里打包分发的逻辑串了个七七八八。

本机暂存
IT 后端/ 2013-06-02 20:26:56 / 累计浏览 2,518

zend php 动态数组

这篇讲的是如何从Zend PHP源码中学习动态数组的C语言实现。作者从C语言静态数组长度固定的痛点切入,指出在很多场景下我们无法预先知道数据规模,但又不想浪费内存预分配一个过大的数组。解决思路就是动态数组:先用malloc分配一块连续内存,通过指针像操作数组一样访问;当空间不足时,用realloc进行扩容(它会保留原有数据)。 文章的核心部分是剖析Zend PHP中动态数组的具体实现。作者展示了完整的头文件和源码,包括初始化、插入、获取、销毁等关键操作。其实现很巧妙:用一个结构体封装数组指针、元素大小、当前元素数和已分配容量;在push时,如果当前容量已满,就将容量翻倍进行realloc,确保了均摊下的高效插入;通过元素大小和偏移量计算,可以泛型地支持任意类型的数组。文末通过一个读取输入并输出的对比实验,直观展示了静态数组(固定缓冲区可能截断数据)和动态数组(随输入自动增长)在实际应用中的行为差异。

本机暂存
IT 后端/ 2013-06-02 20:26:04 / 累计浏览 13,260

Linux内存点滴 用户进程内存空间

这篇详解Linux用户进程的内存空间,作者从大家熟悉的top命令输出讲起,解释了VIRT、RES等字段背后,其实是进程被内核分配的虚拟内存(VM)这一核心概念。 文章重点梳理了这块内存空间的构成,清晰地区分了Text(代码段)、Data、BSS、Heap(堆)和Stack(栈)这几个段的特性与用途,并通过多个C语言示例,生动演示了不同段数据的生命周期和访问权限差异——比如栈上变量在函数返回后失效,而堆内存则需手动释放以防泄露。 此外,文章还深入到底层,分析了malloc()函数通过brk()和mmap()系统调用分配内存的机制,并解释了“按需缺页”这一精妙的虚拟内存管理策略:首次访问时才分配物理页框,从而高效利用系统资源。最后,通过strace工具跟踪系统调用,直观展示了内存分配的实际过程。对于想从应用层迈向系统内核,理解Linux如何为进程管理内存的开发者,这篇内容提供了非常扎实的起点和细节剖析。

本机暂存
IT 后端/ 2013-06-02 20:23:56 / 累计浏览 5,033

http keepalive

这篇讲的是HTTP KeepAlive机制的工作原理与正确配置。作者从早期每个HTTP请求都需要单独建立TCP连接的性能瓶颈出发,解释了KeepAlive如何允许在一个TCP连接上持续传输多份数据,从而显著减少连接建立开销、降低服务器内核调用与TIME_WAIT状态连接数。 不过,文章也明确指出KeepAlive并非“免费午餐”,配置不当的长连接反而会导致系统资源被无效占用,其损失可能超过重复建立连接。因此,正确设置`keepalive_timeout`参数至关重要。 作者通过编写脚本与`tcpdump`抓包,细致地分析了三种场景:关闭KeepAlive、开启KeepAlive(超时300秒)、以及在同一连接上发送多个请求(超时180秒)。测试清晰地揭示了TCP连接从建立、数据传输到最终释放的完整生命周期。一个关键发现是,`keepalive_timeout`的计时器是在最后一个HTTP响应发送完毕后才开始启动,并在每次收到新请求后重置。这意味着合理的超时设置需要在复用连接提升性能与避免资源长期占用之间取得平衡。

本机暂存
IT 后端/ 2013-06-02 20:23:05 / 累计浏览 4,294

记一次tps提升,做的配置变更

这篇讲的是作者如何将一个php应用的TPS从120稳定提升至810的实战过程。 文章开篇直面问题:系统TPS低下、响应慢、并发能力差。作者从应用代码入手,借助xhprof定位瓶颈,优化了如避免高频内核调用、用memcached缓存数据等细节。随后,思路扩展到整个服务栈的配置调优。 在php层面,通过禁用不必要的模块、重新编译、配置php-fpm等方式节约资源。Web服务器Nginx侧,则涉及worker进程数、epoll模型、keep-alive、gzip压缩及静态资源处理等关键配置。更深层的,作者对操作系统进行了“瘦身”:精简守护进程、调整文件描述符限制、优化磁盘挂载参数。 整个过程的转折点在于对内核参数的精细调整。通过sysctl优化TCP连接、缓冲区等设置后,系统不仅TPS达标,性能曲线也趋于稳定。作者总结道,提升TPS的核心在于缩短单个请求的响应时间,并可通过strace等工具分析,从减少上下文切换和系统调用入手,最终实现更少资源开销下的更高吞吐。

本机暂存
IT 前端/ 2013-06-02 20:22:17 / 累计浏览 3,068

网站优化 更小的静态资源

这篇文章解决一个实际问题:如何通过压缩构建静态资源来加快网站加载。作者团队发现,更小的JS、CSS和图片文件意味着更少的网络传输时间,因此在构建阶段对它们进行优化至关重要。 核心方案是根据资源类型,选择不同工具进行深度压缩。对于JavaScript,他们对比了UglifyJS、Google Closure Compiler等工具,最终因稳定性考量,采用了Google Closure Compiler;对于CSS,则沿用了熟悉的YUI Compressor;而对于PNG和GIF图片,他们组合使用OptiPNG、AdvPNG和AdvDef三个工具,以实现最大化的压缩率。文章详细解释了每个选择背后的权衡与理由。 为了将这些工具集成到发布流程中,他们编写了一个简版的Bash构建脚本。这个脚本实现了自动化的压缩、复制和输出,避免了人工介入。从脚本执行结果的日志可以看到,多数文件的大小都得到了显著缩减,例如一个近50KB的JS文件被压缩到了约17KB,充分验证了方案的效果。 总的来说,这是一份非常扎实的前端工程化实践记录。它没有停留在工具介绍层面,而是完整展现了从工具选型到构建集成的决策与实现过程,其中对PNG图片“优先选用png8格式,并结合CSS Sprites”的建议,以及具体的脚本实现,对同类项目的优化工作都有直接的参考价值。

本机暂存