12 2020 档案

摘要:2019 年初还挺乐呵的,然后有一些不顺利。 春季,CTO来上海访问,我向他推销自己对AI的想法,可能真到要做事时就有太多中间层级,估计没什么用。 我自己也没空做AI,这一年主要在做权限管理系统,这系统可复杂了,基于规则的、行列级粒度的权限控制,提供多种多样的API给业务团队,任务多,难度大,发动大 阅读全文
posted @ 2020-12-31 22:00 计算法 阅读(106) 评论(0) 推荐(0) 编辑
摘要:原文发表于2020-12-18。 继上一篇文章《Java元注解meta-annotation与依赖注入》,我又探索了两大依赖注入技术体系CDI和Spring的关系。Spring实现了CDI规范吗?相信大家也会有这种问题。 事实上有两个规范,一个JSR-299 CDI规范,一个JSR-330 DI规范 阅读全文
posted @ 2020-12-25 18:35 计算法 阅读(195) 评论(0) 推荐(0) 编辑
摘要:原文发表于2020-12-18。 这篇文章既介绍一个技术,又记录一个逐渐探索发现的过程,以供大家参考。 缘起 注意到Java的依赖注入DI规范(起初以为是CDI规范,然后发现是DI规范)有个叫@Qualifier的注解,用于当一个interface或base class有多个实现类时,能选择其中一个 阅读全文
posted @ 2020-12-25 18:31 计算法 阅读(107) 评论(0) 推荐(0) 编辑
摘要:原文发表于2019-08-24。 近年来有一种思潮,认为代码不需要注释——代码即注释。这种思潮是有一定道理的,但很多人难以正确领会。 这一思潮的兴起是由于以往提倡多写注释,很多人没能正确领会“多写注释”的意义,写了一大堆多余甚至有错误的注释: 当注释内容与代码内容重复时,注释就是多余的: // up 阅读全文
posted @ 2020-12-25 18:30 计算法 阅读(299) 评论(0) 推荐(0) 编辑
摘要:原文发表于2019-03-18。 这是由Kubernetes创始人发表的论文,总结了基于容器的分布式系统的设计模式,让我们来一览究竟吧。 论文认为,继OOP(面向对象编程)所引领的软件开发革命之后,如今似乎在分布式系统开发中也发生着一场相似的革命:基于容器化组件构建的微服务架构。 容器的一大独特优势 阅读全文
posted @ 2020-12-25 18:28 计算法 阅读(75) 评论(0) 推荐(0) 编辑
摘要:原文发表于2019-02-28。 虽然Google的MapReduce论文很老了(十多年),但只要还没看,就值得一看。 概要 MapReduce是一种重视容错性的分布式并行计算模式,它把分布式并行计算分为map和reduce两个阶段: map: 把输入数据集切分成很多份(1份可包含很多records 阅读全文
posted @ 2020-12-25 18:23 计算法 阅读(79) 评论(0) 推荐(0) 编辑
摘要:原文发表于2019-02-21。 2017没总结,2018也写得晚,于是两年一起总结吧。 2017 主业基本上就是摆弄OData,一个类似GraphQL的API协议(但是比GraphQL先出现)。 在公司里做了一个微服务和并发编程的分享,顺带安利了Kotlin。 写了这些博客: Kotlin框架巡礼 阅读全文
posted @ 2020-12-25 18:22 计算法 阅读(45) 评论(0) 推荐(0) 编辑
摘要:原文发表于2019-01-15。 这里所说的自动编程,是运用人工智能技术来自动生成程序,尽量免除人类劳动。 在自动产生程序之前,先要知道需求是什么吧?要能把需求准确地描述给机器,这就需要一种需求描述语言。假如我们制造了这种需求描述语言,它进一步发展,越发规范,成为了一种DSL(领域特定语言)。嗯,这 阅读全文
posted @ 2020-12-25 18:21 计算法 阅读(594) 评论(0) 推荐(0) 编辑
摘要:原文发表于2017-09-28。 某个测试服务器试图通过反射来修改static final变量的值,出现了时灵时不灵的现象。 开发环境无法重现。这是怎么回事呢? 先介绍背景知识 一般认为,static final常量会被编译器执行内联优化,即它的值会被内联到调用位置。 这对于如下方式初始化的字面常量 阅读全文
posted @ 2020-12-25 18:20 计算法 阅读(70) 评论(0) 推荐(0) 编辑
摘要:原文发表于2017-09-01。 情况 Lambda的表示法是 ,例如: val func = { println() } val func = { x -> println(x) } 若函数的唯一或最后一个参数是函数类型,可以不需要用括号围住这个参数,这样就能随手写出这样漂亮的DSL: // tr 阅读全文
posted @ 2020-12-25 18:18 计算法 阅读(60) 评论(0) 推荐(0) 编辑
摘要:原文发表于2017-04-10。 问题 今天忽然发现轻境界无法输出日志了,控制台输出以下警告⚠️: SLF4J: No SLF4J providers were found. SLF4J: Defaulting to no-operation (NOP) logger implementation 阅读全文
posted @ 2020-12-25 18:02 计算法 阅读(212) 评论(0) 推荐(0) 编辑
摘要:原文发表于2017-04-06。 很高兴Kotlin在前两天发布了Kotlin/Native的Tech Preview版本。Kotlin/Native能把Kotlin编译成机器码,也就是C/C++、Go和Rust的层次,于是这个领域又添一位竞争对手。 JetBrains是一家务实的公司,它家的各种I 阅读全文
posted @ 2020-12-25 17:58 计算法 阅读(92) 评论(0) 推荐(0) 编辑
摘要:原文发表于2017-04-03。 向大家推荐这篇文章——Redis架构之防雪崩设计:网站不宕机背后的兵法 (另外推荐我去年的小文章作为餐前点心——略谈服务端缓存设计) 《Redis架构之防雪崩设计》这篇文章(下文称之为“原文”)写得非常好,全面概括了大规模系统可能面对的缓存穿透和缓存雪崩等问题,可以 阅读全文
posted @ 2020-12-25 17:57 计算法 阅读(49) 评论(0) 推荐(0) 编辑
摘要:原文发表于2017-03-31。 问题 昨天凌晨1点多,可能是V友太热情,或者爬虫太勤奋,轻境界的服务器宕机了,悄悄地,没有留下错误日志。 我上午收到用户反馈,赶快先重启服务器压压惊,再来分析原因。 连错误日志都没有,这是什么程度的问题呢? 最大的可能性是 JVM内存不够用 或 线程数过多。需要调整 阅读全文
posted @ 2020-12-25 17:55 计算法 阅读(37) 评论(0) 推荐(0) 编辑
摘要:原文发表于2017-03-14。 可以用irb(Ruby的REPL程序)实际运行: class A [:scope, :show_snippets, :search_results, :search_objects].each do |name| define_method name do sear 阅读全文
posted @ 2020-12-25 17:52 计算法 阅读(36) 评论(0) 推荐(0) 编辑
摘要:原文发表于2017-02-12。 首先要说明,Kotlin支持你所知道的所有Java框架和库,包括但不限于Spring全家桶、Guice、Hibernate、MyBatis、Jackson等,甚至有人在用Kotlin写Spark大数据程序,因此Kotlin不需要专门的框架。因此,为Kotlin开发框 阅读全文
posted @ 2020-12-25 17:51 计算法 阅读(165) 评论(0) 推荐(0) 编辑
摘要:原文发表于2016-12-31。 一些事件: 今年终于养成了记日记的习惯 上线了“轻境界” 每个月都在轻境界发表了文章,其中《JVM并发编程模型览》历经两年终于完成 考到了驾照 每日俯卧撑数量达到150 开源项目: 完善了Answerer (主要能自动生成跨类型的bean copier代码) 完善了 阅读全文
posted @ 2020-12-25 17:50 计算法 阅读(49) 评论(0) 推荐(0) 编辑
摘要:原文发表于2016-11-27。 本文介绍和点评JVM上的Thread, Thread Pool, Future, Rx, async-await, Fiber, Actor等并发编程模型。本人经验有限,难免粗陋,还请高手多多指教。 我们知道程序分为同步风格和异步风格。 可以写成同步风格用多个线程来 阅读全文
posted @ 2020-12-25 17:46 计算法 阅读(48) 评论(0) 推荐(0) 编辑
摘要:原文发表于2016-10-31。 Kotlin是什么? 著名IDE厂商JetBrains开发的基于JVM的静态类型编程语言,声称100% interoperable with Java。Kotlin是由工程师设计的,各种细节设计非常切合工程师的需要。语法近似Java和Scala,且已活跃在Andro 阅读全文
posted @ 2020-12-25 17:43 计算法 阅读(59) 评论(0) 推荐(0) 编辑
摘要:原文发表于2016-08-24。 有人问以下情况如何得到泛型参数的实际类型: APIService api = new APIService<User>(); 由于Java的类型擦除,没有办法获取,APIService不知道它被赋予了User。 但可以变通一下: APIService api = A 阅读全文
posted @ 2020-12-25 17:42 计算法 阅读(264) 评论(0) 推荐(0) 编辑
摘要:原文发表于2016-08-03。 1. 用线程池执行异步任务 为了减少阻塞时间,加快响应速度,把无需返回结果的操作变成异步任务,用线程池来执行,这是提高性能的一种手段。 你可能要惊讶了,这么做不对吗? 首先,我们把异步任务分为两种: 务必成功执行的 不成功就放弃 显然大多数时候都是第一种。那么当你把 阅读全文
posted @ 2020-12-25 17:41 计算法 阅读(55) 评论(0) 推荐(0) 编辑
摘要:原文发表于2016-07-10。 问题背景 略谈服务端缓存设计 一文说到缓存不是必须的,因为数据库本身就利用了内存。但实际情况是缓存是大型网站的标配。 虽然经验显示RDBMS最快时只需0~1ms就能响应,不逊于专门的缓存,但是当压力增大时,性能的下降也是飞快的。随着业务的逐渐复杂、开发团队的逐渐扩大 阅读全文
posted @ 2020-12-25 17:40 计算法 阅读(41) 评论(0) 推荐(0) 编辑
摘要:原文发表于2016-01-11。 今天上午满屋子找了一个小时也找不到眼镜。这种不显眼的东西,如果戴上眼镜到处望或许能找到,但丢的就是眼镜啊…… 这么找不是办法,于是我定下来进行推理。简单分析注意到,眼镜的失踪,分为今早用了眼镜和今早没用眼镜两种情况。如果今早用了,应该就放在我上午的活动范围内;如果今 阅读全文
posted @ 2020-12-25 17:38 计算法 阅读(69) 评论(0) 推荐(0) 编辑
摘要:原文发表于2015-10-14。 大略谈一下,各位轻拍哦! 服务端性能优化,除了重构,最常用的手段就是缓存。缓存主要分为本地缓存和分布式缓存两种。 根据我们每日千万次访问的经验来看,缓存不是必须的。优化充足的情况下,SQL平均耗时1ms。这是因为命中了索引,并且命中了MySQL缓冲池(内存中)。如果 阅读全文
posted @ 2020-12-25 17:36 计算法 阅读(40) 评论(0) 推荐(0) 编辑
摘要:原文发表于2015-09-18。 ThreadLocal是个很爽的东西,线程安全,能当全局变量来用(别!)。 上一篇末尾提到ThreadLocal的妙用,这东西确实在框架实现中很常用。不过一定要小心啊。 先告诉大家一个安全秘诀:try-finally大法,百战百胜!(一定要在finally里清空Th 阅读全文
posted @ 2020-12-25 17:33 计算法 阅读(94) 评论(0) 推荐(0) 编辑
摘要:原文发表于2015-09-18。 熟悉Scala的人知道返回值是代码块的最后一句,一般不能提前返回。return关键字是用抛异常来实现的,这样就能提前脱离代码块了。 最近看Scala源代码,注意到它对return的高效实现,有趣。 ##Scala咋实现的? 抛的异常类是NonLocalReturnC 阅读全文
posted @ 2020-12-25 17:32 计算法 阅读(54) 评论(0) 推荐(0) 编辑
摘要:原文发表于2015-05-17。 概念 不可变对象(Immutable Object),就是状态始终不会改变的对象,例如值对象(Value Object),无状态的服务对象(Stateless Service Object)。 Java和Scala都是JVM语言,都经常用synchronized来做 阅读全文
posted @ 2020-12-25 17:30 计算法 阅读(54) 评论(0) 推荐(0) 编辑
摘要:原文发表于2015-04-16。 ###问题 我们写代码是喜欢从左到右一路写过去的,多流畅,多顺手啊! 考虑这种代码:返回某些数据的json形式。 大概会这么写: def getyou() = { Json(Map("a"->1, "b"->2)) } 我写出了获取数据的表达式Map("a"->1, 阅读全文
posted @ 2020-12-25 17:28 计算法 阅读(55) 评论(0) 推荐(0) 编辑
摘要:原文发表于2015-04-12。 当你采用Spring之类的框架,用了声明式事务,难道每一段需要事务的代码都必须写成一个bean method,再标上@Transactional? 未免太麻烦了,不信你瞧。假如你写了类似这样的Controller和Service (伪代码): class UserC 阅读全文
posted @ 2020-12-25 17:27 计算法 阅读(67) 评论(0) 推荐(0) 编辑
摘要:原文发表于2015-02-12。 网上介绍Java 8 lambda和集合新特性的代码太千篇一律了,我来提供些不一样的。虽然很简单,但也是工业级代码,不是网上抄来抄去的教学代码。权当给大家提供一个思路。 你想把Collection<T>转换成Collection<R>,或者复制、合并、排序,你可以用 阅读全文
posted @ 2020-12-25 17:25 计算法 阅读(71) 评论(0) 推荐(0) 编辑
摘要:原文发表于2014-09-13。 现代对象设计主张“组合优于继承”。总之无论组合还是继承,对象都成了涉及多个类的复合结构。 “对象的有效范围”,是指对象从创建到丢弃(不再引用)的这段时间,不包括等待被GC销毁的时间。可以近似认为是对象的生命期。 单例对象(Singleton)的有效范围几乎是整个应用 阅读全文
posted @ 2020-12-25 17:23 计算法 阅读(42) 评论(0) 推荐(0) 编辑
摘要:原文发表于2014-09-10。 前段时间知乎上有人发了这么个段子: 某日,老师在课堂上想考考学生们的智商,就问一个男孩: “树上有十只鸟,开枪打死一只,还剩几只?” 男孩反问:“是无声手枪,还是其他没有声音的枪么?” “不是.” “枪声有多大?” “80~100分贝.” “那就是说会震的耳朵疼?” 阅读全文
posted @ 2020-12-25 17:21 计算法 阅读(96) 评论(0) 推荐(0) 编辑
摘要:原文发表于2015-05-14。 最后再啰嗦一篇吧,分享些宏观经验,供需要做类似事情的人参考。 技术示例在前篇! 伸手党绕行! 大规模系统重构,不可避免要触到各个团队/模块的很多代码,很可能破坏功能,到时候你就成众矢之的了,tickets扑面而来,到处灭火。 怎么确保不破坏功能呢?就要做安全重构。( 阅读全文
posted @ 2020-12-25 17:20 计算法 阅读(102) 评论(0) 推荐(0) 编辑
摘要:原文发表于2015-04-24。 本系列临近尾声,科技树到此点满。 语法分析主要用库解决了,代码变成了一棵树,但是变量类型,方法签名之类的东东都不清楚。 如果做IDE插件,可以享受IDE的语义分析能力。为了让程序独立运行,我自己按需实现了语义分析。(更新:JDK已提供可观的编译器API,也可以使用, 阅读全文
posted @ 2020-12-25 17:19 计算法 阅读(364) 评论(0) 推荐(0) 编辑
摘要:Java代码分析器(四): 代码改写技术 一般的工具只能分析代码,不能改变代码,除了IDE的重构功能。但我们还是有办法实现的。 不想让黑科技失传,趁着Java 7还在广泛使用,赶紧写下来(可能无法支持Java 8)。(更新:已支持Java8) 这个小框架让你看文章前就能上手,快速对代码库做分析/改写 阅读全文
posted @ 2020-12-25 17:15 计算法 阅读(237) 评论(0) 推荐(0) 编辑
摘要:原文发表于2015-02-05。 上篇介绍的形形色色的语法元素大概让人眼花缭乱了,而且每种元素都对应一个Java类。知道是一回事,使用就是另一回事了,这么多个类,要给每个类写对应的处理代码,不胜其烦。ASTVisitor虽然能自动遍历语法树,但是并不能帮你处理每一种结点。 好在JDT提供了更加抽象的 阅读全文
posted @ 2020-12-25 17:14 计算法 阅读(82) 评论(0) 推荐(0) 编辑
摘要:原文发表于2014-09-07。 上篇博客末尾提到了一棵抽象语法树长什么样子。JDT提供了一套DOM API来让我们顺利地控制这样一棵树。 读完本篇后请继续完成上篇的延伸阅读:http://help.eclipse.org/ 点击JDT Plug-in User Guide → Programmer 阅读全文
posted @ 2020-12-25 17:11 计算法 阅读(116) 评论(0) 推荐(0) 编辑
摘要:原文发表于2014-07-17。 这是一个关于抽象语法树(Abstract Syntax Tree, AST)的故事。 抽象语法树是对程序代码的结构化表示,是对代码进行词法分析、语法分析后得到的产物。编译器要用到它,很多生产力工具也要用它,例如: IDE可以自动重构、自动生成一些代码、自动对不规范代 阅读全文
posted @ 2020-12-25 17:09 计算法 阅读(274) 评论(0) 推荐(0) 编辑