高性能系统设计
未读 一、功能定义:
–商品 :展示商品,商品管理,……
–交易 :创建交易,交易管理,……
–用户 :注册用户,信息查询,用户管理,……
二、技术发展
第一版:简单基础版
出于快速开发的考虑,第一版往往采用单台机器构建(这里采用java技术,下同),这样开发方便而且快速,采用的技术甚至可以是最简单的jsp,servlet等。
它的技术特点:
•三个功能模块
•一个数据库中的三个表
•连接数据库使用了JDBC
•模块之间的调用是JVM内部的方法调用
第二版:应用和数据库分离
随着访问量的上升,这台机器的负载越来越高,这时可以说是该网站遇到的第一个性能问题,此时一般的解决方案很简单,将应用(App)和数据库(DB)拆分到两台机器上
这种改造实现了应用服务器和数据服务器的分离,对开发、测试、部署,没什么影响。
第三版:多台应用服务器
访问量持续上升,应用服务器的压力也变的很大,第二版的简单设计已经不能支撑这么大的访问量,所以不得不继续对其进行改造。
它的设计方案就是将应用从1台拆分到了两台,甚至多台。但此时会遇到的问题——sessio ...
问题提出:12.0f-11.9f=0.10000038,”减不尽”为什么?
现在我们就详细剖析一下浮点型运算为什么会造成精度丢失?
1、小数的二进制表示问题
首先我们要搞清楚下面两个问题:
(1) 十进制整数如何转化为二进制数
算法很简单。举个例子,11表示成二进制数:
11/2=5 余 1
5/2=2 余 1
2/2=1 余 0
1/2=0 余 1
0结束 11二进制表示为(从下往上):1011
这里提一点:只要遇到除以后的结果为0了就结束了,大家想一想,所有的整数除以2是不是一定能够最终得到0。换句话说,所有的整数转变为二进制数的算法会不会无限循环下去呢?绝对不会,**整数永远可以用二进制精确表示 **,但小数就不一定了。
(2) 十进制小数如何转化为二进制数
算 ...
原文:https://blogs.oracle.com/corejavatechtips/source-code-analysis-using-java-6-apis
静态代码分析工具Checkstyle, FindBugs,以及IDE如NetBeans, Eclipse能快速进行代码关联,它们使用了API解析代码,生成AST,深入分析代码元素。JAVA 6 提供了3种新API来完成这样的任务:
http://www.jcp.org/en/jsr/detail?id=199">Java Compiler API(JSR 199),
http://www.jcp.org/en/jsr/detail?id=269">Pluggable AnnotationProcessing API (JSR 269)
http://java.sun.com/javase/6/docs/jdk/api/javac/tree/index.html">CompilerTree API.
在本文中,我们探讨了其中每个 API 的功能,并继续开发一个简单的演示应用程 ...
在Spring中有BeanFactory和FactoryBean这2个接口,从名字来看很相似,比较容易搞混。
一、BeanFactoryBeanFactory是一个接口,它是Spring中工厂的顶层规范,是SpringIoc容器的核心接口,它定义了getBean()、containsBean()等管理Bean的通用方法。Spring的容器都是它的具体实现如:
DefaultListableBeanFactory
XmlBeanFactory
ApplicationContext
这些实现类又从不同的维度分别有不同的扩展。
1.1、源码1234567891011121314151617181920212223242526272829303132333435363738public interface BeanFactory { //对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象, //如果需要得到工厂本身,需要转义 String FACTORY_BEAN_PREFIX = "&& ...
我在做什么
曾经,我试过接到一些需求。一眼带过后,脑袋马上随着高昂的斗志沉溺在代码的世界中 ,马不停蹄地敲着键盘直到最后测试的完成。我从思绪中恢复过来,乍一看自己写的功能,和需求差了十万八千里,我TM都在干嘛?
除此之外,我还见过类似的很好笑的事情。有一个程序员,经理提了需求,然后他在那里折腾了一天。结果不但没做出来,而且和实际需求都是完全搭不上调。经过询问发现,他不知道经理说了什么,也不知道自己到底在做什么。
代码的世界可能是昏天暗地的,但是我们的思维不能这样随之混乱,否则一切都会前功尽弃。所以我现在编写程序的时候,经常会想一下:我要做什么,我在做什么。更好的方法是把详细需求落实到文档,并时刻核对文档。
大局为重
2-8法则告诉我们,一个项目核心的功能只有很少,其它大部分都是对核心功能辅助或增强的。但当任务分发下来,我手头总有一些自己很想开发的模块,不过它们不属于那20%。我以前经常会在这些感兴趣的模块上花费很多时间和精力。
结果项目快要到上线期限,主要的功能却没开发完成,其它一些不起眼的功能却做得很好,但为此项目不得不延期了。如果反过来,只要对整体功能 ...
先说一个小笑话。有一个生产队队长,他对专家说:“现在我们生产队的地越来越多,牛越来越忙不过来了。我想要这么一种牛,他吃的草和普通牛一样多,但是干的活是普通牛的十倍。”专家说:“这种牛是可以造出来的,现在有基因工程。”队长说:“好吧,你给这造几头这样的牛。”于是专家找到了生物实验室,让生物实验室的人搞一个基因工程,把牛造出来。于是工程浩大,投资无法保证,合作多半是不愉快的收场。
现实世界里很多人分析需求的过程就类似于这位专家,他们把注意力放在用户提出的功能点上,而对用户的实际需求没有兴趣。有不少软件公司和程序员,其实都在做类似的基因工程。如果这个专家把注意力放在生产队长的业务需求上,而不是太在乎他提出的功能点,他会说:“我认识一个卖拖拉机的,可以带你去看看。”
软件的维护为什么这么痛苦,一个很重要的原因在于:需求已经被遗忘了。
需求是对用户具有直接商业价值的活动,而不应该牵涉到任何的功能实现方式。实现同一个需求可以使用多个方案,每个方案有自己的功能方式,在某个方案中至关重要的功能点,也许在另一个方案中根本无关紧要。
瀑布式的开发过程,首先是由一批懂得用户业务的专家去调查用户的需求,分析出 ...
系统架构
未读 新浪微博在短短一年时间内从零发展到五千万用户,我们的基层架构也发展了几个版本。第一版就是是非常快的,我们可以非常快的实现我们的模块。我们看一下技术特点,微博这个产品从架构上来分析,它需要解决的是发表和订阅的问题。我们第一版采用的是推的消息模式,假如说我们一个明星用户他有10万个粉丝,那就是说用户发表一条微博的时候,我们把这个微博消息攒成10万份,这样就是很简单了,第一版的架构实际上就是这两行字。第一版本的技术细节,典型的LAMP架构,是使用Myisam搜索引擎,它的优点就是速度非常快。另外一个是MPSS,就是多个端口可以布置在服务器上。为什么使用MPSS?假如说我们做一个互联网应用,这个应用里面有三个单元,我们可以由三种部署方式。我们可以把三个单元部署在三台服务器上,另外一种部署模式就是这三个单元部署在每个服务器上都有。这个解决了两个问题,一个是负载均衡,因为每一个单元都有多个结点处理,另外一个是可以防止单点故障。如果我们按照模式一来做的话,任何一个结点有故障就会影响我们系统服务,如果模式二的话,任何一个结点发生故障我们的整体都不会受到影响的。
我们微博第一版上线之后,用户非 ...
软件设计
未读 今天这堂培训课讲什么呢?我既不讲Spring,也不讲Hibernate,更不讲Ext,我不讲任何一个具体的技术。我们抛开任何具体的技术,来谈谈如何提高代码质量。如何提高代码质量,相信不仅是在座所有人苦恼的事情,也是所有软件项目苦恼的事情。如何提高代码质量呢,我认为我们首先要理解什么是高质量的代码。
高质量代码的三要素
我们评价高质量代码有三要素:可读性、可维护性、可变更性。我们的代码要一个都不能少地达到了这三要素的要求才能算高质量的代码。
1. 可读性强
一提到可读性似乎有一些老生常谈的味道,但令人沮丧的是,虽然大家一而再,再而三地强调可读性,但我们的代码在可读性方面依然做得非常糟糕。由于工作的需要,我常常需要去阅读他人的代码,维护他人设计的模块。每当我看到大段大段、密密麻麻的代码,而且还没有任何的注释时常常感慨不已,深深体会到了这项工作的重要。由于分工的需要,我们写的代码难免需要别人去阅读和维护的。而对于许多程序员来说,他们很少去阅读和维护别人的代码。正因为如此,他们很少关注代码的可读性,也对如何提高代码的可读性缺乏切身体会。有时即使为代码编写了注释,也常常是注释 ...
概述在应用软件开发领域,对表达式计算的应用有非常广泛的应用。例如,在报表开发中,经常为用户提供公式输入功能,从而实现更灵活的报表汇总;工作流应用软件中,经常利用逻辑条件进行动态配置,从而提供更加灵活的流程配置;另外,在某些 UI 开发中,需要通过某个属性的表达式计算结果来动态控制 UI 组件的显示。所有这些应用都可以归结为一个通用模型,即表达式的解析以及计算。本文旨在提供一种可扩展的表达式解析及其计算方法。
表达式解析的一般条件及因素
本文所讲的表达式是一种以一定的运算规则组合所表达的字符串;另外,通过解析表达式字符串并以其代表的运算规则可以得到一个结果。表达式解析一般需要满足下列条件:
支持的操作符集合
操作符的优先级
操作符所代表的操作规则集合
支持的分隔符集合以及分隔符所代表的意义
支持的数据类型集合
语法约束,如命名规则、分割符所代表的语法规则等
表达式解析除了以上必须满足的条件之外,在有些表达式环境中,可能还支持函数、变量。结合本文所要解决的问题,如下列出可选的条件:
支持的内部函数集合
支持的内部全局变量
支持函数定制
支持自定义变量
支持函数以及操作符重载
以上最 ...
导读:你曾去想重构一个很老的模块,但是你只看了一眼你就恶心极了。文档,奇怪的函数和类的命名,等等,整个模块就像一个带着脚镣的衣衫褴褛的人,虽然能走,但是其已经让人感到很不舒服。面对这种情况,真正的程序员会是不会认输的,他们会接受挑战认真分析,哪怕重写也在所不惜。最终那个模块会被他们重构,就像以前和大家介绍过的那些令人销魂的编程方式中的屠宰式编程一样。
下面是重构代码的几个阶段,文章译自《The 7 stages of refactoring》这篇文章。内容如下:
第一阶段——绝望
在你开始去查看你想要重构的模块的,你会觉得好像很简单,这里需要改一个类,那里需要改两到三个函数,重写几个函数,看上去没什么大不了的,一两天就搞定了。于是你着手开始重构,然后当你调整重构了一些代码,比如改了一些命名,修理了一些逻辑,渐渐地,你会发现这个怪物原来体型这么大,你会看到与代码不符甚至含糊不清的注释,完全摸不着头脑的数据结构,还有一些看似不需要方法被调了几次,你还会发现无法搞清一个函数调用链上的逻辑。你感到这个事可能一周都搞不定,你开始绝望了。
第二阶段——找最简单的做
你承认你要重构的这个模块就是一个 ...
