SEDA工作笔记(一)
摘要
在普遍认知中,软件开发实践是一项充满不确定性的工作,这是由于编码工作占据了其绝大部分的工作,而编码本身就是具有极大不确定性的。同样,计算机科学被视作一门门槛低,基于经验,而无理论意义的纯工程类学科。这种观念不仅为广泛非本专业内人士所共持,即便本门师生,从业人员也偶有赞同。本文试图通过一次对SEDA服务器架构的编程实践的学习与研究,找寻一种科学的解决问题思路。在本次实践中,笔者将强调数学在软件开发中的重要地位,同时指出在核心算法的制定工作阶段,数学是其最重要的工作,而非经验性的设计模式套用。
关键词:SEDA,多线程,并发,量化分析
工作目标
Staged Event Driven Architecture (SEDA) 中文译为阶段事件驱动架构,也称为阶段式服务器模型,是加州大学伯克利分校研究的一套优秀的高性能互联网服务器架构模型。这是一类软件架构模型,它将复杂的、事件驱动的应用分解为一系列通过队列连接的阶段。该模型避免了基于线程的并发模型所带来的高负载问题,同时将事件与线程调度从应用逻辑中解耦。通过对每个队列实施准入控制,使服务得以状态良好地加载。当需求大于服务能力时,能够防止资源过度使用。其设计目标是:支持大规模并发处理、简化系统开发、支持处理监测、支持系统资源管理。
在本次软件实践中,笔者期望得到一个具有可用性的SEDA服务架构的实现方案,并试图将数学方法的使用贯穿于整个过程之中。
前言
笔者将在编程工作开展之前,对量化分析等数学方法进行引入而进行基础的概念介绍。
命题
在现代哲学、数学、逻辑学、语言学中,命题是指一个判断(陈述)的语义(实际表达的概念),这个概念是可以被定义并观察的现象。命题不是指判断(陈述)本身,而是指所表达的语义。当相异判断(陈述)具有相同语义的时候,他们表达相同的命题。
更为简单的定义中,命题是一个或真或假的陈述语句,但不能又真又假。
例:命题
1. 华盛顿是美国的首都。
2. 多伦多是加拿大的首都。
3. 1+1=2。
4. 2+2=3。
这这些例子中,1和3为真命题,2和4为假命题。
例:非命题
1. 几点了?
2. 仔细读这个。
3. x+1=2。
4. x+y=2。
语句1和2不是命题,因为它们不是陈述语句。语句3和4不是命题,因为它们真假性无从判断。
科学理论
两个约定
显然地,并非所有的命题都能被称之为科学理论。所谓科学理论实质上是一个哲学中的约定,在这个约定(波普尔的两个约定)中,科学理论被定义如下:
1. 科学理论是一个严格的普遍陈述。
2. 科学理论要是有一个或几个理论被证伪,整个理论也就被证伪。
可证伪性
除此之外,可证伪性是一个科学理论的必要属性。可证伪性是由经验得来的主张的必要属性,却不是充分属性。可证伪性可表述如下:
如果一个主张是可证伪的,则至少在理论上存在一种观测的方法(即使实际上没有进行这项观测也无妨),来表明这个主张不符合重言式的标准(即这个主张不总是真的)。对某种描述进行观测的逻辑前提是它描述的事物是存在的。
例如“所有的天鹅全都是白色的”这个主张可以被“一个黑色天鹅”的观测证伪,虽然这个观测并不一定会发生。一个可证伪的命题必须定义某些被禁止的情形。例如,在这个例子中,“所有的天鹅全都是白色的”这个主张禁止了“黑色天鹅”的存在。由于理论上可能存在“观测到黑色天鹅”这个反例,“所有的天鹅全都是白色的”这个主张是可证伪的。 再比如假设现在有一个人宣称“我说的话一直都是对的”,那么我们考察他以前说过的话,如果有自相矛盾的地方,那么这句话肯定是个假命题。然而,即使这个人过去一直贯彻一种想法,在他自己的言论中没有自相矛盾之处,也不能作为足够的证据证明这句话是个真命题。
简单总结
任意一个科学理论都应该是经验上可证伪的,而任何一个非科学的理论都是不能用逻辑证明的。同时,一个科学理论不应该具备全部的可能性。如:
1. 明天以后的某个时间,有可能下雨,有可能不下雨。
2. 1+1=2。
计算机程序与算法
以下将带来计算机程序与算法的基本定义。
计算机程序或者软件程序(通常简称程序)是指一组指示计算机每一步动作的指令,通常用某种程序设计语言编写,运行于某种目标体系结构上。
在数学和计算机科学之中,算法(Algorithm)为一个计算的具体步骤,常用于计算、数据处理和自动推理。精确而言,算法是一个表示为有限长列表的有效方法。算法应包含清晰定义的指令用于计算函数 。
大体上,程序与算法之间的区别有以下几点:
1. 一个程序不一定满足有穷性。例操作系统,只要整个系统不遭破坏,它将永远不会停止,即使没有作业需要处理,它仍处于动态等待中。因此,操作系统不是一个算法。
2. 程序中的指令必须是机器可执行的,而算法中的指令则无此限制。
3. 算法代表了对问题的解,而程序则是算法在计算机上的特定的实现。一个算法若用程序设计语言来描述,则它就是一个程序。
在日常的软件开发实践中,我们交付的一个软件/系统,可能涵盖若干文件及程序,究其根本,即承诺所供给的工具是对特定用户的特定问题的通解,或者说是一组特定的算法。进而言之,我们在认定所提交软件的同时,可视作提出了如下一个科学理论:
∀p∈P={(x1, x2, ..., xn) | x1∈C1, x2∈C2, ..., xn∈Cn},
∃r=algorithm(p) 使得
r∈R={(y1, y2, ..., ym) | y1∈B1, y2∈B2, ..., ym∈Bm},
显而易见,这是一个科学理论,因为他是容易证伪的,只需要:
∃r=algorithm(p) 使得
r∉R={(y1, y2, ..., ym) | y1∈B1, y2∈B2, ..., ym∈Bm},
同时我们可以知道的是,当n→∞时,p→∞(甚至p可能是n的高阶无穷大),也就是指任取有限组的p作为输出并验证结果r,仅仅能证明
r∈R'={(y1, y2, ..., ym) | y1∈B1, y2∈B2, ..., ym∈Bm},其中R'是R的某个有限大小的子集。因而为了证明algorithm(p)正确性我们只能通过逻辑工作完成,而不能通过反复测试实现的。
简而言之,算法作为软件的灵魂部分,应该是某种科学理论,可被经验证伪而非证实的,要证明其正确性只能从逻辑入手。
注:期望通过多次随机测试并评测其结果的正确率在直至本文现阶段是行不通的,一个简单的原因是,我们期望随机测试能带来正确性证明本质上是在做某种抽样检验的工作,但因为我们样本空间是无穷大的,因此有限次的测试永远没有办法得出样本结果对整体而言的置信度。这就好比在常规的抽样检验中,总量是1000的样本,抽取100个进行检验所得结果总是比10个更有可信度。然而在当前讨论范畴中就像从10000000个样本中评价对其中1个或2个进行检测哪个更可信,是无意义的。
又,从逻辑学上而言,这种工作本质上是进行归纳并假设的行为,然而归纳是某种认识论,不能成为假设成立的前提,这个工作依然缺乏逻辑证明的部分。
一个例子
在这个例子中,我们将试图探讨冒泡算法及归并算法的性能优劣(此处特指其时间复杂度的比较),算法本身的工作本文将不作赘述。
为此我们将定义如下:
An是指一个含有n个整数的有序集合{a1, a2, a3, ..., an}。
∀An={a1, a2, a3, ..., an}
∃function(An) 使得:
A'n={a'1, a'2, a'3, ..., a'n}, 其中a'1≤a'2≤a'3≤...≤a'n。
特殊地,我们取An为已逆排序的长度为n的序列,及恰好a'1≥a'2≥a'3≥...≥a'n。在这种情况下我们可以轻易地得知,前者进行了n2次操作,而后者仅仅做了nlgn次操作,我们是否可以认为冒泡排序比归并排序慢呢?
又特殊地,取An为已正向排序的长度为n的序列,我们可以轻易地得知,前者事实上仅仅做了一系列的比较,而并未进行实质的操作,耗费的可以视作某个常数量k的时间,而后者则依然进行了nlgn次操作,我们又是否可以认为冒泡排序比归并排序快呢?
尽管两次测试的结果大相径庭,但两者本质上是逻辑上对等的两次互相独立的假设检验。虽然我们知道归并排序的时间复杂度确实更低,也就是第一个场景的结论是与之符合的,但事实上这两个场景的结论却都是不可信的,因为他们都试图用一次特殊的假设检验,来论证一般规律。
小结
在绝大多数算法适用的场合下,测试都是一种试图将有限的个例推广到无限的可能性的尝试,而这既是数学上错误,又是哲学上不能等价的:当我们尝试使用测试来对算法进行证实的时候,本质上并不是一个严密的逻辑形式推理,而是一种概率推理。然而在绝大多数现有的测试过程中,这些工作本身又是不符合概率论的基本要求的,其结论本身也就不具有可信度了。
(未完待续)
SEDA工作笔记(一)的更多相关文章
- 2016年第2周读书笔记与工作笔记 scrollIntoView()与datalist元素
这一周主要是看了html5网页开发实例与javascript 高级程序设计,供以后翻阅查找. html5网页开发实例第1章与第二章的2.1部分: 第1章内容: html5在w3c的发展史. 浏览器的 ...
- javascript - 工作笔记 (事件四)
在javascript - 工作笔记 (事件绑定二)篇中,我将事件的方法做了简单的包装, JavaScript Code 12345 yx.bind(item, "click&quo ...
- 工作笔记3.手把手教你搭建SSH(struts2+hibernate+spring)环境
上文中我们介绍<工作笔记2.软件开发经常使用工具> 从今天開始本文将教大家怎样进行开发?本文以搭建SSH(struts2+hibernate+spring)框架为例,共分为3步: 1)3个 ...
- Sencha Touch2 工作笔记
Sencha Touch2 工作笔记 Ext.dataview.List activate( this, newActiveItem, oldActiveItem, eOpts ) Fires whe ...
- 工作笔记5.JAVA图片验证码
本文主要内容为:利用JAVA图片制作验证码. 设计思路: 1.拷贝AuthImageServlet.class图片验证码 2.配置web.xml 3.JSP中,调用封装好的AuthImageServl ...
- 读书笔记——《MySQL DBA 工作笔记》
关于前言 作者在前言中提出的一些观点很具有参考价值, 梳理完整的知识体系 这是每一个技术流都应该追逐的,完整的知识体系能够使我们对知识的掌握更加全面,而不仅仅局限于点 建立技术连接的思维,面对需求,永 ...
- 《工作笔记:移动web页面前端开发总结》
工作笔记:移动web页面前端开发总结 移动web在当今的发展速度是一日千里,作为移动领域的门外汉,在这段时间的接触后,发现前端开发这一块做一个小小的总结. 1.四大浏览器内核 1.Trident (I ...
- 【工作笔记】BAT批处理学习笔记与示例
BAT批处理学习笔记 一.批注里定义:批处理文件是将一系列命令按一定的顺序集合为一个可执行的文本文件,其扩展名为BAT或者CMD,这些命令统称批处理命令. 二.常见的批处理指令: 命令清单: 1.RE ...
- oracle 工作笔记,不定期更新
此博客为工作时,所见技术问题的解决方案笔记,欢迎大家转载,转载请注明出处,谢谢~ 更新时间: 2017-07-12 1. clob字段值读取时,借用extractvalue或extract函数读取节点 ...
随机推荐
- IE6 png兼容问题
1.IE6 png <!--[if IE 6]> <script src="../js/png.js" type="text/javascript& ...
- 找出整数中第k大的数
一 问题描述: 找出 m 个整数中第 k(0<k<m+1)大的整数. 二 举例: 假设有 12 个整数:data[1, 4, -1, -4, 9, 8, 0, 3, -8, 11, 2 ...
- SGU 207.Robbers
题意: 有m(m<=10^4)个金币分给n(n<=1000)个人,第i个人期望得到所有金币的xi/y,现在给分给每个人一些金币ki使得∑|xi/y-ki/m|最小. Solution: 首 ...
- POJ 2112.Optimal Milking (最大流)
时间限制:2s 空间限制:30M 题意: 有K台挤奶机(编号1~K),C头奶牛(编号K+1~K+C),给出各点之间距离.现在要让C头奶牛到挤奶机去挤奶,每台挤奶机只能处理M头奶牛,求使所走路程最远的奶 ...
- extern "C" {} 来沟通C和C++
比如说你用C++开发了一个DLL库,为了能够让C语言也能够调用你的DLL输出(Export)的函数,你需要用extern "C"来强制编译器不要修改你的函数名. 通常,在C语言的头 ...
- Java发邮件:Java Mail与Apache Mail
作者:Vinkn 来自http://www.cnblogs.com/Vinkn/ 一.邮件简介 一封邮件由很多信息构成,主要的信息如下,其他的暂时不考虑,例如抄送等: 1.收件人:收件人的邮箱地址,例 ...
- php配置虚拟主机的配置步骤(hosts、httpd.conf、vhosts.conf)1.配置本地的dns文件2.配置apache的主配置文件3.配置Apache的虚拟主机
1.域名解析(DNS) 找到C:\Windows\System32\drivers\etc目录下的hosts文件,在里面进行添加对应的内容
- Telerik_2012_Q3 破解全套下载链接
1.Telerik_OpenAccess_ORM_2012_3_1012_SDK.zip (暂未提供下载) 2. Telerik_OpenAccess_ORM_2012_3_1012.zip 3. T ...
- C++ 类的前向声明
前向声明 在计算机程序设计中, 前向声明是指声明标识符(表示编程的实体,如数据类型.变量.函数)时还没有给出完整的定义.即可以声明一个类而不定义它,只声明类但不知道类的成员变量.函数等具体细节. 如: ...
- UIControl-IOS开发
UIControl-IOS开发 UIKit提供了一组控件:UISwitch开关.UIButton按钮.UISegmentedControl分段控件.UISlider滑块.UITextField文本 ...