输入关键词开始搜索

  • 基于我划线最密集、最认同的这 3 本书的核心主张,帮我找出与其观点完全对立、批判最狠的 5 本硬核书籍,给我做一次认知压力测试。
  • 假设我以当前的阅读结构和速率继续读 5 年,推演那时的我会变成什么样的人,会形成哪些固化偏见,产生哪些知识盲区,错过哪些真正重要的问题,并指出现在必须立刻插入哪 5 本反向修正书来避免那个未来。
  • 在我读过的所有书里,按现在的我重读它获得的认知增量最大排序,给出 Top 10 重读清单。
  • 把我过去 1 年的阅读按动机分类,给出比例和具体书目,并诚实指出我可能在用哪类书逃避哪件事。

定义你的,不是你的本质,而是你的所作所为。

《蝙蝠侠》
  • 虽然我做了坏事,但我内心是个好人。
  • 是生活所迫,让我做了这个那个,但我本质上是这个那个,现在不是真正的我。但依然有很多人为了面临更大压力的时候也从未妥协。选择妥协的那个,就是真正的你
  • 一件事情,在大多数时候是没有确定性答案的。认知不是从天上掉下来的,它是靠人不断推演、争论、交流,一点一点磨出来的——这个过程不能省略,因为这个过程就是人本身。 如果认知直接由 AI 给到,且不论它是否全面、是否带着批判性,单是中间那段思考的缺席,就足以让主体性一寸一寸地退场,最后沦为珍妮机前面那个等待被淘汰的身影。
  • 帕斯卡说,人是一根会思考的芦苇,宇宙无需武装就能碾碎他;但人依然比碾碎他的东西高贵,因为人知道自己会死,而宇宙对此一无所知。在 AI 时代,这句话有了一个新的读法:模型可以在几乎一切任务上超过我们,但知道自己在做什么、为什么做、做成之后世界会有什么不同的,依然只有这根芦苇。
Why I Don’t Vibe Code
A “brief” accounting of various reasons why vibe coding has just never clicked for me personally as a developer.
jacobharr.is
  • AI 的热潮确实让我想起早期低代码和无代码工具的突破。我不怀疑 AI 能成为开发者的有用工具,我知道有些任务它能作为更好的工具来辅助完成。但这些论点总让我再次思考偶然复杂性与本质复杂性的问题。

  • 布鲁克斯在《没有银弹》一文中探讨了新工具对开发者生产力的影响。要像程序员一样思考,你必须理解现实世界的复杂性。编程最好被理解为在混乱的现实之上施加简化的表征——我们称之为_抽象_——通过降低复杂性使其可理解。这让我们能够将特定情境泛化为可层层叠加的抽象层。

  • 即使更好的工具减少了偶然复杂性,本质复杂性依然存在。我们仍需以正确的方式设计抽象和系统——一种优雅、清晰且可维护的方式——这本身就是一项复杂的工作。而这种复杂性不会消失。这类工作需要技能、经验以及从过去系统失败中艰难获得的智慧。


  • LLM 驱动开发的魅力在于它理应消除摩擦。拥护者们编造着开发团队一天内交付数十个功能的故事,他们指挥着多个自主运行的智能体团队,以越来越奇特的拓扑结构协同工作。我理解,软件开发有时确实繁琐且令人沮丧。能够以相对惊人的速度产出代码,并摆弄那些打磨精美的产品而非原型,这种感觉一定令人无比兴奋。

  • 不过我需要这种摩擦。

  • 当我初次学习一门新语言或框架时,即使是最基本的任务也会让我感到举步维艰。这感觉糟透了!而当我面对一个陌生且不熟悉的代码仓库或数据源时,我需要花上几个小时仔细审视。我常常会进行细致的研读,调出特定文件逐行查看,直到理解它们的上下文以及开发者做出的选择。我知道我可以直接让 LLM 帮我总结项目来节省时间,但我发现我需要这个过程来真正沉浸到代码中。我需要的不只是理解开发者做了哪些选择,更是理解他们为何做出这些选择,以及这些选择如何体现所用语言的约束或惯用法。我在失败中学习,如果 LLM 替我完成了这部分工作,我就无法真正理解自己在做什么。

  • 如果编写提示词的工程师缺乏判断好坏的能力,他们就会陷入反复让 AI 硬编码来消除摩擦的循环。这可能导致一团混乱的抽象层,而留给未来团队的唯一设计文档,只是一份为几年前使用的 AI 模型写的 Markdown 指令。


  • 也许我不使用 LLMs 的最简单原因就是,我实在是太热爱编程了,以至于我不想把它交给机器。就像如果我是艺术家或音乐家,我不会求助于 AI 一样,编程是我表达创造力的一种方式,我不会放弃这种快乐。尽管有时会极其令人沮丧,但从一个模糊的想法塑造出一个真实的系统,尤其是涉及优雅的实现或有趣的问题时,会带来深沉的喜悦。有些晚上,我合上工作笔记本,打开个人笔记本,去探索一些我想构建的有趣新东西。

  • 编程也一直是我在困难时期的慰藉。有研究表明,玩俄罗斯方块是避免创伤后应激障碍的有效方法。其理论依据是,调动大脑中负责排列和旋转形状的部分,会妨碍创伤记忆的形成。幸运的是,我没有患 PTSD(我也并非轻视那些受其困扰的人),但确实能理解这一概念。编程就像解复杂的谜题,有时是我黑暗时刻的慰藉。

宝贵的人生建议
在68岁生日那天,凯文·凯利开始动笔为他的子女写下一些人生建议,他希望子女们能早点知道这些智慧。他在几年间不断写下新的建议,当这些建议足够多了,他决定写下这本书,以便读者能与朋友和希望改善自身生活的人,分享这些建议。
book.douban.com

养成习惯的好处是,在行动时,不必再进行内心的权衡。

不再消耗能量去思考是否要做这件事。

你只管去做。


每个人都害羞。

其他人在等你做自我介绍;

他们在等你给他们发邮件;

他们在等你

约他们出去。

当我们在讨论 Harness 的时候,我们在讨论什么 | 深度对谈: Minimax × Hermes Agent
听《十字路口Crossing》上小宇宙。AI 正在给各行各业带来改变,我们在「十字路口」关注变革与机会,寻找、访谈和凝聚 AI 时代的「积极行动者」,和他们一起分享实战经验。
xiaoyuzhoufm.com
  • 在这样高密度、高复杂性的任务上,如果想 scale up, 那人在其中的占比一定要是少的,人只能是驾驭,否则这个效率就会很低,我们就做不出最有生产力最好的东西。
  • 要改变视角,工作应该改造成以 ai 为中心,而非继续以人为中心。
  • 不要想模型做不到,而且想模型能做到,我应该怎么配合模型做到。
  • 如果一个 AI 公司不是以 AGI 为目标,那它就不应该存在。而 agent 是 AGI 之路的一个重要工具,因此大模型公司一定会做agent。
  • OpenClaw 出来之后,我一直在想它和claude code的本质区别是什么,对谈里给 OpenClaw 的定义我觉得挺好的:
    • 第一就是随时随地能够联系到他的一个伙伴。
    • 第二就是他能够你在使用过程中越来越聪明。
  • 一方面,我越来越擅长自学,也养成了独立思考的能力;另一方面,我变得孤僻,不善与人建立连接。面对人群,我总是局促不安,不知如何表达真实的自己;我害怕袒露想法,总觉得无人理解,也无人愿意理解。

  • 人必须与外部世界建立连接,而表达,就是这场连接中的第一道桥梁。

  • 我才明白,表达不是可有可无的能力,而是一门人生的必修课

  • 真正的表达,不是为了炫耀,也无关于技巧,而是一种自我的袒露。你越愿意将内在推向外部,你就越清楚自己是谁、想要什么、和他人有什么不同。而你越害怕表达、越不敢袒露,你的“自我”就越容易被模糊、被裹挟、被湮没。久而久之,甚至你自己也不认识自己了。

  • 表达像是一面镜子,一面不断校准自我认知的镜子。你表达得越多,越真实,就越靠近那个真实的“自己”

如果你希望存储一段信息,让 100 年后的人也能访问,要怎么做?

三体中有类似的想法:如果人类灭亡,最好的保存文明的方式是什么?答案是:“刻在石头上”

但在一百年的时间尺度上,文章作者认为 GitHub 是存储信息的最好方式:

  • Github 已经是全人类的互联网基础设施
  • Git 能保存所有的 commit 历史
  • Git 是分布式存储的,即使 Github 被黑客侵入数据丢失,只要有一份 fork 还在,数据就还在。

越来越多的人会把自己的信息搬到 GitHub 上,依托 GitHub 实现曾经人们可望而不可及的”永生”。

几十几百年后,GitHub 将成为世界上最大的数字公墓,注册用户大部分都已去世,然而个人主页,项目,commit 历史 还述说着他们生前做过的事——就比如 Joe 的博客。 这虽然是个比较 creepy 的推论,但从另一个角度想,却证明了人类的巨大进步:对抗死亡是人类文明的永恒主题,而我们已经实现了阶段性胜利。

tk 教主分享在微博上的文章:“粉丝群有人问有没有关于怎么带团队的书。我觉得把《怎样当好一名师长》看明白就够了。这也是我非常推崇的一篇文章。”

  1. 要勤快:应该自己干的事情一定要亲自过问,亲自动手。
  2. 要摸清上级的意图:对上级的意图要真正理解,真正融会贯通,真正认识自己所领受的任务在战役、战斗全局中的地位和作用。这样,才能充分发挥自己的主观能动性,才能打破框框,有敢于和善于在新情况中找到新办法的创造性。
  3. 要调查研究:平时积累的掌握的情况越多,越系统,在战时,特别是在紧张复杂的情况下,就越沉着,越有办法,急中生智的“智”才有基础。
  4. 要有活地图
  5. 要把各方面的问题想够想透:
    • 要让大家提出各种可能发现的问题,要让大家来找答案
    • 没有得到答案的问题,不能因为想了很久想不出来就把它丢开,留一个疙瘩
    • 整个战役战斗的过程,就是不断的提出问题和不断的回答问题的过程。
    • 总之,对每一个问题都不能含糊了事,问题回答完了,战役、战斗的组织才算完成。
  6. 要及时下达决心
  7. 要有一个很好的很团结的班子
  8. 要有一个好的战斗作风
  9. 要重视政治,亲自做政治工作

微博链接:https://weibo.com/1401527553/PB3xN1Pag

要锻炼出创造性的身体,去看电影、听音乐会、去美术馆、看别人的建筑,然后要有想做得比他们更好的意愿,超越前人的勇气,体力衰退了,竞争意识就会变弱。没有了创造性的身体,竞争意识就没了。这两个是一回事,要同时锻炼身体和意志。

我捐出了所有来自苹果的财富,因为财富和权力并非我的追求。我享受生活的乐趣——在我的出生地圣何塞,我资助了许多重要的博物馆和艺术团体,他们以我的名字命名了一条街道以示认可。如今我从事公开演讲并成为行业顶尖,虽然不清楚具体资产数额,但经过 20 年的演讲事业,可能积累了约 1000 万美元和几处房产。我从不寻找任何避税手段,通过劳动获得的收入缴纳约 55%的综合税负。我是世界上最快乐的人。对我而言,生活从来不是关于成就,而是关于快乐,那正是笑容减去愁容的简单公式。这些人生理念在我 18 到 20 岁时就已形成,而我始终坚守至今。

最近看了《成为乔布斯》这本书以及听了播客半拿铁的《苹果简史》。对沃兹的印象就是他和乔布斯最开始的组合就是天使+魔鬼,沃兹是毫无疑问的赤子。沃兹的这个留言更加印证了这个印象。

今天恰好是 woz 的生日,看到了他在论坛上的留言,再次感叹他的人生态度。

我们做任何决定,最终都有可能会后悔会遗憾,但是面对多个选择时,我们应该选择让自己后悔或者遗憾最少的那个。

贝索斯

股市是世界上最可爱的东西。对于股市你可以随便怎么想,怎么想都可以,甚至觉得”川大智胜”和川普有关系都可以。

一切观点、一切想法都可以掏钱验证。如果你是对的,那就不光是对的,还能赚钱。所以如果你这么坚定地相信,就没道理不掏钱。除非,你其实也没那么相信。

社会是一个周期更长的股市。每个人最终都会在这个股市里得到和自己的想法相匹配的回报,一切想法也最终都会变成收益或亏损。而且社会这个股市是由不得你不掏钱的,退不了,缩不了,怂不了。 不光是钱,你的整个人生都会被投入进去。所以收获的也不光是钱,是你整个人生的悲喜荣哀。

所以,你可以随便怎么想,怎么舒服怎么想,或者,认真地思考自己的每一个判断,每一个决定,想清楚自己要的到底是简单、爽,还是有更想要的东西。

一个 Gin 缓存中间件的设计与实现

我们在开发 HTTP Server 的时候,经常有对接口内容做缓存的需求。例如,对于某些热点内容,我们希望做 1 分钟内的缓存。短期内缓存相同内容不会对业务造成实质影响,同时也会降低系统的整体负载。

高性能服务之优雅终止

「优雅终止」指的是当服务需要下线或者重启时,通过一些措施和手段,一方面能够让其他服务尽快的感知到当前服务的下线,另一方面也尽量减小对当前正在处理请求的影响。优雅终止可提升服务的高可用,减少下线造成的服务抖动,提升服务稳定性和用户体验。

Golang 定时器底层实现深度剖析

本文将基于 Golang 源码对 Timer 的底层实现进行深度剖析。主要包含以下内容:

  1. Timer 和 Ticker 在 Golang 中的底层实现细节,包括数据结构等选型。
  2. 分析 time.Sleep 的实现细节,Golang 如何实现 Goroutine 的休眠。

注:本文基于 go-1.13 源码进行分析,而在 go 的 1.14 版本中,关于定时器的实现略有一些改变,以后会再专门写一篇文章进行分析。

Elasticsearch 学习:入门篇

Elasticsearch 是一个分布式搜索引擎,底层基于 Lucene 实现。Elasticsearch 屏蔽了 Lucene 的底层细节,提供了分布式特性,同时对外提供了 Restful API。Elasticsearch 以其易用性迅速赢得了许多用户,被用在网站搜索、日志分析等诸多方面。由于 ES 强大的横向扩展能力,甚至很多人也会直接把 ES 当做 NoSQL 来用。

个人博客及公众号常用工具

本文整理和记录下自己在运营 个人博客 以及公众号时常使用到的一些工具。主要包含以下方面:

  1. 中英文空格的自动排版
  2. 微信公众号如何使用 markdown 发布
  3. 绘图工具
  4. 图片压缩工具
  5. 如何测试网站的打开速度以及针对性优化

Golang channel 源码深度剖析

channel 是 Golang 中一个非常重要的特性,也是 Golang CSP 并发模型的一个重要体现。简单来说就是,goroutine 之间可以通过 channel 进行通信。

channel 在 Golang 如此重要,在代码中使用频率非常高,以至于不得不好奇其内部实现。本文将基于 go 1.13 的源码,分析 channel 的内部实现原理。

FileBeat-Log 相关配置指南

本文主要介绍 Filebeat 7.5 版本中 Log 相关的各个配置项的含义以及其应用场景。

一般情况下,我们使用 log input 的方式如下,只需要指定一系列 paths 即可。

filebeat.inputs:
- type: log
  paths:
    - /var/log/messages
    - /var/log/*.log

但其实除了基本的 paths 配置外,log input 还有大概十几个配置项需要我们关注。

这些配置项或多或少都会影响到 Filebeat 的使用方式以及性能。虽然其默认值基本足够日常使用,但是还是需要深刻理解每个配置项背后的含义,这样才能够对其完全把控。

同时,在 filebeat 的日常线上运维中,也会涉及到这些配置参数的调节。

Redis 事件循环器 (AE) 实现剖析

Redis 作为一个单线程高性能的内存缓存 Server 而被人熟知。作为一个典型的 Reactor 式网络应用,Redis 能够达到如此高的性能,必然要依靠足够可靠的事件循环库。 Redis 内置了一个高性能事件循环器,叫做 AE。其定义和实现可以在 ae*.h/cpp 这些文件中找到。

AE 本身就是 Redis 的一部分,所以整体设计原则就是够用就行。也正因为这个背景,AE 的代码才可以简短干净,非常适合阅读和学习。

本文将基于 Redis 5.0.6 的源码分析下其事件循环器 (AE) 的实现原理。

同时本人也提供了一个 Redis 注释版,用以辅助理解 Redis 的源码。

Elastic-Filebeat 实现原理剖析

Filebeat 是使用 Golang 实现的轻量型日志采集器,也是 Elasticsearch stack 里面的一员。本质上是一个 agent,可以安装在各个节点上,根据配置读取对应位置的日志,并上报到相应的地方去。

Filebeat 的可靠性很强,可以保证日志 At least once 的上报,同时也考虑了日志搜集中的各类问题,例如日志断点续读、文件名更改、日志 Truncated 等。

Filebeat 并不依赖于 Elasticsearch,可以单独存在。我们可以单独使用 Filebeat 进行日志的上报和搜集。filebeat 内置了常用的 Output 组件, 例如 kafka、Elasticsearch、redis 等。出于调试考虑,也可以输出到 console 和 file。我们可以利用现有的 Output 组件,将日志进行上报。

当然,我们也可以自定义 Output 组件,让 Filebeat 将日志转发到我们想要的地方。

filebeat 其实是 elastic/beats 的一员,除了 filebeat 外,还有 HeartBeat、PacketBeat。这些 beat 的实现都是基于 libbeat 框架。

uber-go 漏桶限流器使用与原理分析

uber 在 Github 上开源了一套用于服务限流的 go 语言库 ratelimit, 该组件基于 Leaky Bucket(漏桶) 实现。

我在之前写过一篇 《Golang 限流器 time/rate 实现剖析》,分析了 Golang 标准库中基于 Token Bucket 实现限流组件的 time/rate 原理,同时也讲了限流的一些背景。

相比于 TokenBucket 中,只要桶内还有剩余令牌,调用方就可以一直消费的策略。Leaky Bucket 相对来说更加严格,调用方只能严格按照预定的间隔顺序进行消费调用。(虽然 uber-go 对这个限制也做了一些优化,具体可以看下文详解)

还是老规矩,在正式讲其实现之前,我们先看下 ratelimit 的使用方法。

Golang 标准库限流器 time/rate 实现剖析

限流器是微服务中必不缺少的一环,可以起到保护下游服务,防止服务过载等作用。上一篇文章 《Golang 限流器 time/rate 使用介绍》 简单介绍了 time/rate 的使用方法,本文则着重分析下其实现原理。建议在正式阅读本文之前,先阅读下上一篇文章。

上一篇文章讲到,time/rate 是基于 Token Bucket(令牌桶) 算法实现的限流。本文将会基于源码,深入剖析下 Golang 是如何实现 Token Bucket 的。其代码也非常简洁,去除注释后,也就 200 行左右的代码量。

同时,我也提供了 time/rate 注释版,辅助大家理解该组件的实现。

Golang 标准库限流器 time/rate 使用介绍

本主题为系列文章,分上下两篇。本文主要介绍 time/rate 的具体使用方法,另外一篇文章 《Golang 限流器 time/rate 实现剖析》 则着重介绍其内部实现原理。

限流器是后台服务中的非常重要的组件,可以用来限制请求速率,保护服务,以免服务过载。 限流器的实现方法有很多种,例如滑动窗口法、Token Bucket、Leaky Bucket 等。

其实 Golang 标准库中就自带了限流算法的实现,即 golang.org/x/time/rate。该限流器是基于 Token Bucket(令牌桶) 实现的。

简单来说,令牌桶就是想象有一个固定大小的桶,系统会以恒定速率向桶中放 Token,桶满则暂时不放。 而用户则从桶中取 Token,如果有剩余 Token 就可以一直取。如果没有剩余 Token,则需要等到系统中被放置了 Token 才行。

微信 libco 协程库源码分析

libco 是微信后台开发和使用的协程库,同时也是极少数的直接将 C/C++ 协程运用到如此大规模的生产环境中的案例。

《云风 coroutine 协程库源码分析》 中,介绍了有栈协程的实现原理。相比云风的 coroutine,libco 在性能上号称可以调度千万级协程。 从使用上来说,libco 不仅提供了一套类 pthread 的协程通信机制,同时可以零改造地将三方库的阻塞 IO 调用进行协程化。

本文将从源码角度着重分析 libco 的高效之道。

在正式阅读本文之前,如果对有栈协程的实现原理不是特别了解,建议提前阅读 《云风 coroutine 协程库源码分析》

同时,我也提供了 libco 注释版,用以辅助理解 libco 的源码

C++ lambda 内 std::move 失效问题的思考

最近在写 C++ 时,有这样一个代码需求:在 lambda 中,将一个捕获参数 move 给另外一个变量。 看似一个很简单常规的操作,然而这个 move 动作却没有生效。

具体代码如下:

std::vector<int> vec = {1,2,3};

auto func = [=](){
    auto vec2 = std::move(vec);
    std::cout << vec.size() << std::endl; // 输出:3
    std::cout << vec2.size() << std::endl; // 输出:3
};

代码可在 wandbox 运行。

我们期望的是,将对变量 vec 调用 std::move 后,数据将会移动至变量 vec2, 此时 vec 里面应该没有数据了。但是通过打印 vec.size() 发现 vec 中的数据并没有按预期移走。

这也就意味着,构造 vec2 时并没有按预期调用移动构造函数,而是调用了拷贝构造函数。

为什么会造成这个问题呢, 我们需要结合 std::movelambda 的原理看下。(最终的解决方案可以直接看 这里

云风 coroutine 协程库源码分析

随着 Golang 的兴起,协程尤其是有栈协程 (stackful coroutine) 越来越受到程序员的关注。协程几乎成了程序员的一套必备技能。

云风实现了一套 C 语言的协程库,整体背景可以参考其 博客

这个协程库非常轻量级,一共也才 200 多行代码,使用上更贴近于 lua 的写法(众所周知,云风是知名的 lua 粉)。整体基于 ucontext 和共享栈模型实现了有栈协程,代码质量毋庸置疑,本文将详细剖析该协程库的实现原理。

同时,我也提供了 coroutine 注释版,辅助大家理解 coroutine 的代码。

深入理解网络 IO 模型

在进行 Linux 网络编程开发的时候,免不了会涉及到 IO 模型的讨论。《Unix 网络编程》一书中提到的几种 IO 模型,我们在开发过程中,讨论最多的应该就是三种: 阻塞 IO 非阻塞 IO 以及 异步 IO

本文试图理清楚几种 IO 模型的根本性区别,同时分析了为什么在 Linux 网络编程中最好要用非阻塞式 IO。

客户端秒级时间同步方案

在客户端开发中,往往会有一些功能对时间要求比较严格,客户端需要获取到当前最准确的时间。但由于客户端环境多种多样,我们无法保证直接在客户端设备上获取到的时间是最准确的时间。 对于某些问题设备来说,设备时间与比当前实际的时间差了几个小时,甚至几天的情况都存在。倘若某功能依赖于当前时间,而客户端所提供的时间不准,就往往会给客户造成一些困扰。

那么,客户端如何能够获取到当前最准确的时间呢?

muduo 源码剖析

muduo陈硕 大神个人开发的 C++ 的 TCP 网络编程库。muduo 基于 Reactor 模式实现,Reactor 模式也是目前大多数 Linux 端高性能网络编程框架和网络应用所选择的主要架构,例如 Redis 和 Java 的 Netty 库等。

陈硕的《Linux 多线程服务器端编程》一书对 muduo 整个架构进行了非常详尽的介绍和分析,可以说是学习 muduo 源码和设计理念最好的资料了。

而本文则主要是从源码角度辅助理解整个 muduo 的实现,同时也姑且算是对 muduo 的一个小小的补充。

同时我也提供了一个 muduo 注释版,用以辅助理解 muduo 的源码。

自动生成数据库文档小工具的诞生

最近我用 Golang 开发了一个可以将数据库每张表的各个列信息转化成文档的小工具。开发的缘由是因为写后端时,经常需要为数据库写说明文档,对于稍微有些规模的项目来说,就动辄几十张上百张数据表,开发人员在文档中不断的写各个列的列名、类型、描述实在是无聊、枯燥和苦不堪言。所以就有了这个小工具的诞生。

项目地址在 这里

ClassViewer 的介绍及实现

ClassViewer是我最近开发的一个用于展示 jvm class 字节码的小工具。它是一个单纯的静态网页,完全使用浏览器端的 Javascript 开发。之所以开发这款工具,是因为我在开发 ToyJVM 的时候,需要常常校验 class 文件某一部分的字节码, 所以如果一款工具能够很方便的显示 class 文件各个部分的信息和字节码,对于 ToyJVM 的开发将会是一个非常大的帮助。

在开始写代码之前调研了一些类似的产品,主要有 jdk 自带的 javap、国外的 Java-Class-Viewer 以及国人开发的 classpy,它们都是非常不错的 class 文件分析工具,但是也存在着一些算不上缺陷的小问题。所以最终还是决定自己写一个适合自己小工具,同时也加深下 class 结构的理解。

在调研了目前的产品后,我也更加清晰了自己的目标。首先它的受众应该是有兴趣研究 jvm 的程序员,而它应该有这些特性:

  • 不依赖于特定操作系统平台 它应该具备基本的跨平台的能力,因为程序员的 Mac 和 Linux 使用率很高。
  • 无需复杂的安装和编译,无需用户有特定的知识背景 我不太希望用户拿到我的代码后,还需要安装相应的环境、了解一堆无关知识。

最终实现出来的工具是这样的:

首次半马记

4 月 9 号,在武汉参加了人生第一次半程马拉松,风里雨里的 21.0975 公里。虽然已时隔一周,但想到那天一路的奔跑、疲惫、欣喜,还是想记记这半马的流水账。

结合 Guava 源码解读布隆过滤器

BloomFilter(布隆过滤器)是一种可以高效地判断元素是否在某个集合中的算法。

在很多日常场景中,都大量存在着布隆过滤器的应用。例如:检查单词是否拼写正确、网络爬虫的 URL 去重、黑名单检验,微博中昵称不能重复的检测等。

服务器校园网登录验证解决方案

前两天把实验室的一台旧台式机装上了 Ubuntu Server,打算当作测试服务器使用着玩。 装上之后意识到一个严重的问题:实验室电脑连接外网时候需要打开浏览器输入学号进行认证。

第一篇博客

为什么会想到建立一个博客:

在此博客之前,我其实也用过新浪博客、CSDN、博客园,作为个人博客的载体,但对每个博客都并不是特别的满意。原因大概有下面几条:

  • 没有美观友好的支持代码。
  • 广告多。
  • 管理复杂,但可控性差。

目前该博客是使用 hexo+Next 主题 + Github 进行搭建。 事实上,当开始接触使用 hexo 时,我觉得满足了我对博客的诸多要求。我对它的为程序员而生、高度可定制性非常喜欢。而且,如有机会,可以自己写出满意的主题使用。