zoukankan      html  css  js  c++  java
  • 优秀软件

    如何编写优秀软件

     

      作为每一名程序员,都希望自己能编写出非常优秀的软件,而要写出好的软件,并非易事,需要有良好的编程习惯,一流的技术水平和丰富的实践经验。作为北大青鸟的一名老师,我一直从事着ACCP课程的教学工作。通过多年的开发经验和教学经验以及在学生中发现的问题,我现在来谈谈软件开发,希望能帮助各位学员编写出优秀的软件,成为出色的软件工程师。

      1、   需要的便是最好的。对于公鸡来说,麦粒胜过钻石。

      需要的东西才是最好的。对于公鸡来说,钻石对它没有任何价值,它不能吃,也不能用。而对于人来说,钻石可能非常有用,因为我们需要。

      那么什么样的软件才是最好的软件呢?需要的便是最好的,满足用户需求的软件才是最好的软件。我们开发软件的时候一定要以用户为中心,为用户设计软件。而不要站在自己的角度来设计软件,更不能更改用户的需求。

      有些学生在考试的时候,更改试题的题目,不按题目要求来做,这是非常错误的。我跟他们说,试题就是用户的需求,如果试题要求的你没有做,就不能得分,做多了不能加分。同样,用户要求你开发一个软件,你没有按照他的要求来开发,他不会给你钱,你开发了多余的功能,他也不会多给你钱。我们开发软件,一定要按照用户的要求来开发,需要的便是最好的。

      开发软件一定要以用户为中心,不要以自己为中心。你是为用户开发软件,软件是卖给用户的,不是卖给你自己的。所以你觉得好不一定好,只有用户觉得好才是好软件。一次答辩会上,一个学生的界面用鲜艳的颜色做背景,我觉得不太合适,我就问:“你项目中的背景颜色合理吗?”,他说:“我觉得很好看”。很明显,这样的软件一定是失败的,他不是站在使用者角度看问题。同样在答辩会上,有些学生讲解项目的时候,如果是可视化的项目,一个菜单一个菜单的讲,如果是Web程序,一个网页一个网页的讲。如果你是以设计者的角度来讲解的话,只有你自己能听懂,也只有你自己可能愿意听。我们应该站在使用者角度来讲解项目。比如我要讲解一个网上书店,先打开主页,然后分类浏览,浏览后可能要搜索书籍,加入购物车,登录,注册,下定单等等。用户怎么用,我们怎么讲,这样用户更容易理解。

      2、   提高软件的可读性。

      很多程序员都知道,如果软件没有可读性。那么就无法协同开发,因为别人无法阅读你的代码。同样软件没有可读性,可能过一段时间自己都看不懂自己写的代码了,这样的代码可能就成了一次性代码,再也不能修改和使用了。

      怎样提高软件的可读性。有经验的编程人员会告诉你:使用规范的命名,合理的分层结构,完整的文档及注释。我不会这样跟你说,因为检验软件可读性的标准不仅仅是这些。那么我告诉你,要想让你的软件具有很好的可读性,你应该这样做:把你的代码给你班上的所有同学和老师阅读。如果他们能够看懂,那么你的代码具有很好的可读性。如果连老师都看不懂,那么你的代码可读性就非常差。同样,作为程序员要有很好的沟通能力和语言表达能力。那么怎样训练自己的表达能力以及知道自己的表达能力是否过关呢?当同学遇到问题,给同学讲解,如果他能听懂,说明你的表达能力不错,如果所有人都听不懂,你的沟通和表达一定存在问题。我们把自己的代码给其他人看,一方面可能检验自己的代码是否具有可读性,另一方面也可以帮助其他同学。同样,同学有问题我们帮助讲解,一方面可以提高和检验自己的表达能力,也能帮助其他同学学习知识。记住:帮助别人就是帮助自己。一个晚上一个瞎子提着灯笼,路上一个行人看到这个瞎子对他说,你一个瞎子,提着灯笼干什么,又看不见。瞎子说:我提着灯笼,是为了照亮别人,让别人看清楚,以至于不撞到我。帮助别人就是帮助自己呀!世界级软件大师Eric Gamma(设计模式之父、JUnit设计者、Eclipse架构师)说的好:“我们每个人都需要别人的关怀和帮助,每个人也需要关怀和帮助别人。

      3、   具有良好的复用性和灵活性。

      使用面向对象的开发技术,能很好的支持复用性和灵活性。封装和继承是用来复用的,多态是用来实现灵活性的。

      复用非常重要,可以开发大型应用程序。我们到处可以看到复用技术,封装是让变动的事物和不变的事物彼此隔离,不变的事物就可以复用了。而继承很明显在复用基类代码。框架技术也是在复用,用户控件是在复用,母版页是在复用,三层结构也是在复用代码。复用不是复制。复用是重复调用,复制是到处拷贝代码。复用是很好的,复制是很差的。

      用户的需求经常变化,那么怎么提高软件的应对变化的特性(也就是灵活性)。多态性是用来实现灵活性的。我举一个接口的例子,在Java和C#中都有接口,为什么要使用接口,为什么要用接口作为方法的参数。在计算机中我们可以看到USB接口,那么为什么用USB接口呢?因为使用USB接口后,就可以连接所有使用USB接口的设备了,今天你可以接打印机,明天可以接鼠标,后天可以接移动硬盘,再后天你可以接数码相机,只要它们是USB接口的。所以接口可以根据你的变化来适应你所需要的设备,程序中的接口一模一样。如何能根据用户的变化做出快速的反应呢?这就需要我们的软件写的灵活。现在我们听说的敏捷软件开发也是如此。何为敏捷,在环境变化的情况下能快速的做出反应叫敏捷。

      所以我们应该深入的理解面向对象的思想,提高程序的复用性和灵活性。

      4、   高强度的测试,保证软件的健壮性。

      很多人不重视软件测试,认为测试是在浪费时间。那么我告诉你,在软件开发中,几乎所有人都会参与测试,但不是所有人都会写代码,系统分析师对软件功能最了解,他会做系统测试,软件设计师对模块与模块的关系最为清楚,他会做集成测试,程序员对自己写的代码最清楚,他会做单元测试(或叫模块测试)。测试人员还会做专门的测试。如果没有进行很好的测试,软件在使用过程中出现了问题,以后别人可能再也不使用你的软件了,测试是保证软件质量最关键的一个因素。对于测试我们要注意以下两点:1)尽可能早的做测试。测试越早,发现问题也越早,那么问题也更容易解决。2)尽可能多的做测试。测试的用例越多,发现的问题也越多,使用的时候出现的问题也就越少,软件的质量也就越高。

      如果软件没有进行有效的测试,你既得不到功劳,也没人欣赏你的苦劳,你获得最多的将只是疲劳。

      为什么软件要有健壮性?对于一个人你肯定不希望自己长得非常的肥胖,因为这样做什么都不方便,效率会非常低。长得太胖,是因为有多余的肉,而对于程序就是多余的废代码,很明显废代码多了,会影响程序的执行效率的。同样一个人长得太瘦了,什么事也干不了,还可能经常得病,哪个公司也不愿意要这种人。而对于程序,代码太少了,实现不了功能,而且可能因为没有进行异常处理造成运行不正常,这样的软件谁也不愿意使用。我们需要的人是长的非常健壮的人,做事效率高,不生病,看起来身体均称。而对于代码,执行效率高,不出错,代码有很好的可读性。

      5、   学习解决问题的方法而不仅仅是知识本身。

      很多学生学习编程是靠记忆,这是非常错误的,一个人在一年中80%的知识是会忘记的。我可以跟大家说,我的记忆力是非常差的,但是我记住的东西是不会轻易忘记的。因为我是靠理解记忆。而且对于每一项技术,我会去深入的理解,所以我记忆的非常深刻。

      好,我们举个例子,你看我怎样理解。在学生学习Java的时候,我会问学生==号是比较地址相等还是值相等。大部分学生回答地址相等,有的学生回答值相等。我说:“全错”。很明显,他们没有理解。值类型变量存放的是数值,引用类型变量存放的是对象的地址。那么两个值类型变量比较肯定是比较值相等了,你说3==5是比较地址相等吗?引用类型变量因为存放的是对象的地址,那么相等比较当然是地址相等了。

      学生学习自加运算符++时,有一次晚自习,班长给学生辅导,问所有学生,5++等于几?所有学生都说等于6。幸好被我听到。我相信他们都知道++是将自己加一,也都能分清楚变量和常量,可是合在一起运用都不知道了,但是你跟他们一讲,他们都会理解,而且会理解的非常深刻。我对学生说:“5++是错误的。不能这样用。自加是改变自身的值。而5是一个常量,常量的值是不能改变的。这不是自相矛盾吗?所以自加和自减运算符只能用在变量上”。

      6、   遇到问题不可怕,关键在于你是否能解决问题。

      很多学生去参加面试,回来后非常不解的跟我说,面试单位给我出了个程序或者小项目,要我做完了过两天再拿给他看。这不相当是开卷考试吗?我跟他说,如果我是一个面试官,我也会这么做。因为我看重的,不是你记住了多少知识,而是你能解决多少问题和知识。因为每个人都会遇到问题,老师也是如此,遇到问题不可怕,我们可以看书,可以上网查阅资料,可以问其他人,只要问题解决了,就非常好。

     
     
    分类: 软件开发

    公共场所Wifi上网有多危险

    大家都知道公共场所的Wifi安全性很差,但并不清楚究竟有多差。大多以为只要不上QQ、不登陆网站账号就没事了,看看新闻小说什么的应该毫无关系。

      的确如此,看看新闻网页没有涉及任何敏感的账号信息。即便是数据明文传输,Hacker也只能嗅探到你看了哪些新闻,这些毫无价值的信息。

      不过如此守株待兔的嗅探,似乎也太被动了。既然我们能主动控制流量,何必用这种弱爆了的方法呢?

      --------------------------------------------------

      在上一篇文章《把笔记本改造成无线路由器 ——  手机抓包牛刀小试》里提到如何实现Wifi的流量拦截,并做出更大范围的攻击。

      今天,我们使用一种古老的技术,打造一个巧妙的时光机原型。让我们的脚本能穿越到未来运行,不再受时间与空间的限制,实现超长诅咒!

      

      

      (全图链接://images0.cnblogs.com/blog/273626/201306/14174024-1adcf1c6f0ab4dad99e53167da41dfd4.png

      

      原理其实非常简单,相信大家看完图就明白了。

      1. 当有人连上我们创建的AP时,他的命运已掌控在我们手中了!

      2~5.  他访问任何网站,我们的Web代理就能在其中插入一段脚本代码了。当然这不是一般的广告的代码,而是预加载各大网站的通用脚本库。

      6~7.  一切都在我们掌控之中,我们并非返回真正的脚本库文件。事实上一次预加载那么多文件,很是浪费带宽~ 我们只返回一个很小的“桩文件”,让他在实际运行时再加载真正的文件。此外,这个“桩文件”里我们还可以额外加些其他脚本:) 由于这些脚本库通常有着很长的缓存时间,因此只要在用户在清空缓存之前,始终从本地缓存里读取这个文件!

      8~12. 即使用户离开了公共场所,但常用的脚本文件都已被感染并缓存。只要未来某一天登陆我们预先感染的网站,脚本将穿越时空被唤醒!

      由此看来,只要实现了第1步,之后的几乎都是顺理成章了!

      

      不过并非所用的人都是小白,还是有不少警惕性高的用户,不会轻易连接没有密码的公开wifi。事实上很多餐厅咖啡店的wifi都是设置了密码的 —— 大家都知道的密码。

      对于这种情况,我们就需要一个功率更大的AP了,并且将SSID与密码设置的完全一致 —— 根据wifi的连接策略,同样的热点名将会优先选择信号更好的。如果密码也一样,我们的AP将成为磁金石一样,将新来的用户统统吸过来,于是可以尽情的掌控了。。。

      

      不过最终的难点却不在此,要找出每个网站缓存最久的脚本资源才是重中之重。

      事实上,光看缓存时间是远远不够的 —— 有不少文件设置了很久的缓存,但是他们却经常的更新。最常见的就是带时间戳或哈希值的脚本URL,他们几乎三两天换一个,却有很长的缓存时间,这显然是不可取的。因此,我们需要根据资源的缓存时间上次修改时间,来衡量其稳定程度

      为了能方便从各大网站寻找稳定度较高的资源,我们使用PhantomJS来实现自动化分析。PhantomJS是没有界面的命令行Webkit浏览器,使用它来模拟网站的访问,能为我们节省大量的系统资源。

      我们监听page.onResourceReceived事件,即可获取所有资源请求的回应数据。之前已提到,缓存时间是必要条件,修改时间是充分条件。修改时间早说明这个资源不经常改变,可以放心用!

      首先我们过滤掉缓存很短的资源,很快就过期的资源是没有利用价值的。然后按上修改时间的先后排序,最终为每个站点选择稳定度最优的几个资源。

      代码实现很简单(sniffer.js):

     View Code

      我们测试几个常用的大网站(url.txt):

     View Code

      根据返回的数据来看(-几天没修改 / +缓存几天),资源的修改时间远比缓存时间短,不过仍有少数可以利用的。

    复制代码
    E:\NodeJS\AirDebug\tool>phantomjs sniffer.js
    == www.hao123.com ====================
    -5 / +360               http://s0.hao123img.com/v3/Mr/T0/gh/sn/61/6/hao123.js
    -92 / +360              http://s0.hao123img.com/res/js/track.js?380890
    
    == www.taobao.com ====================
    -6 / +3650              http://a.tbcdn.cn/s/kissy/gallery/??search-suggest/1.0/index-min.js,search-suggest/1.0/plugin/history-min.js,search-suggest/1.
    0/plugin/local-query-min.js,search-suggest/1.0/plugin/storage-min.js,search-suggest/1.0/plugin/tab-min.js,search-suggest/1.0/plugin/telephone-min.js?t
    =20130606190449
    -6 / +3650              http://a.tbcdn.cn/s/kissy/1.3.0/??node-min.js,dom/base-min.js,event/dom/base-min.js,event/base-min.js,event/dom/focusin-min.js
    ,anim-min.js,event/custom-min.js,switchable-min.js,cookie-min.js,ajax-min.js,json-min.js,rich-base-min.js,base-min.js,combobox-min.js,component/base-m
    in.js,menu-min.js,component/extension-min.js,xtemplate/facade-min.js,xtemplate/runtime-min.js,xtemplate/compiler-min.js?t=20130606190449
    
    == www.kaixin001.com ====================
    -14 / +365              http://s.kaixin001.com.cn/js/apps/reg/ARegister-00100c612.js
    -80 / +365              http://s.kaixin001.com.cn/js/core/media/MediaBox-0002a9159.js
    
    == www.baidu.com ====================
    -5 / +3650              http://s1.bdstatic.com/r/www/cache/static/user/js/u_75caac89.js
    -5 / +3650              http://s1.bdstatic.com/r/www/cache/static/global/js/home_f949edf5.js
    
    == www.baidu.com/s?wd=ss ====================
    -5 / +3650              http://s1.bdstatic.com/r/www/cache/static/global/js/common_7fd3f7db.js
    
    == www.renren.com ====================
    -7 / +365               http://s.xnimg.cn/a56656/n/core/base-all2.js
    -88 / +365              http://s.xnimg.cn/a53726/n/apps/login/login-v6.js
    
    == tieba.baidu.com ====================
    -4 / +30                http://tb1.bdstatic.com/tb/static-spage/component/feed_data/feed_data_c51ac7ba.js
    -8 / +30                http://tb1.bdstatic.com/tb/static-common/js/tb_ui_ac13f64f.js
    
    == map.baidu.com ====================
    -7 / +365               http://webmap1.map.bdimg.com/init_0gj0re.js
    -8 / +365               http://webmap2.map.bdimg.com/main_hntng4.js
    
    == weibo.com ====================
    -9 / +15                http://js.t.sinajs.cn/t5/register/js/page/login/index.js?version=201306141810
    -30 / +15               http://js1.t.sinajs.cn/t4/apps/publicity/static/wbad.js?version=201306141810
    
    == www.sina.com.cn ====================
    -141 / +223             http://i2.sinaimg.cn/jslib/modules2/sina/util/1.0.5/util.js
    -169 / +203             http://i2.sinaimg.cn/jslib/modules2/seajs/1.3.0/sea.js
    
    == www.mop.com ====================
    -365 / +300             http://mopimg.cn/tj/dcq.js
    -427 / +300             http://mopimg.cn/dc/tj.js
    
    == www.tianya.cn ====================
    -38 / +29               http://static.tianyaui.com/global/ty/TY.js
    
    == bbs.tianya.cn ====================
    -7 / +29                http://static.tianyaui.com/global/lite/js/lite-all.js?v=201306070836
    -15 / +25               http://static.tianyaui.com/global/lite/js/bbs/bbs.js?v=201306070836
    
    == user.qzone.qq.com ====================
    -31 / +7                http://imgcache.qq.com/ptlogin/ver/10031/js/h_login_11.js?max_age=604800&ptui_identifier=000D29EE4BA374D65D39E3C1BB890C8E50025
    6813D2C4E549471141C
    
    == www.163.com ====================
    -32 / +90               http://img2.126.net/ntesrich/auto/indexU/dlbox-index-v1.0.1-130506.js
    -51 / +90               http://img2.126.net/ntesrich/auto/indexU/fcbox-index-v1.0.0-130422.js
    
    == www.sohu.com ====================
    -42 / +90               http://js.sohu.com/pv/pvclick1211071116.js
    -42 / +90               http://js.sohu.com/pv/spv1209061800.js
    
    DONE!
    复制代码

      

      很好,有了这些数据,就可实现我们计划了!

      下一篇将介绍使用NodeJS来打造这一计划。目前代码已基本调试完毕,等待实战测试!

     
     
    分类: 以太幻想
  • 相关阅读:
    Nhibernate代码生成器v2.1中文版
    在asp.net中生成16位随机密码
    IIS 启动不了(发生意外错误0x8ffe2740)
    NET代码生成器
    Linux系统
    VS2005快捷键大全
    ASP+ACCESS数据库中文乱码问题解决
    如何配置ASP.NETOracle 9i 远程登陆数据库
    ASP.NET获取汉字拼音的首字母
    checkbox 实时操作,勾选后变色[带演示]
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3136773.html
Copyright © 2011-2022 走看看