在实现一个软件系统时,作为系统的设计、实现人员,我们往往需要在选择一个好的方案或者说设计。有些选择针对的是诸如框架等大方向的设计,但更多的时候我们面临的则是针对某个具体模块或函数等小问题的解决方案的选择。

任何一个有经验的程序员都明白,并不是所有的选择都需要经过详细的考虑(否则我们可能陷入设计陷阱而永远无法正真实现我们所需要的功能),但这并不代表对那些小问题的设计方案选择上我们可以做随意的选择。古人说过,勿以善小而不为,勿以恶小而为之;万物皆是相同的,这句话应用到软件设计中,我想就是:这些小问题上,我们不能因为它在系统中起的作用很小要就可以做出草率的决策,但也不必担心这些小模块可能会严重影响系统性能而花费大量的时间和精力来权衡设计选择。如果在任何问题上都花费大量时间和精力去做“完美”的设计,期结果好一点的无非是一个华而不实的over design,但更糟糕的则是可能导致项目延期或最终流产(毕竟任何一个设计方案都有它的局限性,要想通过设计保证程序的效率、可维护性、可扩展性等等诸多方面是不可能的);但如果完全放弃对这些小问题设计上的权衡,我们又往往可能面临是灾难性的后果。

我在最近的一个项目总就犯了一个“勿以善小而不为”的错误:在我们的系统中,由于需要大量重复访问某类资源,而每次访问这些资源都相当消耗时间。一个自然的做法是在程序中引入一个cache,这样在访问资源时我们可以先查询cache,如果所需访问的资源存在cache中了,则直接返回所需的资源,否则才做一次真正的访问并把访问到的结果放到cache中去。从框架的角度来说,引入cache从设计的角度来说是经过比较详细的考虑的:比如哪些资源需要cache,cache的时效性如何处理等等。但在考虑用什么数据结构来做这个cache时,我草率的决定使用ConcurrentHashMap。

在我们的测试环境中,这个cache产生的效果是显而易见的:资源访问对的速度能有数量级的提升,而在cache本身引入的内存开销也没有产生什么异常。但当代码部署到生产环境中后,我们观察到有些客户的主机内存消耗会突然产生一个爆发式的增长,这时由于Java GC的开销,程序性能急剧下降!究其原因,则是这个用于作为cache实现的数据结构是可以无限增长的:在客户环境下,在一段时间内有数百万条记录被存放到了这个cache中!这个问题我在最初决定使用ConcurrentHashMap就意识到过,但考虑到我们会定期的让cache失效(即清空map里面的所有元素),我并没有打算采用稍微复杂点的数据结构来处理这个问题,最终导致了在这种极端情况下出现极其糟糕的结果。

那么如何在实际工作中,在不需要增加额外的时间和精力开销情况下,避免这类问题的产生呢?很简单:根据所做的项目和自己的经验,应该有一个checklist,在面临对模块或函数的设计抉择时,通过这个checklist快速而有效的选择一个可能不是最优,但能保证达到设计目的的一个方案(即所谓的次优解)。这个checklist里面应该包含对一些极端case的考虑:对这种小问题,我们并不是在设计上解决这些极端case,仅仅需要再设计上预防这种极端case则可。有了这个checklist,我们就可以保证在不需要额外太多时间和精力开销的基础上所做出的设计选择能很好的处理正常的逻辑并保证在极端情况下仍可以正常的工作。

软件设计:勿以善小而不为,勿以恶小而为之相关推荐

  1. T31实战-Day3:勿以善小而不为 勿以恶小而为之

    今天跟随着T31的第三节课,Mysql约束与规范,无尘大咖主讲.整体谈了mysql的实操规范,言简意赅,直击痛点:当然听这课程还是需要有mysql一些实际基础(索引.数据结构等层面)作为理解的支撑:给 ...

  2. sql优化--勿以善小而不为 勿以恶小而为之

    最近换新的工作,从java开发转到sql运维,开发时只写一些简单的查询,对sql的优化并没有深入认识,2个月sql运维让我对sql有了点新的认识.记录一下

  3. 勿以恶小而为之,勿以善小而不为

       居勿以恶小而为之,勿以善小而不为.    Do not fail to do good even if it's small, do not engage in evil even if it' ...

  4. 勿以善小而不为,勿以恶小而为之

    如今的善恶已经没有了统一的标准,已经是仁者见仁,智者见智了. 曾经给乞讨者一些小钱觉得是善事,现在已经觉得这样做是在滋养不劳而获而已.这其中自有真实的困难者,但作为凡人的我着实难于分辨,顾已形成漠然的 ...

  5. 勿以恶小而为之,勿以善小而不为。

    勿以恶小而为之,勿以善小而不为.惟贤惟德,能服于人. -- 刘备 刘备简介 [出处]<三国志·蜀书·先主传>裴松之注. [大意]不要以为坏事小就去做,不要以为好事小就不去做. [提示]这是 ...

  6. 超短线炒股:勿以善小而不为,勿以恶小而为之

    什么是短线操作,或者说什么是超级短线操作,那就是"追涨杀跌",如果你对"追"."杀"两字有厌恶,说明你不具备做短线的思想基础,就根本不是股市 ...

  7. 漫谈 · 软件设计中的具象化

    本文微信公众号链接:https://mp.weixin.qq.com/s/PiZU1biNR5DeqrjnhXE9ag 何为具象化?要说具象,就要说说与具象有关的抽象.表象. 抽象与具象: 抽象是通过 ...

  8. 多核片上系统(SoC)架构的嵌入式DSP软件设计

    多核片上系统(SoC)架构的嵌入式DSP软件设计 Multicore a System-on-a-Chip (SoC) Architecture SoCs的软件开发涉及到基于最强大的计算模型在各种处理 ...

  9. 软件设计之 数据库设计

    [按语:在软件设计或是动态网站开发中,数据库设计时很重要,我觉得可以说是开发工作的核心部分,所以学好数据库设计,是很重要的,也是大有前途的...]  ◆.概念 首先要搞清楚容易混淆的两个概念:&quo ...

最新文章

  1. 一文读懂公有链、私有链、联盟链
  2. [汇编语言]实验五:编写,调试具有多个段的程序
  3. java syn包_TCP攻击之SYN攻击
  4. SVN报错Skipped ‘xxxController.class.php‘ -- Node remains in conflict
  5. Ubuntu上搭建Hadoop环境(单机模式+伪分布模式) - 狂奔的蜗牛 - 博客频道 - CSDN.NET http://blog.csdn.net/hitwengqi/article/detai
  6. 求方程ax^2+bx+c=0的实数根
  7. 微信小程序实现FBX模型的动画加载
  8. Trie树 与 三分树(Ternary Trees)
  9. 小程序商城制作一个需要多少钱?
  10. 数据挖掘#特征工程(二)特征重要性及可解释性总结
  11. 树莓派4B(armv7l,arm32)buster安装PyTorch、torchvision、torchaudio、onnxruntime
  12. 中兴笔试题目总结(一)C++部分
  13. numpy.random.randn()与rand()的区别
  14. 高高兴兴看视频,认认真真写程序
  15. iOS适配之autolayout和sizeclass(二)
  16. Aegisub无法打开视频
  17. IP安全讲解(DHCP Snooping、IPSG、DAI)
  18. 微型计算机怎么没声音,电脑没有声音是怎么回事 电脑失声怎么解决【解决方法】...
  19. uni-app实现微信小程序,支付宝小程序,微信、支付宝、银联多商户收款
  20. PMP的全称是什么?

热门文章

  1. 天天生鲜Django项目③
  2. 视频URL地址获取神器:疯狂URL 视频及直播源地址获取
  3. 场景编程应用集锦 - 电闪雷鸣的数学联想
  4. node搭建webrtc信令服务器
  5. redash入门操作
  6. 中付向代理商追索2500万元损失 事涉另一家支付机构20%股权转让
  7. 1 运筹笔记-随机规划(Stochastic Programming)
  8. 开放原子训练营(第三季)inBuilder低代码开发实验室:货运单的开发
  9. Ubuntu查看cuda版本
  10. No suitable kits found.——QT创建项目错误