如何学好程序设计?

mikel阅读(637)

俗话说“兴趣是最好的老师”,但是只靠兴趣是远远不够的,还需要付出艰辛的努力。程序设计是一种技能,需要在较短的时间内学会,就不能像学习汉语一样,通过十几年甚至更长的时间来学好,也不能像英语那样进行业余学习,以至很多大学毕业的人英语水平也不敢恭维,也达不到实用的程度。
那么如何学好程序设计呢?或者更现实一点,如何在短时间内成为一个程序员呢?
在接触的学生中,很多人会问:学习程序设计有捷径吗?一般我都不直接回答,而是这样反问他们:大家都看过武侠小说吧,那么练武有没有捷径呢?可能一部分学生会说没有,而另一些同学会说,练武有捷径的啊,比如什么“辟邪剑谱”、“葵花宝典”之类的,但是走这些捷径需要付出很大的代价,但是的确可以快速炼成绝世武功。可惜的是,学习程序设计连这些付出很大代价的秘籍都没有。
但是在实际的学习中,就像练武一样,如果有位前辈对你进行指点或引导,的确可以提高你学习的速度,但是你还是要付出艰辛的努力。
在介绍如何学好程序设计以前,首先要搞明白,学习程序设计需要学什么,其实不外乎以下内容:
l 程序设计语言
语言是程序最终表达的方式,必须熟练。
l 开发工具
开发工具相当于练武的武器,拿个趁手的武器可以发挥你的潜能
l 开发技术
开发技术就是实现好的功能,可以直接拿来用的结构,类似于武功秘籍,但是一定要熟练到可以灵活使用啊。
l 逻辑思维
如何实现程序的要求功能。
l 设计模式
设计模式就是设计的技巧,类似于写作文时的倒序、插叙什么的。
其实学好程序的方法很简单——“勤学苦练”。多读代码,多写代码,是学好程序的基本方式。需要把各种东西熟练到可以灵活使用的程度,由于学习的时间一般都比较紧,不能像汉语那样炼成习惯成自然的方式,所以在开始学习的初期伴随着大量的记忆,在记忆的基础上进行使用,仔细记忆并体会每个细节,把合适的内容用在合适的地方。
当然,学习最好的开始是模仿,但是由于程序很灵活,所以一定要在模仿的基础上理解,理解了以后进行创新,把东西理解了以后,这些内容就变成了自己的,即使忘记了,也很容易的捡起来,而不要囫囵吞枣式的学习,那样无法做到灵活的解决问题。
当学会了程序设计以后,就可以成为大师级的人物,像武侠小说里的那些大侠一样,做到“意由心生”、“无招胜有招”了,祝福每个初学者以及从事开发的人员,能够早日进入到该境界。
PS:关于英文阅读能力的锻炼,坚持读1-2本英文原版书籍(网上很容易下到很多原版电子书),就可以获得比较大的提升。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2246408

你适合学习程序设计吗?

mikel阅读(727)

Java编程那些事儿3——你适合学习程序设计吗?
作者:陈跃峰
出自:http://blog.csdn.net/mailbomb
程序设计是一个技术活,所以不是适合所有的人。现在很多人听说程序设计人员待遇如何如何的好,都一窝蜂的来学习程序,其实这个现象很不正常,因为程序不一定适合你。其实对于一个人来说,适合你的才是最好的。
就像现在很多小孩子都被家长逼着去学钢琴啊什么,有些小孩根本没有艺术细胞的,所以学习的效果就是差强人意了。
其实程序设计最需要基础扎实了,现在的程序设计学习很偏重程序设计语言的学习,或者直白点说,程序设计课程基本上可以说是在学习程序设计语言,在上一个内容中已经讲解了程序设计是什么的问题,程序设计语言只是程序设计中最后的环节,也是比较简单的环节,只学会程序语言,离实际工作的距离还很遥远,而更多的程序基础其实是在语言之外的东西。就像会写汉字,熟悉汉语语法的人一定能够成为作家吗?
程序设计的基础不外乎以下几个方面:
1、 一定的英文阅读能力
因为程序设计接触的很多文档都是以英文的形式提供的,一个阅读英文很困难的人,可以学会程序设计,但是不会有很深的造诣。就像一个看不懂字典的人,能学好汉语吗?
2、 较强的数学基础
计算机最核心的功能就是计算,各种程序逻辑都会被转成一定格式的运算,运算需要什么知识呢,肯定是数学了。就像一个数学很差的人能做好会计吗?在程序设计中,需要深刻理解数学,用数学来解决你遇到的各种实际问题,类似于做数学应用题吧。这个基础学要长期的积累。
3、 较强的逻辑思维能力
逻辑思维可能每个程序设计人员都很需要,那么逻辑思维是什么呢?其实就是把一个事情分解成一系列的步骤在有限的时间内做完,这个也是程序设计过程中最灵活的地方。例如你要完成“去罗马”这件事情,那么逻辑有多少种呢?借用一句俗话“条条大道通罗马”来解释这个问题吧,所以程序设计是典型的脑力劳动。可能有些人觉得程序设计就是体力活,这也不错,为什么呢,还是借助一个例子来说明吧,买油翁的故事大家都知道吧,如果你反复做一件相同的事情,可能这个事情对外人来说是脑力劳动,对于不断重复做的人来说,也就只是“唯手熟尔”的体力活罢了。
可能很多初学者对于逻辑思维还不是很清楚,那么举一个比较老套的例子吧,例如实现“把一个大象放到冰箱里”这个事情,逻辑是怎样呢?步骤如下:
a、 打开冰箱
b、 把大象推到冰箱里
c、 关上冰箱的门
当然这只是一个很简单的逻辑。在实际的程序设计中还需要严谨的逻辑思维,保证程序可以正常运行。
那么逻辑严谨又是什么呢?还以上面的例子为例,严谨的逻辑思维应该做如下事情:
a、 冰箱打不开怎么办?
b、 大象不进冰箱怎么办?
c、 关不上冰箱门怎么办?
就像一个运动员来说,良好的体质是基础,同样,对于程序员来说,良好的基础可能帮助你达到更高的高度。当然基础不可能每个人都具备,但是数学基础和逻辑思维能力是必须的。
那你的数学基础如何呢,出个简单的数学题目测试一下你的数学基础吧。
已知一组从1开始的数字,第一行从左到右依次是1到10,第二行从左到右依次是11到20,按照每行10个的顺序依次类推,则任意整数n(n>0)位于该组数字的第几行第几列呢?
所以,如何你觉得以上的内容你欠缺很多,可能你就不适合做程序设计这个职业,趁早选择其他的职业吧,这样对你的发展会更有利。如果你觉得以上的内容你大部分都符合,那么你可以尝试学习一下后续的内容——《如何学好程序设计》。
希望大家积极讨论,不足之处请大家积极指正。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2246284

程序设计是什么?

mikel阅读(872)

Java编程那些事儿2——程序设计是什么?
作者:陈跃峰
出自:http://blog.csdn.net/mailbomb
程序设计,俗称编程,是一个比较专业的概念。初学者,甚至一部分开发人员,都不能很简单的解释这个概念,所以使初学者觉得程序设计是一件很有科技含量,或者是很高深的学科,其实这些都是误解。那么程序设计到底是什么呢?
程序,其实就是把需要做的事情用程序语言描述出来。类似如作家,就是把自己头脑中的创意用文字描述出来。所以学习程序,主要就是三个问题:做什么、怎么做和如何描述,具体如下:
1. 做什么
做什么就是程序需要实现的功能。
2. 怎么做
怎么做就是如何实现程序的功能,在编程中,称为逻辑,其实就是实现的步骤。
3. 如何描述
就是把怎么做用程序语言的格式描述出来。
所以,对于有经验的程序设计人员来说,学习新的程序设计语言的速度会比较快,就是因为第1和第2个问题基本解决了,只需要学习第3个问题即可了。
对于“做什么”的问题,可能初学者觉得会比较简单,其实在大型项目开发,例如ERP,企业都不能很详细的说明需要实现具体的功能,这就需要有专门的人员去发掘具体的功能,这个用程序的术语叫做需求分析。举个例子吧,例如某个人要找个女朋友,如果你大概去问他,他会说,找个中等的就可以了,但是这个还不是具体的需求,你可能需要问一下,要求女朋友的年龄是多少,身高是多少等等具体的问题。所以说,搞清楚“做什么”也不是简单的事情,需要专门的人员从事该工作。
对于“怎么做”的问题,是初学者,甚至很有经验的开发人员都头疼的事情,这个称作程序逻辑。因为实际的功能描述和程序设计语言之间不能直接转换,就像作家需要组织自己的思路和语言一样,程序设计人员也需要进行转换,而且现实世界和程序世界之间存在一定的差异,所以对于初学者来说,这是一个非常痛苦的过程,也是开始学习时最大的障碍。由于计算机自身的特点,“怎么做”的问题其实就是数据和操作的问题,某个顶级大师曾经说过:“程序=数据结构+算法”,把这个问题描述的简单准确。那么“怎么做”的问题,就变成了持有那些数据,以及如何操作这些数据的问题。先简单的介绍这么多,大家仔细体会吧。
对于“如何描述”的问题,是学习程序最容易,也是最枯燥的问题。其实就是学“透”一套格式,并且深刻理解语言的特点。学程序语言,就像学汉语差不多,需要学习字怎么写,学习语法结构等,只是不需要像汉语这样学那么多年,但是学好一个语言还是要耐得住寂寞。语法的学习需要细致,只有深刻领悟了语法的格式才能够熟练使用该语言。
前面介绍的是程序的概念,那么为什么叫程序设计,其实这个设计和现实中的设计一样。例如你自己盖个小棚子,只需要简单的规划即可,也就是编程中的小程序,而如果需要建造一栋大楼,肯定需要进行设计吧,程序也是这样。所以把编程叫做程序设计了。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2245399

利用.NET框架创作安全性网站

mikel阅读(837)

本来标题应当是,利用.NET框架创作安全性网站
这是从MSDN上摘抄整理而来的,结合我自己的经验之谈。
我看了有很多朋友都在尝试写出带有登陆这样功能的网站,其方法几乎都是验证用户的登陆合法,然后发送一个表示验证的Cookie,或者在Session中保存信息以便于追踪接下来的访问授权,其实,这些细节化的操作,.NET都提供了一种非常有效的解决办法,能使你从繁琐的安全验证上解脱出来,而且,尽管你可能很小心地定义那些页面不能被没有权限的人访问,然而还有可能出现一些无法被检查出来的漏洞让他们跳过安全验证
好,废话少说,本文将介绍如下内容:
1、关于登陆验证和授权
2、使用Forms验证模式
3、授权资源的访问
4、基于角色的授权
1、关于登陆验证和授权
很多网站都有登陆对话框,让事先已经注册的用户验证,以便为他们提供个性化的服务等。可以把这个过程看作是两件事情的发生:验证和授权!登陆的作用是验证请求登陆的用户是否合法,而授权则是验证合法的用户在请求资源时,根据他们的权限决定是访问还是拒绝。
以上这种网站本身提供对话框的作法在.NET中被称之为Forms验证模式,接下来将会讲述这种验证模式。在以前ASP陈序员或者其他程序员,要想保存合法用户的验证,在以后的访问授权中使用,不得不使用写Cookie或者将信息保存在Session中的方法,而在需要授权的页面加载前添加一堆繁琐的代码来验证制定的用户是否具有访问权限否则的话就不能显示页面的内容,最恼火的是在授权页面上添加这些代码让人觉得重复和繁琐,而且可能不是最安全的,有一些比较隐蔽的方式可能会轻易绕过这种验证,因此程序员将来要做的很多事情就是再修改代码已堵住在运行过程中才发现的漏洞。在.NET的 System.Web.Security中提供了一些网站安全方面的解决方案,尽管验证用户合法和授权的基本思路没有变化,但是授权的工作几乎已经交给. NET框架了,我们些代码之需要自己验证用户合法,并且告诉框架这个用户合法即可。
2、使用Forms验证模式
要使用启用Forms验证模式,请在网站根目录下的web.config文件中添加如下配置:(注意区分大小写)





这将告诉.NET,你的网站使用Forms验证模式,.NET将不参与验证用户的工作,而是将这个工作交给你完成,你必须自己编写一些代码来验证用户合法,并且报告给.NET用户是合法的。.NET将会发送一个验证Cookie到用户,随后的访问中,.NET以此Cookie为依据,来执行授权的操作。
例如我们在login.aspx界面中放置两个接受输入的文本框txtUserName和txtPassword,在数据库中,保存了用户名UserName和密码UserPassword,使用btnLogin按钮的Click事件来验证用户:
private void btnLogin_Click(object sender, EventArgs e)
{
string SQL = “Select userid FROM Users Where UserName = '” + txtUserName.Text.Replace(“'”,”_”) + “' AND UserPassword = '” + System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(txtPassword.Text, “md5”) + “'”;
//使用上面类似的SQL语句向数据库执行查询,如果用户是合法的,将会返回数据。
if (…) //根据条件判定用户是合法的
{
//下面的语句告诉.NET发送一个验证Cookie给用户:
System.Web.Security.FormsAuthentication.SetAuthCookie(userid, false)
Response.Redirect(“afterlogin.aspx”); //定位到登陆后页面
}
else
{
//用户不合法,提示错误信息
}
}
以上代码中,
txtUserName.Text.Replace(“'”,”_”)将用户输入的文本中单引号替换为下划线,以防止SQL注入攻击。
System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(txtPassword.Text, “md5”)方法将txtPassword.Text转换为MD5散列值,注意,在用户注册的时候,同样使用此方法将其输入的注册密码转换为散列值存储在数据库中,这里将用户输入的散列值进行对比以决定是否合法用户。任何时候不要将敏感的文本信息以明文方式存放在数据库中。通过MD5加密,即便此密文被截获,攻击者仍无法获得真实的密码。
当确认用户验证是合法的,则调用 System.Web.Security.FormsAuthentication.SetAuthCookie(userid, false)方法,发送验证Cookie,此方法传递两个参数,一个是代表用户的标示,一般来说,在接下来确认用户唯一身份的就是从数据库中获得的 userid。第二个参数告诉.NET是否写入持续的Cookie,如果为true,则Cookie将被持续,下次用户再次访问时,Cookie仍存在(相当于记住用户,可以提供这样的复选框让用户来决定是否持续Cookie)。发送了Cookie后,即可调用跳转语句跳转到指定地方。
另外还有一个方法:Web.Security.FormsAuthentication.RedirectFromLoginPage(string UserName, bool);将发送Cookie,并且根据传递的ReturnUrl参数来跳转到指定的页面(相当于将上面的两个步骤合为一步)。因此 login.aspx隐含可以传递ReturnUrl,如果没有这个参数,这个方法将用户跳转到Default.aspx页。
3、授权资源的访问
一旦验证了用户合法,接下来要做的事就是对于用户请求的资源,授权他们是否能够访问。重新回到web.config文件中,在网站的任何目录中都可以使用web.config,他们的设置是传递继承的。
例如在users目录中存放的均是当用户登录后才能访问的页面,则在这个目录中创建一个web.config文件,内容如下:









上述内容中deny users=”?” 将告诉.NET,此目录拒绝匿名用户的访问,也就是没有验证的用户。当用户试图请求此目录中的资源,将会被重新定向到login.aspx页面,要求登陆。没有登陆的情况下是无法访问的。
上述仅对目录进行定义,程序员不用在页面上添加任何代码,即可完整地实现了授权方案。
当然,这种仅针对目录的授权配置可能有时候又会缺乏灵活,因此,.NET也提供location配置节,可以对指定的资源定义授权:









其中path是资源相对路径。
如果这还不够灵活的话,.NET也提供了在代码中使用的方法,ASP.NET页全局隐含了一个只读的User对象,通过获取 User.Identity.IsAuthenticated属性,可探知用户是否验证(即是否登陆),User.Identity.Name属性可以获得用户的Name,即在验证时的SetAuthCookie方法中传递的userid。
4、基于角色的授权
上面我们讲述的用户验证,只可能有两种情况,要么用户通过验证,可以授权访问资源,要么用户没有通过验证,不能访问需要授权的资源。但是即便是验证通过的用户,可能他们所持用的权限还需要再进一步区分。例如普通用户和管理员同样是需要验证通过的,但是普通用户显然不能够访问管理页面,而管理员可以。面对这种情况,.NET可以使用基于角色的授权模型。
其基本原理是,一旦用户验证合法,他们就被分配角色,用户可以使一个或者若干和角色,而资源的授权面向角色,这样,针对不同的角色,就可以授予不同的权限,没有某种角色类型的用户试图访问需要这种角色的资源将会被拒绝。
当网站开始接受用户请求时,就伴随着验证,将激发Application_AuthenticateRequest事件,在Global.asax文件中写代码以响应此事件。角色的分配工作就需要再这里进行。
public void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (this.Request.IsAuthenticated)
{
//这里简化了操作,可以从数据库中获得角色信息用以构造rolesStrArr数组。作为示例,我们为除了a之外的用户分配了管理员角色
string[] rolesStrArr;
if (this.Context.User.Identity.Name == “a”)
{
rolesStrArr = new string[]{“普通用户”};
}
else
{
rolesStrArr = new string[]{“普通用户”,”管理员”};
}
this.Context.User = new System.Security.Principal.GenericPrincipal(this.User.Identity, rolesStrArr);
}
}
以上代码清晰明了,因此不再赘述。虽然在全局性有User对象,但是只有Context上下文中的User对象是可以写入的,我们调用 System.Security.Principal.GenericPrincipal方法,在原有User对象的基础上为其加入角色。角色列表示一个字符串数组。
一旦用户被授予访问角色之后,在web.config中就可以配置针对不同角色的访问。例如在管理员admin目录内










上述配置只允许管理员角色才能被授权。资源默认是任何人都访问的,所以要在下面再添加表示对任何用户拒绝。
注意,无论对角色或者对用户指定资源的访问,如果对于多个角色或者读个资源,他们之间使用半角逗号隔开。同样,也可以使用上面讲到的方法,对指定的资源进行配置而不是对整个目录。
全局的User对象提供了一个方法IsInRole(string RoleName)方法用来在代码中检测用户是否拥有某种角色。如果他拥有这种角色,将返回true。
后记
.NET提供了完整的安全方面的解决方案,相对于ASP,这是激动人心的一个新特性。只是很多人可能并不能够熟练地运用,而且最痛心的是,很多书籍上甚至并没有这方面的任何描述,甚至连概念都没有。这就让人很怀疑编者的水平了。
首先,还是要在不断的实践过程中去了解和体会.NET,其实最好的老师应当是MSDN,到论坛来发帖的用户,我都尽量建议去查阅MSDN的资料,MSDN 除了教给你怎么写代码,其实他教给你的还有非常优秀的思想和整体概念。只要学会使用,没有这些书也可以。从写第一行代码到现在,除了一本启蒙书,其他的资源都是MSDN或者网上找的,还有就是在每次做项目中的心得。尽管现在看来,启蒙书中也没有非常全面地讲述这些东西。
好了,希望大家看到会有所收获。限于我的水平,错误难免,欢迎指正!

FireFox与IE中对onKeyUp事件的处理问题

mikel阅读(877)

Firefox下不支持keyCode返回功能键的值,如下:
在IE下:
支持keyCode,不支持which和charCode,二者值为 undefined
在Firefox下:
支持keyCode,除功能键外,其他键值始终为 0 ,支持which和charCode,二者的值相同
解决方法如下:
解决办法:

function EnterSubmit(){
var _key;
document.onkeyup = function(e){
if (e == null) { // ie
_key = event.keyCode;
} else { // firefox
_key = e.which;
}
if(_key == 13){
s_submit();
}
};
}

三种支持Javascript事件处理方法

mikel阅读(1030)

Events make the client-side JavaScript world go ‘round. After a Web page loads, the only way a script can run is in response to a system or user action. While simple events have been part of the JavaScript vocabulary since the first scriptable browsers, more recent browsers implement robust event models that allow scripts to process events more intelligently. The problem, however, is that in order to support a wide range of browsers you must contend with multiple advanced event models. Three, to be exact.
The three event models align themselves with the Document Object Model (DOM) triumvirate: Netscape Navigator 4 (NN4), Internet Explorer 4 and later for Macintosh and Windows (IE4+), and the W3C DOM, as implemented in Safari. Despite sometimes substantial differences among the models, they can all work side-by-side in the same document with the help of a few JavaScript shortcuts. This article focuses on two key aspects of the conflicting event models:
* Methods for binding an event to an HTML element object.
* Processing the event after it fires.
Approaches to Event Binding
Event binding is the process of instructing an HTML element to respond to a system or user action. There are no fewer than five binding techniques implemented in various browser versions. A quick overview of these techniques follows.
Event Binding I: Element Attributes
The simplest and most backward-compatible event binding avenue is an element tag’s attribute. The attribute name consists of the event type, preceded by the preposition “on.” Although HTML attributes are not case-sensitive, a convention has evolved to capitalize the first letters of each “word” of the event type, such as onClick and onMouSEOver. These attributes are also known as event handlers, because they instruct an element how to “handle” a particular type of event.
Proper values for event handler attributes come in the form of JavaScript statements within quoted strings. Most commonly, a statement calls a script function that is defined inside a






Event Binding II: Object Properties
For NN3+ and IE4+ browsers, scripters can bind events to objects by way of script statements instead of as tag attributes. Each element object that responds to events has properties for each event it recognizes. The property names are lowercase versions of the tag attributes, such as onmouSEOver. NN4 also accepts the interCap versions of the property names, but for cross-browser compatibility, the all-lowercase versions are trouble-free.
Binding occurs when you assign a function reference to the event property. A function reference is the name of the function, but without the parentheses of the definition. Therefore, to bind the click event of a button named myButton to invoke a function defined as myFunc(), the assignment statement is as follows:
document.forms[0].myButton.onclick = myFunc;
One point you should notice is that there is no way to pass a parameter to the function when the event fires. I’ll come back to this point later in the discussion of event processing.
Event Binding III: IE4+
Naturally, statements inside the tag can call any other functions defined elsewhere on the page (or imported from a .js file). But this binding style means that you must create a



键盘键值表——用javascript获得键盘键值

mikel阅读(834)

键盘键值表原地址:http://hi.baidu.com/giliwala/blog/item/97659c3d78974c00baa1678a.html
我找的作者地址:http://www.x5dj.com/blog/00379474/00329496.shtml
获取键盘键值的地址:http://hehe.veryplace.com/article/list.asp?id=136

值 描述
0x1 鼠标左键
0x2 鼠标右键
0x3 CANCEL 键
0x4 鼠标中键
0x8 BACKSPACE 键
0x9 TAB 键
0xC CLEAR 键
0xD ENTER 键
0x10 SHIFT 键
0x11 CTRL 键
0x12 MENU 键
0x13 PAUSE 键
0x14 CAPS LOCK 键
0x1B ESC 键
0x20 SPACEBAR 键
0x21 PAGE UP 键
0x22 PAGE DOWN 键
0x23 END 键
0x24 HOME 键
0x25 LEFT ARROW 键
0x26 UP ARROW 键
0x27 RIGHT ARROW 键
0x28 DOWN ARROW 键
0x29 Select 键
0x2A PRINT SCREEN 键
0x2B EXECUTE 键
0x2C SNAPSHOT 键
0x2D Insert 键
0x2E Delete 键
0x2F HELP 键
0x90 NUM LOCK 键
A 至 Z 键与 A – Z 字母的 ASCII 码相同:
值 描述
65 A 键
66 B 键
67 C 键
68 D 键
69 E 键
70 F 键
71 G 键
72 H 键
73 I 键
74 J 键
75 K 键
76 L 键
77 M 键
78 N 键
79 O 键
80 P 键
81 Q 键
82 R 键
83 S 键
84 T 键
85 U 键
86 V 键
87 W 键
88 X 键
89 Y 键
90 Z 键
0 至 9 键与数字 0 – 9 的 ASCII 码相同:
值 描述
48 0 键
49 1 键
50 2 键
51 3 键
52 4 键
53 5 键
54 6 键
55 7 键
56 8 键
57 9 键
下列常数代表数字键盘上的键:
值 描述
0x60 0 键
0x61 1 键
0x62 2 键
0x63 3 键
0x64 4 键
0x65 5 键
0x66 6 键
0x67 7 键
0x68 8 键
0x69 9 键
0x6A MULTIPLICATION SIGN (*) 键
0x6B PLUS SIGN (+) 键
0x6C ENTER 键
0x6D MINUS SIGN (–) 键
0x6E DECIMAL POINT (.) 键
0x6F DIVISION SIGN (/) 键
下列常数代表功能键:
值 描述
0x70 F1 键
0x71 F2 键
0x72 F3 键
0x73 F4 键
0x74 F5 键
0x75 F6 键
0x76 F7 键
0x77 F8 键
0x78 F9 键
0x79 F10 键
0x7A F11 键
0x7B F12 键
0x7C F13 键
0x7D F14 键
0x7E F15 键
0x7F F16 键

如何用js获得组合键的代码
原链接:http://www.runup.com.cn/soft/p281/A28134591.shtml

event.altkey
event.ctrlkey
event.shiftkey
<script language="javascript">
function test()
{
if (event.shiftkey == true && event.keycode == 81)
{
alert("shift+q");
}
}
</script>
<input onkeydown="test();">
发表者:huis
if(event.srcelement.type !="submit" && event.srcelement.type!="textarea" && vent.keycode==13)
{
event.shiftkey=true
event.keycode = 9;
}

限制只能输入非中文的内容正则表达式

mikel阅读(897)

<script language="javascript">
/**
函数:repChinese
作者;mikel
日期;2008-4-2
功能说明:
将中文字符替换成空字符
只允许输入中文
参数:
id :需要进行中文字符校验的页面输入框的ID
**/
function  check(str)
{
//正则表达式,中文字符
var   pattern=/[\u4e00-\u9fa5]/g;
//检测是否中文字符
if(pattern.test(str))
{
alert("对不起,只能输入英文!");
return true;
}else
{
return false;
}
}
/**
函数:repChinese
作者;mikel
日期;2008-4-2
功能说明:
将中文字符替换成空字符
只允许输入中文
参数:
id :需要进行中文字符校验的页面输入框的ID
**/
function repChinese(id)
{
var obj=document.getElementById(id);
var str=obj.value;
if (check(str))
obj.value=obj.value.replace(/[\u4e00-\u9fa5]/g,&#39;&#39;);
}
</script>
<body>
<form id="test">
<textarea id="tes" onkeyup="repChinese(&#39;tes&#39;);" onafterpaste="repChinese(&#39;tes&#39;);"></textarea>
<!--<textarea onkeyup="check(this.value);" onafterpaste="check(this.value)"></textarea>-->
</form>
</body>
</html>

Guice示例

mikel阅读(964)

依赖注入,DI(Dependency Injection),它的作用自然不必多说,提及DI容器,例如spring,picoContainer,EJB容器等等,近日,google诞生了更轻巧的DI容器……Guice!
废话不多讲了,先看看Guice是如何实现注入的吧。
定义一个简单的service接口和它的实现吧:

public interface MyService ...{
void myMethod();
}
public class MyServiceImpl implements MyService ...{
public void myMethod() ...{
System.out.println("Hello,World!");
}
}

以上是最普通的接口和其实现,没什么可说的。
定义一个测试类,这个类里边包括service对象的一个引用,这个对象是需要Guice进行注入的

import com.google.inject.Inject;
public class Client ...{
MyService service;
@Inject //告诉容器,这里的service对象的引用,需要进行注入
void setService(MyService service) ...{ //这里的方法名字可以任意定义
this.service = service;
}
public void myMethod() ...{
service.myMethod();
}
}

这里除了加了一个@Inject,和Spring的配置没有任何的区别,@Inject,是表示对容器说,这里的service需要注射,等到运行的时候,容器会拿来一个实例给service,完成注射的过程。
定义Guice的Module文件 告诉容器如何进行注入

import com.google.inject.Binder;
import com.google.inject.Module;
import com.google.inject.Scopes;
public class MyModule implements Module ...{
public void configure(Binder binder) ...{    binder.bind(MyService.class).to(MyServiceImpl.class).in(Scopes.SINGLETON);
// 这句代码的意思是说:运行时动态的将MyServiceImpl对象赋给MyService定义的对象,而且这个对象是单例的。
}
}

创建测试类

import com.google.inject.Guice;
import com.google.inject.Injector;
public class Test ...{
public static void main(String[] args) ...{
MyModule module = new MyModule();// 定义注射规则
Injector injector = Guice.cr&#101;ateInjector(module);// 根据注射规则,生成注射者
Client client = new Client();
injector.injectMembers(client);// 注射者将需要注射的bean,按照规则,把client这个客户端进行注射
client.myMethod();
}
}

运行测试类,控制台输出:Hello,World!
完成注入过程
下面看看Guice还有哪些其它的使用特性。
1,如果在实现你确定MyService定义的对象,就要被注射为MyServiceImpl而不是其它的实现类的话,可以在MyService接口加上@ImplementedBy(MyServiceImpl.class)

import com.google.inject.ImplementedBy;
@ImplementedBy(MyServiceImpl.class)
//我总觉得这样有点背离了依赖注入的初衷了
public interface MyService ...{
void myMethod();
}

这样的话,在MyModule里的configure方法中就可以不加任何东西,容器就会自动注射给MyServiceImpl对象。
2,可以对Field进行注解式注入
在Client.java中也可以把这个@Inject标注在MyService service;的前边,如:@Inject MyService service;
3,可使用自定义Annotation标注。

package mypackage;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.google.inject.BindingAnnotation;
@Retention(RetentionPolicy.RUNTIME)
@Target( ...{ ElementType.FIELD, ElementType.PARAMETER })
@BindingAnnotation
public @interface MyInterface ...{
}

那么Client.java需要改为

package mypackage;
import com.google.inject.Inject;
public class Client ...{
@Inject @MyInterface MyService service;
void setService(MyService service) ...{ // 这里的方法名字可以任意定义
this.service = service;
}
public void myMethod() ...{
service.myMethod();
}
}

MyModule.java中的configure方法内容需改为:

binder.bind(MyService.class).annotatedWith(MyInterface.class).to(
MyServiceImpl.class).in(Scopes.SINGLETON);

意思是说对于标注为MyInterface的MyService定义的对象进行注入
进行Annotation标注的成员(Field,method,argument等)进行自定义Annotation标注,该成员既拥有该属性,可以在运行,根据这些成员的不同属性,做一些不同的事情 例如:spring的AspectJ,xdoclet等都是如此。
下边是我做了一下对比
Guice与Spring的对比 Spring Guice
使用XML 使用将类与类之间的关系隔离到xml中,由容器负责注入被调用的对象,因此叫做依赖注入 不使用xml,将类与类之间的关系隔离到Module中,声名何处需要注入,由容器根据Module里的描述,注入被调用的对象。
使用Annotation 使用
支持自定义Annotation标注,对于相同的接口定义的对象引用,为它们标注上不同的自定义Annotation注释,就可以达到同一个类里边的同一个接口的引用,注射给不同的实现,在Module里用标注做区分,灵活性大大增加。
使用Annotation也未必是好事,范型等新特性也未必是好事,目前大多的服务器均不支持jdk1.5,wls要9以前才支持,而目前的客户由于价格原因也很少选用wls9的,至少我们做过的项目中都没有。功能再强,客户不需要,何用?
运行效率 装载spring配置文件时,需解析xml,效率低,getBean效率也不高,不过使用环境不会涉及到getBean,只有生产环境的时候会用到getBean,在装载spring应用程序的时候,已经完成全部的注射,所以这个低效率的问题不是问题。 使用Annotation,cglib, 效率高与spring最明显的一个区别,spring是在装载spring配置文件的时候把该注入的地方都注入完,而Guice呢,则是在使用的时候去注射,运行效率和灵活性高。
类耦合度 耦合度低,强调类非侵入,以外部化的方式处理依赖关系,类里边是很干净的,在配置文件里做文章,对类的依赖性极低。 高,代码级的标注,DI标记@inject侵入代码中,耦合到了类层面上来,何止侵入,简直侵略,代码耦合了过多guice的东西,大大背离了依赖注入的初衷,对于代码的可维护性,可读性均不利
类编写时 需要编写xml,配置Bean,配置注入 只需声明为@inject,等着被注入,
最后在统一的Module里声明注入方式
仅支持IOC 否,spring目前已经涉猎很多部分 是,目前仅仅是个DI容器
是否易于代码重构 统一的xml配置入口,更改容易 配置工作是在Module里进行,和spring异曲同功
支持多种注入方式 构造器,setter方法 Field,构造器,setter方法
灵活性
1,如果同一个接口定义的引用需要注入不同的实现,就要编写不同的Module,烦琐
2,动态注入
如果你想注射的一个实现,你还未知呢,怎么办呢,spring是没办法,事先在配置文件里写死的,而Guice就可以做到,就是说我想注射的这个对象我还不知道注射给谁呢,是在运行时才能得到的的这个接口的实现,所以这就大大提高了依赖注射的灵活性,动态注射。
与现有框架集成度 1, 高,众多现有优秀的框架(如struts1.x等)均提供了spring的集成入口,而且spring已经不仅仅是依赖注入,包括众多方面。
2, Spring也提供了对Hibernate等的集成,可大大简化开发难度。
3, 提供对于orm,rmi,webservice等等接口众多,体系庞大。
1,可以与现有框架集成,不过仅仅依靠一个效率稍高的DI,就想取代spring的地位,有点难度。
配置复杂度 在xml中定位类与类之间的关系,难度低 代码级定位类与类之间的关系,难度稍高
再借斧子的例子说一说spring与guice的区别
看下边对于不同社会形态下一个人(java对象,调用者)需要一把斧子(java对象,被调用者)的例子:
(1),原始社会时,劳动社会基本没有分工,需要斧子的人(调用者)只好自己去磨一把斧子,每个人拥有自己的斧子,如果把大家的石斧改为铁斧,需要每个人都要学会磨铁斧的本领,工作效率极低。
对应Java里的情形是:java程序里的调用者new一个被调用者的实例。类耦合度极高,修改维护烦琐,效率极低。
(2),工业社会时,工厂出现,斧子不再由普通人完成,而由工厂生产,当人们需要斧子的时候,可以到工厂购买斧子,无需关心斧子是怎么制造出来的,如果废弃铁斧为钢斧,只需改变工厂的制造工艺即可,制作工艺是工厂决定的,工厂生产什么斧子,工人们就得用什么斧子。
对应的Java里的情形是:Java程序的调用者可以以来简单工厂创建被调用者,变化点被隔离到了简单工厂里,虽然耦合度降低,但是调用者会和工厂耦合,而且需要定位自己的工厂。
(3)近代工业社会,工厂蓬勃发展,人们需要什么斧子,只需要提供一个斧子图形,商家会按照你提供的图形将你的斧子订做好,送上门。
对应Java里的情形:spring的依赖注入
(4)进入按需要分配社会,信息进入现代化,人们不再去工厂购买斧子,不再拘泥于需要什么斧子事先画好什么样的图形,只需要打个电话,描述一下需要什么类型的斧子,或许想打造一个物美价廉的斧子,商家会根据市场零件的价格,计算出最优制作工艺,打造最适合的斧子送过来,更加信息化,更加人性化。
对应Java里的情形:基于描述的注入,动态的,灵活简单的注入,如:Guice。
对于该不该使用Guice,我想也是仁者见仁,智者见智,就象好多论坛里动不动有人会在那里讨论到底学Java还是学.net或者是使用eclipse还是Jbuilder的这类无聊话题,适合和满足项目需求的,又能省工省力简单的完成工作的,就是最好的。