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

最新文章

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

IT 算法/ 2013-05-01 18:34:10 / 累计浏览 3,640

bash遍历目录

作者从实际需求出发,整理了两套用纯Bash遍历目录树的方法:深度优先(DFS)和广度优先(BFS)。文章坦言,对于大多数简单操作,`find`命令组合其他工具足矣;但当需要严格控制遍历顺序,或者执行的操作逻辑比较复杂时,手动实现遍历就很有必要。 文中的两个函数提供了清晰的模板。作者特别指出一个实用的细节:循环中使用`` `ls "$dir"` ``而非通配符`"$dir"/*`,是为了避免当目录为空时,循环体需要额外判断`dentry`是否存在,让代码更简洁。BFS版本使用队列结构,DFS版本则用栈来模拟递归。 更巧妙的是,作者通过将回调函数作为参数传入,让遍历逻辑与具体任务解耦。示例中展示了如何用它们实现一个统计C/C++项目代码行数的脚本。文章追溯了这些代码的起源——从早年为FVWM桌面窗口管理器生成文件树菜单,到后来因ext3迁移ext4后修复文件权限而反复打磨,这些脚本在解决具体问题的过程中不断演进。对于有类似定制化需求的运维或开发人员,这份经过实践检验的代码片段值得参考。

本机暂存
IT 移动开发/ 2013-05-01 18:30:54 / 累计浏览 2,415

iOS设备上高效演示APP原型的方法总结

这篇讲的是如何在iPhone上高效演示APP原型的方法对比与选择。作者从产品和设计师的实际需求出发,对比了POP、快现、Axure等多种原型工具的上手难度、功能性和效率,并重点分析了将Axure原型导入iOS设备演示的两种主流路径。 关键差异在于“Web APP模式”和“APP打开模式”。前者能生成桌面图标,还原初始体验,但依赖在线环境,存在原型信息安全顾虑。后者需要购买Atomic Web等应用,但支持离线演示,速度更快且更安全,作者个人更推荐这一方式。 文章不仅给出了工具和模式的横向对比,还深入到了具体操作细节:比如如何在Axure中设置生成参数以适配移动设备,演示时需要注意的页面命名规则,以及不同模式下的设计尺寸计算等。这些实操要点对于想要立即上手的读者非常实用,能帮助避免常见坑点,提升演示的真实感和流畅度。

本机暂存
IT DevOps/ 2013-05-01 18:30:14 / 累计浏览 9,625

linux中设置alias永久生效

这篇讲的是如何让Linux终端的alias别名设置永久生效。很多人在使用alias时都遇到过同样的困扰:明明在当前终端设置了快捷命令,一关窗口就失效了,下次还得重新输入。作者从这个常见痛点出发,给出了一个简单直接的解决方案。 关键在于将别名定义写入用户目录下的`.bashrc`文件。文章以Ubuntu系统为例,展示了如何用`ls -a`找到这个隐藏文件,并用编辑器打开它。在文件的后半部分,我们能看到系统预设的一些别名(如`ll`、`la`),在这里添加自定义的别名,比如`alias log='cd /apache-tomcat/logs'`。保存文件后,只需执行`source ~/.bashrc`命令,新设置的别名就会立即生效,且之后每次打开终端都无需重复配置。 这个方法避免了每次手动设置的麻烦,把常用的目录跳转或复杂命令固化成简短的别名,能显著提升命令行工作效率。文章步骤清晰,对于经常使用终端的开发者来说,是一个能立即上手的实用技巧。

本机暂存
IT 开发者/ 2013-05-01 18:29:35 / 累计浏览 6,108

程序员的样子

这篇用一系列搞笑动图,真实还原了程序员工作中的典型瞬间。从紧张地往运行服务器直接上传文件,到发现未保存代码就关闭文件时的崩溃;从凌晨三点还在与bug死磕,到正则表达式一次命中时的狂喜;既有第一次用CSS美化页面时“我真是个天才”的期待,也有发现上周五还好用的功能周一就罢工时的无奈。 文章没有说教,而是用共情力极强的画面,捕捉了那些让程序员会心一笑或心头一紧的永恒场景——比如老板宣布项目奖金时突然爆发的生产力,或是需要有人站出来修复严重bug时默契的“低头族”现象。最后,那个“如何向市场部同事解释程序员工作”的画面,更是道尽了技术与非技术岗位间有趣又真实的鸿沟。 它像一面镜子,让程序员们会心一笑,也让非技术岗位的同事能更直观地理解他们的日常:那些抓狂的瞬间与小小的成就感,共同构成了这个群体最真实的模样。

本机暂存
IT DevOps/ 2013-05-01 18:14:36 / 累计浏览 3,100

robbin谈管理:要给下属challenge你的机会

这篇讲的是管理中的服从与挑战。作者从一条关于马化腾深夜提bug、团队火速响应的微博切入,引出了关于职场执行力的深层讨论:这种高效的“听话”是值得称赞的“使命必达”,还是需要警惕的“无原则媚上”? 文章的核心观点是,一味强调下属无条件服从,对创新和产品成功可能有害。作者指出,当员工只为老板的指令而工作,用户的需求就可能被忽视,产品最终成了“做给老板看的”。他举了乔布斯早期力主iPad用Intel芯片,被下属Tony Fadell强烈反对并最终改变的案例,来说明挑战权威的价值。 作者提倡,管理者应该给下属“challenge你”的机会。这不仅能帮上司纠错、避免决策盲点,更能让下属从被动执行转为主动担责,快速成长。他结合自身经历,分析了上司害怕被挑战的几种心态(如权威被威胁、爱面子等),并总结了下属提出异议后可能出现的几种结果。他认为,绝大多数情况下,开放讨论的结果都好过一言堂,即使最终证明下属是错的,上司承担责任的过程也能建立团队信任。 文章呼吁建立一种更开放、互信的团队氛围,让每个人都为产品和用户负责,而不仅仅是对上级的KPI负责。

本机暂存
IT 数据库/ 2013-05-01 18:11:01 / 累计浏览 4,759

Oracle数据恢复专题

这篇专题文章直击一个国内DBA常面临的痛点:如何在缺少规范备份的严苛条件下,执行Oracle数据库的恢复操作。作者从东西方DBA工作重心的差异切入,坦言“无备份恢复”在国内技术环境中,有时会成为一种被迫练就的“屠龙之技”。 文章并非泛泛而谈,而是系统整理了一系列极具实战价值的案例与脚本。从利用DUL、BBED等底层工具直接抢救数据文件,到通过构造ROWID巧妙绕过ORA-1578等坏块错误;从处理ASM磁盘头丢失这类存储层灾难,到解决PL/SQL对象被覆盖、数据文件名乱码等逻辑故障。每一个链接背后,都是一个需要深入理解数据块结构与数据字典的硬核场景。 对于需要直面数据库“心跳停止”时刻的工程师来说,这份专题更像是一本应急手册。它提供的不只是方法,更是对Oracle内部机制的理解深度——在备份失灵时,这份理解往往是找回数据的最后一道防线。

本机暂存
IT DevOps/ 2013-05-01 18:10:27 / 累计浏览 4,594

Unix考古记:一个“遗失”的shell

这篇讲的是Unix历史上第一个被广泛传播的shell——Thompson Shell,它由Ken Thompson编写,却常常被后来的Bourne Shell的光芒所掩盖。作者从Unix V6时代的尘封文档和源代码出发,带我们重新认识了这个只有900行C代码、却奠定了现代shell基因的“鼻祖”。 文章的价值在于,它清晰地展示了Thompson Shell如何将管道线、I/O重定向、通配符扩展和后台执行这些影响深远的概念工程化实现。尽管它在1977年就被Bourne Shell取代,但它所确立的命令语言结构和解释器可移植性原则,直接塑造了我们今天习以为常的命令行交互方式。 更妙的是,文章深入其解释器源码,剖析了预处理、词法扫描等步骤。你会发现,这个简陋的解释器原理竟与编译器一脉相承,对于想理解Shell或编译原理的读者来说,这份“活化石”级别的代码解析提供了难得的直观视角。

本机暂存
IT 后端/ 2013-05-01 18:07:24 / 累计浏览 2,954

Perl 实现 Flash 的 Socket Policy 服务器

这篇讲的是作者从一个误解出发,折腾出一个轻量解决方案的实践经历。起初,为了支持Flash P2P功能的测试,作者需要提供Socket策略文件。他最初错误地以为只需用HTTP服务器响应,直到被合作方提醒,才明白Flash Player的机制:在建立Socket连接前,它会主动向服务器的843端口发送一个 `` 字符串以请求策略文件。 理解了这个机制后,作者利用Perl的AnyEvent框架,仅用几分钟就实现了一个TCP服务器来响应这个请求。核心代码展示了AnyEvent::Handle的强大:它让服务器可以简洁地监听连接,并依据自定义规则(此处是收到特定字符串)进行读写。收到请求后,服务器直接返回预设的 `crossdomain.xml` 内容并主动断开连接,完美符合协议要求。作者也借此引出了AnyEvent在快速构建高性能TCP服务上的便利性。 文章最后,作者提到自己后来发现GitHub上已有类似实现,相当于“重复造了个轮子”。但整个过程清晰地记录了问题排查、机制理解和代码实现的完整链条,对需要处理类似Flash Socket安全策略的开发者,是一个直接而有用的参考。

本机暂存
IT 移动开发/ 2013-05-01 17:59:19 / 累计浏览 3,585

移动开发之touch event篇

这篇讲的是移动端网页开发中,如何用好触控事件来优化交互体验。作者从移动设备流量已占北美网络总流量20%的背景出发,指出虽然手机浏览器能渲染桌面网页,但交互方式因缺少鼠标而大不相同。 文章核心梳理了三个基础触摸事件:`touchstart`、`touchmove`和`touchend`,并通过控制台日志演示了事件触发的顺序与包含的触摸点列表(`touches`, `targetTouches`, `changedTouches`)的区别。作者还深入探讨了几个实际开发中的关键点:如何一行代码检测浏览器触摸支持;在`touchend`中,离屏的触摸点仅存在于`changedTouches`列表;以及移动端“轻拍”如何被浏览器转化为单击事件。 特别值得一提的是,文章分析了在`touchmove`事件中使用`preventDefault()`来禁用页面默认滚动和缩放的最佳实践——这是实现诸如Canvas自由绘图等自定义手势的基础。作者通过几个可运行的Demo和截图,将抽象的事件模型变得直观可感,对需要处理多点触摸或自定义手势的前端开发者来说,是份清晰的入门与避坑指南。

本机暂存
IT 开发者/ 2013-05-01 17:53:57 / 累计浏览 7,048

在杭州工作(2013年版)

一位在北京学习工作七年后转战杭州的程序员,结合自己四年的亲身经历,分享了对这座城市的感受。文章从工作、生活、消费等几个维度展开,并与北京做了直观对比。 工作层面,作者坦言杭州的互联网机会相对集中,主要就在阿里和网易,选择面不如北京广,但电子商务氛围浓厚。生活则是杭州的强项,城区紧凑,周末去龙井、梅家坞聚会爬山都很方便,运动环境极佳。作者用“分分钟秒杀北京”来形容生活便利性上的优势。消费水平被认为与北京接近,但夏天的闷热被指出是明显的缺点。 最后,作者给出了“超出期望”的总体评价。这篇文章没有宏大的叙事,却通过通勤时间、聚会开销、爬山路线等真实细节,为考虑来杭发展的技术人提供了一份接地气的参考。

本机暂存
IT 数据库/ 2013-05-01 17:47:14 / 累计浏览 5,558

老托的Oracle 数据库Patch概念性小常识

这篇讲的是Oracle数据库补丁体系中那些容易混淆的概念。文章清晰地梳理了从标准版本Release,到累积型的Patch Set (PSR)、季度发布的Patch Set Update (PSU) 和 Critical Patch Update (CPU) 等各类补丁的定义与区别。 特别实用的部分在于,它点明了不同补丁的发布逻辑和应用场景:例如,PSU和PSR虽是累积型,但PSU不改变主版本号;在Windows平台上则使用Bundle Patch (BP) 作为替代。文章还澄清了小补丁 (One-Off Patch)、合并补丁 (Merged Patch) 以及诊断补丁 (Diagnostic Patch) 的具体用途和注意事项。 对于希望理解补丁策略的DBA来说,文中的安装建议很有价值,比如推荐安装最新的PSR,以及在应用小补丁前务必进行测试。文章最后引入了Composite Patch的概念,解释了这种新格式如何通过增量安装减少时间开销,并与之前的PSU版本构成了清晰的包含关系,为管理补丁提供了新的视角。

本机暂存
IT 后端/ 2013-05-01 17:44:21 / 累计浏览 5,841

whatsapp深度使用Erlang有感

当很多人还在争论Erlang是否过于小众、能否胜任大规模商业系统时,WhatsApp用事实给出了响亮的回答。这篇文章分享了作者对WhatsApp深度使用Erlang技术栈的观察与思考。 文章的核心是一个极具说服力的案例:一个以Erlang为主的后台架构,支撑了数亿用户。作者通过引用WhatsApp主要开发者Rick Reed的分享,揭示了一个有趣的成长故事——这位有深厚系统性能背景的工程师,在2011年加入WhatsApp时竟是一位Erlang新手,但短短两三年后,他已能将Erlang的虚拟机、集群、Mnesia数据库等特性运用到极致。 文中列举的数据令人印象深刻:仅用两台服务器承载百万级的长连接、Mnesia数据库支撑起巨大的数据集,以及背后惊人的消息吞吐量。作者指出,Rick Reed的工作并非创造了全新的魔法,而是将Erlang已知的特性进行了系统化整理并坚决落地于商业系统,这是从理论到实践的巨大飞跃。 文章最终的结论很直接:任何系统开发到最后,都是在操作系统和硬件能力的边界内解决同类问题,Erlang为解决高并发、高可用等特定规模问题提供了坚实的基础。作者鼓励读者停止对它的怀疑,因为它在正确的场景下确实能带来巨大的价值。

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

从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-05-01 17:40:52 / 累计浏览 5,530

简单理解Memcached的Slab Allocation

这篇讲的是Memcached如何用Slab Allocation机制管理内存。作者从内存分配的基本问题切入,解释了这套机制的核心:它预先将内存划分为大小固定的Page(默认1MB),再将每个Page切成相同尺寸的Chunk,相同尺寸的Chunk集合就构成了一个Slab。 这种预分配和分组的方式,能有效减少动态分配内存时产生的碎片。文章进一步指出,通过启动参数`-f`可以调整Growth Factor(默认1.25),它决定了相邻Slab中Chunk尺寸的倍增关系。不过,Slab Allocation并非完美:当实际数据尺寸与Chunk大小不匹配时,会产生内部碎片;当一个Slab无法被其Chunk大小整除,或是某些尺寸的Slab根本没被使用时,也会造成内存浪费。 文章通过结构图和工具截图,直观展示了Slab、Page与Chunk的关系,以及Growth Factor对不同Slab中Item尺寸的影响,清晰剖析了这个内存管理方案的利与弊。

本机暂存
IT 后端/ 2013-05-01 17:38:27 / 累计浏览 3,799

“C++的数组不支持多态”?

这篇博客澄清了一个关于“C++数组不支持多态”的常见误解,作者从微博上的一场讨论切入。文章指出,争议的核心在于对C/C++内存布局的理解差异。当使用 `Base* p = new Derived[n]` 时,删除操作能否正确调用派生类析构函数,并非语言本身的缺陷,而是涉及指针类型转换后,数组步长与对象内存布局是否匹配的根本问题。 作者通过对比C和C++进行了深入分析。在C语言中,不同大小的结构体数组被强制转型会导致严重的内存访问越界和数据混乱,这纯粹是内存模型问题。但在C++中,由于编译器通常将虚函数表指针置于对象起始位置,并且在内存对齐规则下,只要派生类大小不小于基类,数组的物理步长就是安全的。文章通过具体的代码示例和内存调试,展示了在特定内存布局下(例如派生类大小不超过基类),上述C++代码反而能正确执行。 最终,文章揭示了所谓“坑”的本质:它混淆了C语言中数组指针转换的危险性和C++对象模型的特殊性。关键在于理解对象的内存布局,而非简单断言语言特性的有无。这提醒开发者,需要扎实掌握底层内存知识,才能准确区分语言设计、编译器实现和编码错误之间的边界。

本机暂存
IT 后端/ 2013-05-01 17:36:13 / 累计浏览 3,144

使用 AnyEvent 来实现同一个端口跑二种服务

这篇讲的是一个非常实际的网络访问问题:当 Linode 的 SSH 端口(22)被 GFW 过滤后,如何利用仍然开放的 80 端口,让同一台服务器同时提供 HTTP 和 SSH 两种服务。作者从这个痛点出发,实现了一个基于 Perl AnyEvent 库的协议识别与转发代理。 核心方案在于对连接建立时发送的初始数据包进行嗅探。对于 HTTP 请求,开头通常包含“GET”、“POST”等关键字;而对于 SSH 连接,像 SecureCRT 或 Bitvise 这样的客户端会主动发送包含“SSH”字样的协议头。程序根据这个特征,将连接动态转发到本地对应的 80 或 22 端口后端服务。作者基于国外一个 Perl 实现进行了重写和封装,利用 AnyEvent 的事件循环特性来构建高性能的异步代理。 最终效果就是,作者现在浏览的网页和远程管理都是通过这同一个 80 端口完成的。这个方案虽然牺牲了使用 CDN 的可能性,但在特定网络环境下,提供了一种巧妙且有效的端口复用思路。

本机暂存
IT 算法/ 2013-04-07 13:18:50 / 累计浏览 7,563

深入浅出插入类排序算法(直接插入, 折半插入, 希尔排序)

这篇讲的是如何用最生活化的方式理解插入类排序。作者从打扑克牌的场景切入——手里每拿到一张新牌,就按大小插到已排好序的牌列中——清晰展示了直接插入排序的核心过程。文章不仅给出了这个算法的C语言实现,还通过统计比较和移动次数,分别演示了最好情况(已排序)和最坏情况(逆序)下的性能差异,最后得出平均时间复杂度为O(n²)的结论。 随后,文章对比介绍了两种优化变体。折半插入排序通过二分查找减少比较次数,而不是顺序扫描;希尔排序则通过分组和逐步缩小增量的方式,让排序效率更高。作者通过扑克牌的连续操作步骤,将这些抽象算法的每一步都可视化,让读者能直观看到算法如何一步步移动元素、缩小比较范围。 整体而言,这篇文章没有停留在代码罗列,而是结合实例与原理分析,把三种容易混淆的插入排序讲得层次分明。尤其适合想搞清楚“它们到底有什么不同”以及“各自适合什么场景”的学习者。

本机暂存
IT 算法/ 2013-04-07 13:17:17 / 累计浏览 7,077

深入浅出交换类排序算法(冒泡排序,快速排序)

这篇文章通过对比两种经典的交换类排序算法,系统讲解了冒泡排序与快速排序的原理、实现与性能差异。文章从冒泡排序“两两比较、逐步上浮”的直观思想切入,用军训排队的生活比喻和具体的序列交换过程(如4,3,5,6,2,1的逐步排序),清晰展示了其简单但低效的特点,并指出平均时间复杂度为O(n²)。 重点转向快速排序时,文章突出了其“分治”核心:通过选取基准元素(pivot),用双指针扫描将序列划分为左右两部分,再递归处理。文中通过图示详细拆解了一轮快排的完整指针移动与交换过程,代码实现也体现了递归思想的巧妙运用。对比部分明确指出,快速排序在平均情况下时间复杂度可达O(n log n),是内排序中效率最高的算法之一,尤其适合处理大规模或基本无序的数据。 整体上,文章将算法思想、步骤图解、代码实现与复杂度分析紧密结合,既解释了冒泡排序易于理解但效率有限的教学价值,也阐明了快速排序在追求效率的实际应用中的优势。

本机暂存
IT 算法/ 2013-04-07 13:15:28 / 累计浏览 4,647

深入浅出选择类排序算法(简单选择排序,堆排序)

这篇文章讲的是两种经典的选择类排序算法:简单选择排序与堆排序。作者从基本思想出发,用一个有趣的比喻——在班级中依次选择最喜欢的“女朋友”——生动解释了简单选择排序如何工作:每一轮遍历未排序部分,找出最小值放到已排序序列末尾。它的实现直观,但时间复杂度固定为O(n²),无法避免大量的比较操作。 堆排序的讲解则更深入。它将待排序序列构建成一个完全二叉树(大顶堆或小顶堆),利用“父节点总是最大(或最小)”的性质,通过反复交换堆顶元素与末尾元素并调整堆来完成排序。文中详细演示了建堆和递归调整的过程,并附有代码。这种基于二叉树结构的方法,将最坏情况下的时间复杂度提升到了O(nlogn),同时保持O(1)的空间复杂度。 两者虽然同属选择排序范畴,但效率差异显著。简单选择排序逻辑简单、易于实现,适合数据量小或对稳定性有要求的场景;堆排序则凭借更优的时间复杂度,在处理大规模数据时表现突出,是许多高效排序系统的基础。

本机暂存
IT 算法/ 2013-04-07 13:14:34 / 累计浏览 4,071

数学中的极限思想求时间复杂度

这篇讲的是如何用更严谨的数学方法来计算算法的时间复杂度。通常大家习惯直接保留函数中的最高次项,比如将 T(n) = 2n^5 + 3n^2 - 1 简写为 O(n^5)。文章指出,这种简便做法其实不够严格,其背后的正确依据应当是数学中的极限概念。 作者详细推导了极限判定法:当 n 趋向无穷大时,T(n) 除以某个猜想 f(n) 与一个常数系数的乘积,若结果为一个常数,则 f(n) 就是 T(n) 的时间复杂度。用这个方法重新计算开头的例子,可以严谨地得出 O(n^5) 的结论。 更重要的是,极限思想能解决一些常规方法棘手的对比。比如比较多项式 n^k 和指数 k^n(k 为大于1的常数)的复杂度,直接判断很模糊。文章通过对两边取对数再求极限,清晰地证明 n^k / k^n 的极限为 0,从而得出结论:当 n 足够大时,O(n^k) 的效率远优于 O(k^n)。最后,文章还展示了如何将指数增长的思想应用于分析循环次数,推导出类似 i = i*2 这种模式的时间复杂度为 O(log₂n)。 这篇内容为理解算法效率提供了一个更坚实的数学视角,帮助开发者不仅知其然,更知其所以然。

本机暂存