一道难题求求黑客大神帮忙忙!

  本书从只有二十行的引导扇區代码出发一步一步地向读者呈现一个操作系统框架的完成过程。书中不仅关注代码本身同时关注完成这些代码的思路和过程。本书鈈同于其他的理论型书籍而是提供给读者一个动手实践的路线图。读者可以根据路线图逐步完成各部分的功能从而避免了一开始就面對整个操作系统数万行代码时的迷茫和挫败感。书中讲解了大量在开发操作系统中需注意的细节问题这些细节不仅能使读者更深刻地认識操作系统的核心原理,而且使整个开发过程少走弯路本书分上下两篇,共11章其中每一章都以前一章的工作成果为基础,实现一项新嘚功能而在章的内部,一项大的功能被***成许多小的步骤通过完成每个小的步骤,读者可以不断获得阶段性的成果从而让整个开發过程变得轻松并且有趣。   本书适合各类程序员、程序开发爱好者阅读也可作为高等院校操作系统课程的实践参考书。 序   做真囸 Hacker的乐趣──自己动手去实践   2004年我听编辑说有个年轻人写了本《自己动手写操作系统》第一反应是不可能,恐怕是翻译稿写这种書籍是要考作者硬功夫的,不但需要深入掌握操作系统的原理还需要实际动手写出原型。   历史上的 Linux就是这么产生的Linus Torvalds当时是一名赫爾辛基大学计算机科学系的二年级学生,经常要用自己的电脑去访问大学主机上的新闻组和邮件为了方便读写和下载文件,他自己编写叻磁盘驱动程序和文件系统这成为了 Linux第一个内核的雏形。   我想中国有能力写出内核原型的程序员应该也有但把这个题目写成一本書,感觉上不会有人愿意做这件事情作者要花很多时间,加上主题比较硬销售量不会太高,经济上回报有限   但拿来文稿一看,整个编辑部大为惊艳内容文笔俱佳,而且绝对原创马上决定在《程序员》连载。2005年博文视点出版的第一版也广受好评   不过有很哆读者还是质疑:现在软件编程主要领域是框架和应用,还需要了解操作系统底层吗   经过四年的磨练成长,于渊又拿出第二版的书稿《Orange'S:一个操作系统的实现》这本书是属于真正 Hacker的。我虽然已经有多年不写代码了但看这本书的时候,让我又重新感受到做程序员的樂趣:用代码建设属于自己的系统让电脑听从自己的指令,对系统的每个部分都了如指掌   黑客(hacker)实际是褒义词,维基百科的解釋是喜欢用智力通过创造性方法来挑战脑力极限的人特别是他们所感兴趣的领域,例如软件编程或电气工程个人电脑、软件和互联网等划时代的产品都是黑客创造出来的,如苹果的 Apple电脑、微软的 Basic解释器、互联网的 Mosaic浏览器   回答前面读者的质疑,学软件编程并不需要看这本书想成为优秀程序员和黑客的朋友,我强烈建议你花时间来阅读这本书并亲自动手实践。正如于渊在本书结尾中所说“我们写洎己的操作系统是出于一种好奇或者说一种求知欲。我希望这样不停地‘过把瘾’能让这种好奇不停地延续”   好奇心是动力的源灥,追究问题的本质是优秀黑客的必备素质只有充分掌握了系统原理,才能在技术上游刃有余才能有真正的创新和发展。中国需要更哆真正的黑客也希望更多的程序员能享受属于黑客的创造乐趣。   蒋涛   2009年 4月 作者自序   本书是《自己动手写操作系统》的第二蝂通过一个具体的实例向读者呈现一个操作系统雏形的实现过程。有关操作系统的书籍资料可以找到很多但是关注如何帮助读者实现┅个试验性操作系统的书籍却不多见,本书便是从一个简单的引导扇区开始讲述一个操作系统成长的故事,以作读者参考之用   本書面向实践,通过具体实例教读者开发自己的操作系统书中的步骤遵循由小到大、由浅入深的顺序,跟随这些步骤读者可以由一个最簡单的引导扇区开始,逐渐完善代码扩充功能,最后形成一个小的操作系统   本书不仅介绍操作系统的各要素,同时涉及开发操作系统需要的各个方面比如如何建立开发环境、如何调试以及如何在虚拟机中运行等。书中的实例操作系统采用IA32作为默认平台所以保护模式也作为必备知识储备收入书中,而这是传统的操作系统实践书籍经常忽略的总之,只要是开发自己的操作系统中需要的知识书中嘟尽量涉及,以便于读者参考   众所周知,一个成型的操作系统往往非常复杂如果考虑到操作系统作为软硬件桥梁的特殊地位,那麼它可能看上去比一般的软件系统更难理解因为其核心部分往往包含许多直接针对CPU、内存和 I/O端口的操作,它们夹杂在一片代码汪洋之中显得更加晦涩。   我们有许多源代码公开的操作系统可供随时下载和阅读,看上去好像让实现一个供自己把玩的微型操作系统变得嫆易很多但事实往往不尽人意,因为这些代码动辄上万甚至几十几百万行而且细节之间经常互相关联,要理解它们着实不易我们有許多容易得到的操作系统教程,但读来好像总觉得跟我们有隔膜不亲近。造成这些的根本原因在于学习者一开始就面对一个完整的操莋系统,或者面对前辈们积累了几十年的一系列理论成果而无论作者多么擅长写作,读者多么聪明或者代码多么优秀,要一个初学者悝清其中的头绪都将是非常困难的   我并非在此危言耸听,因为这曾经是我的亲身体会当然,如果只是为了考试几本操作系统理論书籍就足够了,你不需要对细节那么清楚但如果是出于兴趣呢?如果你是想编写自己的操作系统呢你会发现理论书籍好像一下子变嘚无用武之地,你会发现任何一个细节上的理解错误都可能导致自己辛辛苦苦编写的代码运行异常甚至崩溃   我经历过这一切!我曾經翻遍了一本《操作系统:设计与实现》,也没有找到实现一个操作系统应该从何处着手并不是这些书不好,也不是前人的代码不优秀而是作为一无所知的初学者,我们所不了解的不仅是高居庙堂的理论知识还有让我们举步维艰的实践细节。   可能在这些教科书作鍺的眼里操作的细节不属于课程的一部分,或者这些细节看上去太容易根本不值一提,甚至作者认为这些属于所谓“经验”的一部分约定俗成是由读者本人去摸索的。但是实际情况往往是这些书中忽略掉的内容恰恰占去了一个初学者大部分的时间,甚至影响了学习嘚热情   我至今仍记得当我开始编写自己的操作系统时所遭受的挫败感,那是一种不知道如何着手的无助的感觉还好我坚持了下来,克服了各种困难并完成了自己的操作系统雏形。   进而我想到一定不只是我一个人对编写自己的操作系统怀有兴趣,也一定不只昰我一个人在实践时遇到困难或许我应该把自己的经历写下来,从而可以帮助跟我相似的后来者就这样,我编写了本书的第一版也僦是《自己动手写操作系统》。我相信如果你也对神奇的计算机世界充满好奇,并且希望通过自己编写操作系统的方式来了解背后发生嘚故事那么你一定可以在这本书中得到一些帮助。而假如你真的因为我的书而重新燃起实践的热情从而开始一段操作系统旅程,我将會感到非常高兴   不过我得坦白,在写作《自己动手写操作系统》的时候我并不敢期待它能引起多少反响,一方面因为操作系统并鈈是时尚的话题另一方面我也是走在学习的路上,或许只是比读者早走了一小步而已然而出乎我的意料,它面世后重印多次甚至一喥登上销量排行榜的榜首,这让我觉得它的确有一定的参考价值我要借此机会感谢所有支持我的读者。   在我写作《自己动手写操作系统》的时候并没有想过今天会有一个第二版。原因在于我希望这本书是用来填补空白的,而不是重复去做别人已经做得很好的事情所谓填补空白,具体说就是让像我一样的操作系统爱好者在读完本书之后能够有信心去读其他比较流行的开源的操作系统代码,有能仂从零开始自己动手写操作系统而这个任务第一版已经完成了。   那么为什么我又写作了第二版呢原因有几个方面。第一虽然第┅版未曾涉及的进程间通信、文件系统等内容在许多书中都有讲解,但阅读的时候还是感觉有语焉不详的通病作者本人可能很清楚原委,但写得太简略以至于读者看来未必清晰。第二我自己想把这个圈画圆。第一版的书虽然完成了它的使命但毕竟到书的结尾,读者看到的不是一个真正的操作系统它没有文件系统,没有内存管理什么也干不了。在第二版中你将会看到,你已经可以通过交叉编译嘚方式为我们的实验性 OS编写应用程序了也就是说,它已经具备操作系统的基本功能虽然仍然极其简陋,但第一个圈毕竟是已经圆起來了。第三实践类的操作系统书籍还是太少了,以至于你要想看看别人是怎么做的除了读以《操作系统:设计与实现》为代表的极少數书籍之外,就是一头扎进源代码中而结果有时相当令人气馁。我自己也气馁过所以我在第二版中,仍然试图把话说细一点把自己嘚经验拿出来分享。而且我选择我能想到的最精简的设计以便让读者不至于陷入太多细节而无法看到全貌。我想这是本书可能具有的价徝所在──简化的易懂的设计还有尽量详细的文字。   在这一版中内容被划分成上下两篇。上篇基本上是第一版的修订只是做了┅个调整,那便是在兼顾 Windows和Linux两方面用户的基础上默认在Linux下建立开发环境来编写我们的操作系统。至于这样做的原因在本书第 2章有比较詳细的说明。当然开发环境毕竟是第二位的,书中讲述的内容以及涉及的代码跟第一版都是一致的本书的下篇全部都是新鲜内容,主偠是增加了进程间通信、文件系统和内存管理跟第一版的做法相同,下篇仍然不仅关注结果更加致力于将形成一个结果的过程呈现出來。与此同时由于本书旨在分享和引路,所以尽可能地简化了设计以便将最重要的部分凸显出来。读者将看到一个操作系统的文件系统和内存管理可以简陋到什么程度。简陋不是缺点对于我们初学者而言,正是需要从简陋入手换言之,如果你已经对实现一个操作系统有了一定的经验那么这本书可能不适合你。这本书适合从来没有编写过操作系统的初学者   本书的排版是我用L ATEX自己完成的。在排版中我花了一些工夫因为我希望读者购买的首先是一本易于阅读且赏心悦目的书,其次才是编写操作系统的方法另外,书中列出的玳码均由我自己编写的程序自动嵌入L ATEX源文件从而严格保***和光盘的一致性,读者可以根据文件名和行号方便地找到光盘中   代码的准确位置   此外,在第二版中还有一些小的变化首先是操作系统的名字改变了,原因在于虽然我们的试验性   OS从前辈们那里借鉴叻很多东西但其各个部分的设计(比如文件系统和内存管理)往往有其独特之处,所以我将原先的 Tinix(本意为 TryMinix)改成了新名字Orange ’S(这个名芓来自于我的妻子 ,)以表示它们的不同。另外书中的代码风格,有些地方也做了调整   我想,虽然第二版有着这样那样的变化泹有一点没有变,那就是本书试图将我在编写自己操作系统的过程中的经验尽可能地告诉读者同时尽可能将我当初的思路和编码过程呈現出来。很可能读者比我更聪明有更好的解决问题的方法,但无论如何我认为我自己的经验可以为读者所借鉴。如果真是如   此峩将会非常欣慰。   在第二版的编写过程中我同样要感谢许多人。感谢我的父母和爷爷对我的爱并希望爷爷不要为我担心,写书是件辛苦的事但同时也使我收获良多。爸爸在第二版的最后阶段帮我订正文字这本书里有你的功劳。我要感谢博文视点的各位朋友感謝郭老师的理解和支持,感谢李玲的辛勤工作感谢江立和李冰,你们的高效让我非常钦佩我还要感谢孟岩老师,你给我的鼓励我一直記在心里我要感谢我的挚友郭洪桥,不仅仅因为你在技术上给我的帮助更加因为你在精神上给我的支持。感谢我的同事和朋友张会昌你在技术上的广度和深度总令我钦佩。另外在第一版中帮助我的人,我要再次谢谢你们因为没有第一版,也就没有第二版   在所有人中我最应该感谢和最想感谢的,是我的妻子黄丹红感谢你给我的所有建议,还有你帮我画的图尤其是,当这本书在我预想的时間内没有完成的时候当我遇到困难迟迟不能解决的时候,你总在一旁给我鼓励在你那里,我从来都能感觉到一种温暖我深知,如果沒有你的支持我无法坚持下来将书写完。谢谢你这本书同样属于你。   跟第一版相比这本书涉及的内容触及操作系统设计的更多方面,而由于笔者的水平实在有限难免有纰漏甚至错误。如果读者有任何的问题、意见或建议请登录/fksec/article/details/7888251 该资料是《SQL Server 2008数据库设计与实现》嘚随书源代码 对应的书籍资料见: SQL Server 2008数据库设计与实现(关系数据库实现的通关宝典) 基本信息 原书名: Pro SQL Server 上架时间: 出版日期:2009 年11月 开本:16开 页码:560 版次:1-1 编辑推荐    资深数据库专家的心血力作    SQL Server设计思想的独到解析    关系数据库实现的通关宝典 内容简介   本书深入浅出地介绍了目前世界上最受欢迎的数据库管理系统之一——sql server。全书共分三个部分:第一部分阐释了数据库的基本概念讲解了数据库建模语言;第二部分展示了从概念建模到在 sql server 2008上真正实现数据库的过程;第三部分深入探讨了 sql server若干方面的技术细节,如数据保护、索引、并发访问等通过将理论融入数据库实践,清晰地讲解了关系型数据库的设计原则完整地展示了如何进行良好的关系型数据库设计,深入揭示了 sql server 2008的技术细节.   本书浓缩了作者作为 sql server数据库架构师多年来丰富的实践经验,适合各类数据库开发和管理人员学习参考... 作译者 作者:   Kevin Kline是Quest軟件公司SQL Server解决方案的技术战略经理。Kevin从2004年开始就是微软的SQL Server ShoupInc.公司内部IT部门的应用程序监管,该公司是——家技术方案的全球供应商总蔀位于伊利诺伊州的Springfield。Kurt在IT工业中的经验超过了17年他在SQL Server专家联盟的董事会中服务了5年,为很多SQL Server杂志供过稿也在讨论SQL Server数据库编程的国际会議上发过言。   Louis Davidson作为企业数据库开发人员和架构师,他拥有超过15年的工作经验目前他是田纳西州Nashville的Christian广播网络和NorthStar工作室的数据架构师。对于Louis而言他全部的职业经验几乎都与微软的SQL Server有关,从早期版本一直到当前最新版本的Beta版Louis是一本讲数据库设计的书的4个版本的主要作鍺。Louis主要的兴趣领域是数据库架构和用T-SQL编码并且,他设计过许多数据库在这许多年中编写过数以千计的存储过程和触发器。   Scott Klein是一位独立咨询师对SQL Server和.NET用户群体交流。Scott住在佛罗里达的Wellington当他不坐在计算机前时,你会发现他和自己的家人在一起或者骑着他的雅马哈摩托车轰鸣在当地的摩托车越野赛赛道上。你可以通过ScottKlein@SqlXml.com联系他 目录 封面 -17 封底 -16 扉页 -15 版权 -14 译者序 -13 关于作者 -12 序 -11 前言 -10 致谢 //blogs/louis_davidson),其标签为DesignBook同时吔会发布到我的网站上(入门地址:/Hui-/soft//soft/)自由下载。PHP遵守GNU公共许可(GPL)在这一许可下诞生了许多流行的软件诸如Linux和Emacs。你可以不受限制的获得源碼甚至可以从中加进你自己需要的特色。PHP在大多数Unix平台GUN/Linux和微软Windows平台上均可以运行。怎样在Windows环境的PC机器或Unix机器上***PHP的资料可以在PHP官方站点上找到***过程很简单。 如果你的机器解决了2000问题那么PHP也一样没有千年虫问题! )了解更多。 PHP的应用在个人性质的web工程中增长显著根据Netcraft在1999年10月的报告,有931122个域和321128个IP地址利用PHP技术 这样的极受欢迎的站点,你不会感觉出PHP的速度与其他的有什么不同最起码我就没有感覺出来!好了,让我们来看看PHP有那些优点: - 学习过程 我个人更喜欢PHP的非常简单的学习过程与Java和Perl不同,你不必把头埋进100多页的文档中努力学***才可以写出一个象样的程序。只要了解一些基本的语法和语言特色你就可以开始你的PHP编码之旅了。之后你在编码过程中如果遇到了什麼麻烦还可以再去翻阅相关文档。 PHP的语法与CPerl,ASP或者JSP对于那些对上述之一的语言较熟悉的人来说,PHP太简单了相反的,如果你对PHP了解較多那么你对于其他几种语言的学习都很简单了。 你只需要30分钟就可以将PHP的核心语言特点全部掌握你可能已经非常了解HTML,甚至你已经知道怎样用编辑设计软件或者手工来制作好看的WEB站点由于PHP代码能够无障碍的添加进你的站点,在你设计和维护站点的同时你可以很轻松的加入PHP使得你的站点更加具有动态特性。 - 数据库连接 PHP可以编译成具有与许多数据库相连接的函数PHP与MySQL是现在绝佳的组合。你还可以自己編写外围的函数取间接存取数据库通过这样的途径当你更换使用的数据库时,可以轻松的更改编码以适应这样的变化PHPLIB就是最常用的可鉯提供一般事务需要的一系列基库。 - 可扩展性 就像前面说的那样PHP已经进入了一个高速发展的时期。对于一个非程序员来说为PHP扩展附加功能可能会比较难但是对于一个PHP程序员来说并不困难。 - 面向对象编程 PHP提供了类和对象基于web的编程工作非常需要面向对象编程能力。PHP支持構造器、提取类等 - 可伸缩性 传统上网页的交互作用是通过CGI来实现的。CGI程序的伸缩性不很理想因为它为每一个正在运行的CGI程序开一个独竝进程。解决方法就是将经常用来编写CGI程序的语言的解释器编译进你的web服务器(比如mod_perl,JSP)PHP就可以以这种方式***,虽然很少有人愿意这样以CGI方式***它内嵌的PHP可以具有更高的可伸缩性。 - 更多特点 PHP的开发者们为了更适合web编程开发了许多外围的流行基库,这些库包含了更易用的層你可以利用PHP连接包括Oracle,MS-AccessMysql在内的大部分数据库。你可以在苍蝇上画图编写程序下载或者显示e-mail。你甚至可以完成网络相关的功能最恏的是,你可以选择你的PHP***版本需要哪些功能引用Nissan的Xterra的话来说就是PHP可以做到你想让它做到的一切而且无所不能! 国外 / - PHP官方站点 / - 极好的教程 - 代码交换 / - 教程、专栏和邮件列表档案 / - 文章和代码 本文档最新版本及文中提到的相关源码及VC6工程文件请在本站找,嘿嘿~~ (首页的SkyDriver公开文件夾中可能需要用代理才能正常访问该空间——空间绝对稳定,不会丢失文件!) (最近工作重心不在SIP开发SO本文档也没有机会更新,有技術问题也请尽量咨询他人本人不一定能及时回复。)   一直没空仔细研究下oSIP最近看到其版本已经到了/msdownl ... ,原创文章欢迎转载,但请保留出处说明!) 附件为原作者提供的

. 样题 . 下列乘法算式中:每个汉字代表1个数字(1~9)相同的汉字代表相同的数字,不 同的汉字代表不同嘚数字 赛软件 * 比赛 = 软件比拼 试编程确定使得整个算式成立的数字组合,如有多种情况请给出所有可能的***。 . 计算24是流行的扑克游戏其方法是任意取出4张牌,A J Q K 王牌 算 1其它 牌按点数计算,花色不计目标是通过加、减、乘、除和括号最终算出24。设计一个程序 输入4个數字(1~10),则列出所有可能计算结果为24的方案要求: 方案不能重复(加法乘法交换律等算不同方案)。 计算中局部可以为分数结果为整数即可(如 3 3 7 7 算法: (3 + 3/7)*7) 如果没有找到方案输出:无解。

变色龙是一款休闲类的扑克牌游戏老少皆宜。 每一轮各玩家要根据上一家变的花銫依次出一张牌如果没有牌可出,就只能扣一张牌出牌时点数越大越好,而扣牌时则应尽量扣点数最小的牌所有牌都出完后,将统計各个玩家扣牌的点数扣牌点数最小的玩家获胜。 正式版新增了很多全新的功能 首先,正式版里加入了设置万能牌的功能所谓万能牌,就是不管别人出什么牌都可以出万能牌,并且变成自己想要的花色(类似大小王)默认情况下该功能未开启,需要用户在设置界媔自行开启一般情况下,都是以J作为万能牌但也有一些其他玩法(比如7作为万能牌),玩家可以根据自己的需要进行设置 其次,游戲的操作方式也有所更新玩家如果想出哪张牌,只要双击该牌即可省去了很多麻烦。如果玩家想扣哪张牌也只需双击该牌即可。双擊的规则是:如果对应牌可以出则双击时出牌;只有对应的牌不能出,双击时才会扣牌 还有一种出牌的方式——拖动出牌(需在设置堺面开启此功能,默认未开启)开启此功能后,只要将要出(扣)的牌拖动到自己的出(扣)牌位即可该功能的好处是,可以用颜色嘚形式提示用户是否可以出牌绿色代表可以出;蓝色代表此张牌可以出,但可能还有更好的选择;红色代表不能出扣牌时的提示与出牌时类似,绿色代表可以扣;***代表还有能出的牌是否要扣牌得考虑清楚;红色代表不能扣牌。 然后相比之前的Beta版本,正式版可以支持最多4副牌只要在设置界面选择好要使用的牌数后,单击确定即可改变牌数后,将在下次运行游戏时生效 次之,正式版本可以选擇游戏动画的模式“普通”模式也就是之前Beta版本的模式,中间的花色显示将会从下到上滚动直至目标花色这种模式看久了会有种心烦嘚感觉,因此建议大家试试“优化”模式“优化”模式是正式版新推出的模式,中间的花色显示将按照最短路径向上或向下滚动如此┅来,不管变成什么花色最多只滚动两次。选择“关闭”模式将取消所有动画包括发牌时的动画以及更改花色时的动画。之所以推出這种模式是由于某些配置较低的电脑在发牌时会产生明显的闪烁,影响了美观性因此需要关闭动画。 再次正式版可以更改电脑玩家嘚等级以及姓名。等级更改只要在设置界面选择对应的级别即可如果要更改电脑玩家的名字,只要在设置界面的“电脑玩家等级/姓名”Φ单击电脑玩家的名字即可更改其中,电脑“逗你玩”和“好大胆”的新名最多只能有5个汉字或字符电脑“小二黑”的新名最多可以囿14个汉字或字符,超过该数量的部分将被忽略 再次,玩家可以自主设置游戏窗口背景的颜色也可以将自己喜爱的图片设置为游戏背景。在游戏开始时的欢迎窗口中只要选择“显示高级选项”按钮,就可以设置默认情况下有9种颜色供大家选择。如果不满意还可以选擇“自定义”按钮。 自定义模式中不仅可以更改游戏的背景颜色还可以自定义背景图片。只要将一个图片文件拖拽到对应的文本框中戓是在文本框中直接输入图片的路径,就可以实时预览效果目前支持的图片格式很多,如.bmp.jpg,.ico.gif等等。选中“自动调整图片至适应窗口夶小”按钮则不管图片尺寸怎样,都自动调整为与窗口等大程序有记忆功能,下次再运行游戏时无需再次设置如果不想再使用背景圖片,只要将图片的路径删除即可 可能会出现中间的花色显示挡住背景图片中物体的情况。这时只要用鼠标按住中间的花色显示不放开再拖拽到别处即可。不能放置的地方会有相应的提示 再次,正式版支持自定义牌背图片在设置界面的“牌背花色”中选择“自定义圖片”,再拖拽一个图片文件到文本框中即可牌背图片不限制大小,但过大或过小的图片可能会导致游戏时的闪烁可以选择关闭动画來解决这一问题。 再次正式版支持将参数以文件的形式保存。只要设置好参数再单击设置界面右下角的“保存参数到文件”即可。此功能的作用是方便不同电脑间的参数共享省去设置的麻烦。 游戏自带老板键功能在游戏时按下ESC,程序会最小化到通知栏默认情况下,程序在通知栏的图标文件为本程序目录下的HIDE.ICO提示文本为System Tray。如果用户要更改程序在通知栏的图标直接替换HIDE.ICO文件即可;如果用户要更改提示文本,可以在程序的设置菜单里进行更改 最后,对游戏中扑克牌所对应的点数进行一下说明默认情况下,从A到10分别代表1点、2点、3點……10点J代表11点,Q代表12点K代表13点。但有的玩家的规则比较特殊比如JQK都只有半点。正式版设计时已经考虑到这些问题因此正式版可鉯支持自定义扑克牌点数。如大家需要扑克牌对应非默认点数请发送电子邮件到我的邮箱(见下方)。邮件中请注明是变色龙扑克牌游戲以及游戏的版本号,和每张牌对应的点数回复的邮件中将包含一个点数配置文件,只要将该文件拷贝到与“变色龙.exe”同一个文件夹丅即可被游戏识别并应用

下载 第1章开发思想 命名是所有事的开始。 要真正掌握一门编程语言不仅要理解它的语法和语义,更重要的是掌握语言所体现的哲 学思想、语言产生和发展的背景以及设计特点 1.1 PHP与我 大家是否想过,为什么会有这么多的编程语言除了所谓“主流語言”例如C、C + +、 P a s c a l等之外,还有其他的如L o g o l、C o b o l、F o r t r a n、S i m u l a和许多更加特殊的语言当列出一 个项目的梗概时,大多数软件开发者不会真正地考虑到可鉯使用多种编程语言;他们都有自己 偏爱的语言(也许是公司指定的一种语言)了解它的优点和它的缺点,并根据语言的具体特点 修正項目但当克服所选语言的缺陷时,就可能会增加不必要的额外工作 了解如何使用一门语言却缺乏其特定的概念知识,就好像一个开卡車的人想参加二轮马车 比赛一样当然,一般来讲他应该懂得如何驾驶二轮马车他甚至可能在终点线上跻身前列, 但他绝不可能成为一個出色的车手除非他熟悉新车的独特之处。 类似地当面向对象程序设计( o o p)程序员编写一个应用程序的时候,他会尽力使程序满 足项目要求处理同一个任务,不同的程序员会运用不同的方式哪种方式更好?每一个程序 员会说他(她)的方法最好但只有那些熟悉两種概念—o o p和过程化编程—的人能够作出 判断。 前面提到的每一种语言代表一种解决问题的特定方法这些问题多属于具有特殊要求的某 一特殊种类。因为这些语言集中在一个有限的应用领域内他们的成功性也限制在这些领域。 像C和P a s c a l这样的语言变得如此流行就是因为它们被广泛应用,并且它们不针对特殊问题 却提供了能很好地解决普遍问题的工具。 那么P H P是如何适应这一体系的呢尽管它被称之为一种语訁,但P H P并不是一种真正独立 的语言而是许多语言的混和体。它主要用C的句法但与C有很大不同。它是被解释的 P H P 能识别不同的变量类型,但没有严格的类型检查 P H P识别类,但没有结构体类型类似的例子 很多,但你可能已领会到了关键一点: P H P融合了许多种不同的解决问题嘚思想形成了一种全 新的、独一无二的方法。 为了能够用P H P成功地开发We b应用程序我们鼓励你首先回答下述问题: P H P是我的项目 所需的理想語言吗?问得好如果我们说不,那我们就会显得很愚笨(谁会去写一本关于他们 第一部分高级P H P 认为不好的东西的书呢)。让我们重新闡述这个问题对项目来说有比P H P更好的语言吗?这 次我们可以很有把握地回答如果你正在从事网络应用程序的开发, P H P就是为你准备的最恏的 语言 1.2 计划的重要性 你为什么应该阅读这一部分 即使你是一个很熟悉P H P的职业程序员,我们也建议你阅读下面的部分因为这里包 含了荿功开发的基本知识,如果你对所讨论的题目已很熟悉也应该花时间浏览一下, 你可能会发现新的信息—新的题观点、新的解决方法、噺的***你对解决未来项目 的不同方面的问题了解得越多,你就能越好地抓住关键点并且用更好的方式处理。我 们希望你信任我们是職业开发者并相信我们的经验,这将使你在以后受益 在深入探讨P H P特定问题之前,先让我们从一个更广泛的观点开始不论你使用什么語言, 也不论你在什么平台上开发有一些问题在应用开发中是总会涉及到的。 当从事一个专业项目的时候考虑一下你正在做什么是至關重要的,“了解你的敌人永远 不要低估它”。尽管你的项目并不是一个真正的敌人这句话的寓意仍然适用,在转向其他题目 时要知道项目的所有技术条件、目标平台、用户,并且决不要低估那些没有考虑周全的小问 题的重要性 据我们的经验,计划占用了5 0 %的开发时間项目越大,它的纲要就应该越详尽这一原则 既适用于同你的顾客相联系并与他们密切合作以确定一个总的项目概要,又适用于与你嘚开发 者探讨确定一个编码概要在一致性和可维护性上花的气力越少,就越容易在重新打开旧文件 并设法清除错误或添加新的特征时遇箌问题 计划所用时间与项目大小并不一定成比例,例如想一下要设计的一个搜索算法。这一应 用程序只需要在一堆信息中进行基本的搜索并能根据规则抽取数据,由于数据已经存在所 以创建和输出将不会需要太多的努力。这一应用程序将把它的大部分运行时间花在搜索循环上 这个循环也许用不了1 0 0行代码,但是为一个优化的循环选择设计一个优化的算法很容易耗费一 整天的时间这个小小的循环也許是设计阶段最庞大的部分,但另一方面你可以在不到一天 的时间内策划好数千行的代码。 同样我们假定需要一个小脚本来列出某个目录中的所有文件,你能够很快地完成它使 其能从事某一特定任务,在一个特定的目录列出所有文件不必再担心它了—问题已解决, 鈳以转向其他任务把你的程序抛在脑后。但另外一种策略是考虑一下以后的某个时间甚至 可能是在一个完全不同的项目中—你可能会洅一次需要一种类似的工具,仅仅一遍又一遍地 重做目录列举器每一个对应一个特定的任务,这简直是在浪费时间因此,当首次遇到這种 情况时应该考虑到这一点,应从一个目录列举器中创建一个分离的模块允许它列举不同的 目录,有选择性地递推子目录甚至允許使用通配符,你可以创建一个“防弹”函数它即能 处理大多数特例,又能完美地应付一个目录列举器的普通要求采用这种策略经过幾个项目之 后,你将拥有一个工具参数的库可以安全地重新使用和依赖这个库,从而可以极大地减省开 发时间 2部分第一部分分高级PHP 下載 当然,有了一个日益增大的免费工具函数库依然不能满足全部需要,也不能优化这个库 以适应特殊需求有些库太庞大以致不能随处咹装,因为每一次选中都必须分析几百K字节的代 码这将严重降低站点的性能。在这种情况下需要用1 0 0 %自己创造的优化解决方案,以取代 非最优解决方案 更大的项目如果缺乏计划将导致更多的错误,在开发后期可能会遇到没有或无法预见的 困难,这是由于缺乏计划的时間和工作这些困难可能会严重到让你彻底地重组整个项目。例 如对一个依赖额外数据库提取层的数据库支持的应用程序,其数据库提取层仅能接收文本数 据但后来你发现也需要用它接收数值性的数据,通过工作区转换可以使它能够接收数值性 数据。但后来你又感觉箌这个工作区仍旧不能满足需要这时唯一能做的就是改变数据库接口, 这需要重构提取层并对所有主代码调用进行检查当然也需要清除先前创建的工作区。 这样数小时甚至整天的工作将不得不耗费在本来从一开始就可以避免的问题上,这些问 题往往决定了程序开发的荿败因为“时间是你永远都不可能充分拥有的珍贵资源”。下面的内 容将针对大部分基本的却是非常重要的开发中的实际问题进行讨论:改善代码质量以及基本设 计和文件管理的问题陈述完这些后,我们创建一个应用程序接口( A P I)采取简单的、实用 的方式使你熟悉这┅新的思想,然后我们从头创建一个A P I在纸上从理论上开发它,并明确一 些实用规则来帮助你实施下一个A P I例如风格问题、以及商业技巧等。 1.3 编码规范 好的编码和差的编码之间究竟有何区别呢实际上,这个问题很简单好的代码(确实好 的代码)能够像一本书一样被阅读。你能从任何地方读起并且能够时刻意识到你所读的这些 行是干什么用的,它们在什么条件下执行它们所要求的设置。即使你缺乏背景知识遇到了 一个错综复杂的算法,你也能很快看出它所从事的任务以及它的风格。 举个例子然后说“照着做”总是很容易的,但峩想这一章应该使你打下写专业化代码的 坚固基础这一基础将区分真正精心编制的代码和一个草草完成的程序段。抱歉的是由于篇 幅所限,我们不能按我们所希望的那样详尽地讨论良好的代码书写风格的每一方面但本章将 给你一个很好的开始。我们期望你能迅速获得專用的材料以熟悉软件设计和工程的每一要点。 编码是一个很广的领域几乎是一门独立的科学。有许多论文论述它虽然这些论文大哆很乏 味,很理论化但在应用中是不可放弃的。下面我们就最重要的问题进行最基本的讨论 1.3.1 选择名字 选择变量名可能是程序员最常做、但却想得最少的。如果你已建立了这些在大项目中出现 的变量名字、类型、定义位置的清单那么你就创建了一个类似于小***簿的东覀,你想让你 的清单成为什么样子呢不同的命名方案已发展起来了,它们有不同的思想及各自的优点和缺 点这些方案一般分为两类:簡短的变量和函数名及谈话式的变量和函数名(描述变量类型和 目的的更长的名字)。 某个***目录可能是这个样子的如表1 - 1所示。 第1章認开发思想部分3 下载 表1-1 ***目录 姓名地址*** J . D . 3 8 2 W. S -3 9 5 1 M . S . 2 0 4 E . R . -8 3 8 2 这份列表非常有意思:该列表有两个条目但并没有更多的信息。人名只有首字母没囿 全称;只有房间号,但没有街道名;只有***号码的一部分却没有完整的号码。 让我们看另外一个例子如表1 - 2所示。 表1-2 ***目录 姓名哋址*** h t 5 f t 9 i n a g e 3 2 J o h n 386 West StreetL o s + 1-5 5 5-3 0 4-3 9 i a, S m i t h f e m a l e s i n g l e U S AE a r t h 在这个例子中,每个人的名字包括身高、年龄、性别及婚姻状况地址中不但包括街道和 城市,而且也包括州、国镓、甚至星球***号码附加了国家和地区号。 第二种解决方案比第一种好吗两个都不是最好的。在程序课上讲授的这两种解决方案 嘟不令人满意,定义一种类型t p I n t t e g e r C o u n t e r I n s t a n c e这样长的名字)也是不可 接受的尤其当我们从事的是像压缩这样复杂的缓冲操作的时候更是如此。 这只是普遍思想被误用的一个简单例子该怎么办?解决的办法是选择好的整体思想然 后在适当的地方加以例外处理,当写一个应用程序时應该知道你的代码从事的是什么工作, 能够快速地从一点转到另一点—但其他人可能认为这并不容易如果你从开发组的某个人手 中获得┅个源文件并需要添加一些特征,首先必须对其进行整体把握并区分代码的各个部分。 理想情况下这一过程将和阅读源文件平行进行,但由于在没有提示和公共样本帮你理清代码 来阅读的情况下这是不可能做到的,所以在源代码中包含尽可能多的额外信息并且使得奣 显的事实不易于混淆就显得很重要了。 那么如何能查知这些信息并将其合并入自己的代码呢? ? 使代码更易读 4部分第一部分分高级PHP 丅载 ? 如果可能,选择谈话式名字 ? 尽可能添加一些注释。 ? 保持清晰、一致的函数接口 ? 把代码结构化成逻辑群。 ? 抽出单独代码塊 ? 使用文件来将函数分类。 ? 编写文档 下面将讨论上述各主题。 1.3.2 使代码更易读 在阅读的时候为了理解文章的含义,你的大脑必须汾析从你的眼睛里获得的信息识别 出重要的部分,然后把这些部分译成正确的代码这个分析过程分两步执行:形式分析和逻辑 分析。艏先通过检查文章的可视结构来执行形式分析例如:检查段落、行、列甚至词之间的 空隙。这一过程打破了对文章的整体了解将其分荿更小块的树形结构。假想一个结构严密的 树有顶部的树节和底部的树叶,树的顶部包含着最一般的信息例如,你要读段落顺序树 嘚底部是诸如一行中的词序或是一个词中的字母顺序的一些东西。 逻辑分析过程将提取这些形式信息然后按顺序遍历此树,并设法将信息译成有意义的结 果这是一种语法上的翻译(这个句子有什么样的结构?)还是一种语境式的翻译(这句话是 什么意思?)在此处讨論中并不重要重要的是:形式分析的结果越好,逻辑分析就越容易、 越快、越好 逻辑分析能补偿形式分析中失去的信息,但仅仅是在┅个有限的程度上补偿 你也许能读懂前面的这个句子,但要花费比读本书其他句子更长的时间和更多的注意力 在第一步分析中,一些偅要的信息(间距)丢失了你并不习惯这样。 我们可以通过添加一些标点使其变得更简单易懂 标点是进行形式分析的有用信息。注意箌阅读这一版本或把注意力集中在所选的任意一点 上要容易得多下一步: 这是你阅读句子的常规方式,即阅读文章时最习惯的方式但峩们也可用多行结构描述这 个句子: 这是可以让你能尽快地理解这个句子极端的方法的一种,上面的断句阻碍了自然的阅读语 序因为你並不习惯读一个在句法上被拆成单元的句子,但对于源代码来说这是一个优势, 第1章认开发思想部分5 下载 因为源代码经常包含复杂的结構、公式等使源代码保持清晰的外在形式、结构以帮助读者理 解是很重要的,这可以通过使用缩进和在适当的位置放置编程语言的关键詞来实现 让我们看一个简短的P H P程序: 这个代码本身也许并不是智力劳动的精品,我们只观察一下它的结构如果以前没有读过 这个片段,你能够一下就指出主代码的起始处吗你能标记出主代码中最初的和最后的说明 吗?即使你能一下子找到想找的地方你的眼睛也会不甴自主的从行首开始从左到右的浏览, 在你认为目标可能在的地方停下来你的大脑也要重复读这一行,因为你会不时丢失形式分析 得来嘚信息为了弥补起步时信息的缺乏,你的大脑(逻辑分析区)也会采取这一步并强调 两次。正如电脑一样你的头脑的能力是有限的。所以当你的大脑确实想要理解和记忆源代 码时,逻辑分析区就在缺乏能力的情况下承担了额外工作但是理解和记忆恰恰是你想让人們 在读你的源代码时所达到的,也是你在读别人的源代码时想要达到的 因此,这就是为什么格式化源代码很有用的原因还有别的原因嗎?噢是的,格式好的 源代码看起来让人赏心悦目 下面是一些指导原则,其中阐述了我们所认为的在格式化源代码时的最优风格请紸意, 这些指导原则不是强制要求的但可以认为是一般的规范,许多工业的和开放式的项目已经用 这种方式将源代码格式化了 并且,采用这种风格经常会带来收益 ? 块标志符( < ?、? >、< ? p h p、< %、% >、{、}等等)要放在不同的行里。 ? 用tab 缩进所有的块(理想情况下把t a b宽度改成不超過4的值)。 ? 在关键词和关系对象符之间要留有空隙特别是在进行计算时尤其要这样做。 ? 将代码的逻辑块分别放在连续的行里使逻輯块分组,并在块之间留有空行 ? 用空行的方式分隔各个块。 ? 用空行的方式把函数头、函数脚和代码的其余部分分开(输入全局变量被看作是函数头的一部分) ? 把每一块的注释并入代码。 ? 在同一块内把所有行的注释放置在同样的一些列中 作为一个例子,清单1 - 2给出了某段格式化的代码 清单1-2 重新格式化的代码片断 6部分第一部分分高级PHP 下载 大家可以看到,这一小块代码读起来要容易得多 在代码中,空格的使用可以进一步把参数和关键词分开: 以上看似毫无必要不过要记住:这些代码要被嵌入几千行代码之中,所以必须改变你的 观点有些人说在书写源代码文本时,括号之间的空隙与其说有帮助不如说分散了人们的注意 力——我们必须承认有些时候这是事实,本书Φ的例子也并不都使用这种格式我们认为, 是否使用这种格式最后由你自己决定最重要的则是:要保持一致性。一旦你决定采用某种風 格就一定要坚持至项目的完成。如果你在修改别人的源代码你也要尽量遵守他们的风格。 在职业开发中一致性是最重要的原则之┅。 要注意阅读所有源程序的例子并尽量模仿他们的风格,调整你自己的风格直至和这些最 初的例子很接近为止一旦你对这种风格很熟悉,你会发现你所做出的努力没有白费 在进一步阐述之前,我们举两个例子来更好地说明这一点如图1 - 1和图1 - 2所示。 图1-1 坏的代码 图1 - 1中源玳码是要建立一个S Q L语句除了最后的一行是把一个包含“ select *”的字符串 赋给一个名为$ q u e r y的变量外,我们看不出图1 - 1中还有什么说明了该段代码的目的与之相反, 在图1 - 2中的代码中你就比较容易理解代码的所有目的。 第1章认开发思想部分7 下载 图1-2 好的代码 我认为代码就应该是这样臸少应该近似这样,代码应该有清楚的结构、很好的注释并 且很容易理解。 1.3.3 添加注释 我们无论怎样强调添加注释都不过分尽管编程时伱可能认为这是最微不足道的事情。在 编写高质量的代码时注释是很重要的。在解决复杂问题的时候很少有两个人会有完全一样 的想法,某些问题对于一个人可能是一目了然而对于另外一个人可能是模糊不清的,在这种 情况下注释就是大有裨益的,只要需要你都應该把它们添加到代码中。 目前主要有两种注释:头注释(例如文件头注释、模块头或函数头注释)和内部注释头 注释主要起介绍性作鼡,告诉读者一个文件要做哪些事情或下面这一大段代码是关于什么的。 内部注释用在函数内或嵌入代码中以解释代码的某一行或某┅块所做的工作。 下面介绍这些注释的外在感观及其所包含内容的概念现在,这些注释通常可通过快速应 用开发工具( R A D)或其他授权帮助工具来产生但由于在撰写本书时仍没有适合P H P的类似 系统,所以这些注释应该是手编的尽管这会增加一些额外的工作量。 下面按照注釋类型的抽象程度从最抽象的到最具体的来讨论。 保持注释不断更新 要记住在编写函数之中或之前就将其注释好仅仅为了加注释而读┅个文件是非常 令人厌烦的工作。同时要注意在以后的某个时候如果对进行函数的修改,就要适当地 更新你的注释例如,若增加或去掉全局变量那么你也要在注释中对它们的使用注释 进行更新;同样,如果参数顺序、类型等发生变化也是如此 使用宏来加速你的注释 茬你最喜欢的编辑器中,为每一种注释类型创建宏并给它们分配热键(例如为文 件头分配Ctrl+Alt+Fl,为模块头分配Ctrl+Alt+F2等等) 8部分第一部分分高级PHP 丅载 如果编辑器支持的话,可以把变量引入注释中这种创建详细的有大量信息的注释 工作就变成了一个创建简短对话框问题。 1. 文件头注釋 文件头可以像清单1 - 3那样编排 清单1-3 文件头注释 你可能偏爱使用多行注释创建的对话框有人认为这样美观(如清单1 - 4所示)。 清单1-4 文件头注释(使用多行注释) 2.在U N I X中提取块注释 在U N I X系统中下面的g r e p命令从源程序中提取这样的块注释: grep '^[\\\/]*\*' source.php3 选择什么样的风格来格式化你的标题并不重要,泹选择的由文件头包含的信息是很重要的 就像在上面例子中所看到的,标题应该包含一些整体信息如:关于模块作者等的细节条目要 按一种有意义的顺序放置(例如,包含一个长描述和一个短描述是没有意义的当读完长描述 后,就已经不再需要短描述了)下面的清單列出了我们所提倡的信息类型及其顺序: 第1章认开发思想部分9 下载 1)模块文件名。 2)短模块描述(一行) 3)长模块描述。 4)关于用法、要求、警告等的注释 5)作者的名字和联系信息。 6)模块的创建和最后修改日期 7)版权注意事项。 8)许可注意事项 9)转变记录、主頁、分配文件等的指针。 1 0)最后如果需要,变化记录中的摘要 如果这些听起来太多了,那么记住宁可有多余的信息,也不要缺乏信息当然,这并非 在所有范围及所有条件下都合适我们没有在前述的例子中包含所有情况。然而你应该设法 向你的标题中放置尽可能哆的数据—这是一种良好的习惯。最坏的情况是有些人可能不去读 它但有可能有些人感激它—也许就是你自己,因为在一个商业化项目Φ如果你忽视了版 权和许可注意事项,而当别的程序员免费更新你的代码时则会导致令人头疼的后果。 3.模块头注释 如果在一个文件Φ不止一个模块(例如当某个模块组的一个模块包含三个函数时),应该 在第一个函数前放一个信息量很大的标头模块头形如清单1 - 5所礻。 清单1-5 模块头注释 这些标题按顺序可能包含如下各项: 1) 短模块描述 2) 细节模块描述。 10部分第一部分分高级PHP 下载 3) 函数原型清单 4) 標记/注解。 多行注释再一次表现出其优越性 4.函数头注释 函数头应足够细致地为每一个函数(见清单1 - 6)描述句法、目的和必要的调用者信息。这 些注释的重要性相对于内部注释来说是次要的,函数头注释的目的是让程序员在模块开发和 扩展中迅速了解每一个函数的要求这些要求是为最初没有建立这些函数的“外人”所提供的, 缺乏函数头注释的源代码经常需要开发者深入其中找到所要信息而这一点經常会导致错误, 因为不是所有隐藏的陷阱(有时它们隐藏得很好)都会被发现 清单1-6 典型的函数头注释 一个函数头注释应按顺序包含如丅各项: 1)函数原型。 2)函数细节描述 3)标记/注解。 4)参数描述 5)返回值描述。 6)全局引用 7)作者和最后一次修改的日期。 5.内部紸释 第1章认开发思想部分11 下载 内部注释直接放入代码中并直接解释所有产生的问题。当你编写代码时每件事你自己 当然是很清楚的,這就是有人经常不写注释的一般原因后来当你重新打开这个文件时(甚至 也许是一年之后),你也许已遗忘你用的所有结构及使用它们嘚原因这是我们经常遇到的一个 问题。在我们自己的代码中或别人的代码中使用内部注释的原则是:注释越多越好这一原则的 唯一例外昰注释不能被滥用到让人们对代码模糊不清的程度,同时注意不要注释显而易见 的东西。清单1 - 7列举了一些例子 清单1-7 不好的内嵌注释 茬第一行中,因加1而增大的$ b a s e i n d e x代码是需要注释的语句吗我们表示怀疑。每一个 人都能看得出$ b a s e i n d e x正加上1但它为什么加1?为什么正好加1更好嘚注释大致是这样的: 跳至我们所指的下一个指数,它仅有一个元素的距离 第二个注解有同样的问题,但产生的原因不同程度员把算法的完整参考传送至代码中, 却又包含了很多不适当的“垃圾”当然,详细描述你所做的事情是好的但你必须弄清楚什么 是重要的,什么是不重要的 当你给代码添写注释时要考虑如下问题。 ? 你在做什么 ? 为什么要做这件事? ? 为什么要采用这种方式做 ? 为什么偠在这个地方做? ? 这个代码如何影响其他代码 ? 这个代码要求什么? ? 你的方法有什么缺陷吗 例如,当你分析字符串的时候记录輸入串的格式,你的分析器的偏差(它对输入中的错 误的反应)和它的输出如果这些信息太多,以致不能直接嵌入你的代码那么至少偠安置一 个指针,指向一个外部文件在此文件中读者能够了解到分析器的各个方面。同时要记住更 新函数头注释,即设置一个对此文件的链接 12部分第一部分分高级PHP 下载 1.3.4 选择谈话式名字 正如前面所提到的,为函数和变量选择合适的名字在编程中是一个很重要的问题一般情 况下,当为一个变量选择名字时首先要确定它是全局变量还是局部变量,如果此变量仅在函 数的局部作用范围内可见那么就给它選一个简洁、准确的名字来陈述此变量的内容或意义, 这个变量名应该至少包含两个词这两个词或者被下划线分开或者被大写字母分开,如清单1 - 8 所示 清单1-8 局部变量名实例 记住不要混用命名方案,要么都用小写字母来写变量名用下划线来分隔词,要么使用大 写字母来分隔词不要用大写字母来分隔一个变量而用下划线来分隔另一个,这会导致错误 并且表现出不好的风格。一旦定好你自己的风格就一矗坚持到项目结束。 每一个全局变量都应该有一个前缀来标识它所属的模块这一方案帮助把全局变量赋给它 们的模块,同时也可避免出洎不同模块的同名变量在全局范围内产生冲突前缀应该用下划线 和变量名分开,并应该包含一个词—多数是一个缩写(见清单1 - 9) 清单1-9 铨局变量名的例子 小尺寸优势 创建更小的项目,每一个项目都用不同的命名风格原因如下: ? 你能发现你偏爱的风格。 ? 当你不得不适應别人风格时能够很快变得熟练。 如上例所示全局变量名倾向于比局部变量名长,这不仅是因为全局变量具有模块前缀 也是为了分清全局变量和局部变量。当一个变量的定义和初始化因隐藏在一个你接触不到的模 块中而变得未知时用变量的名字来思考它的意义和内嫆就显非常重要。这在实践中当然有个 极限—没人想记住多于四十个字母的名字—但这只是一般意义上的极限 从根本上讲,你应该命名铨局变量就像向某人描述它一样例如,如何描述变量 $ p h p P o l l s _ l a s t I p你可能不知道p h p P o l l s是做什么的,但这个名字暗示它和p o l l s有一些关系 l a s t I P意指它是最后一个I P。哪一个I P你不知道。显然这个全局变量的名字选得不太好,因 为它并没有准确地描述其内容现在假定你问这个变量的含义是什么,***是它包含最后一 个投票者的I P,现在想想该给它取一个什么名字 $phpPolls_ last_voters_IP听起来如何?更好一 点不是吗?尽管这个名字可能很好但它仍鈈合适,因为你曾见过另外两个同样出自p h p P o l l s 第1章认开发思想部分13 下载 的全局变量都以p h p P o l l s 为前缀,然后紧跟一个词出于一致性的考虑,你可鉯决定在名字 内部仅用大写字母来分隔不同的词: $ p h p P o l l s l a s t Vo t e r s I P 函数名也应该用与全局变量名相同的相近风格加以处理,但略有不同函数命名应描述它 们的功能而且要符合语流,让名字符合语流是通过确定函数行为、并选择在该名字大量出现之 处最适合的名字来实现的 例如,如果鼡一个函数确定一个用户目前是否在线它可能有以下名字中的一个: 考虑到返回值类型,上述清单中只有第一个和最后一个名字是合适的假定函数将返回一 个布尔值,那么它经常用在一个与i f ( )语句的连接处在那里,它一般是这样的: 选择1: 选择2: 在第一个选择中函数名看起来不是很恰当,“If the user status of Jahn then do something.” 再检查一下第二种可能性:“If the John is online then do something.”,第二个观点没有打破语流 并且在第一眼见到的时候给人留下了更多印象。苐一个选择把问题公开化:什么身份被谈及该 身份如何返回?第二个函数名清楚地表示这个函数会检查某人的在线状况并返回一个布尔徝 如果检查结果在函数的变量参数中返回又会怎样? 选择1: 选择2 : 14部分第一部分分高级PHP 下载 尽管u s e r s t a t u s ( )并非一个不好的名字但g e t o n l i n e s t a t u s ( )更好一些。“g e t”這个词很清 楚地表明函数检索在线状态并将其存于某个地方—或者在一个全局变量中或者在一个函数 变量中。 )或将两个词交换顺序这將很好地适应模块前缀。 你的代码是两种语言的还是三种语言的 对代码最普遍的批评之一涉及“民族化”一种程序语言(起源于英语)與另一种程 序语言搅合在一起。在我们的实际例子中(To b i a s源于意大利语,Ti源于德语)当我们 检查各自国家程序员开发的项目时,我们发现怹们喜欢使用德语和意大利语变量名和函 数名而不是用英语这导致了一种奇怪的混淆。正如你不会在你的日常信件中混用英语、 法语、覀班牙语等一样所以,你在编程时也需要保持语言一致性使用英文名字编写 PHP程序,还有助于外国人理解你写的程序 1.3.5 保持清晰一致的接口 你也许不愿意再看到“一致性”这个词,但对于接口设计来讲它是编程基石中的关键一 块。 非常不幸的是P H P本身恰恰存在如何违反這一点的例子。 你在驾驶汽车的时候油门在右而刹车板在左。当你换一辆车时你希望情况也是如此, 无论你在哪里你都希望红灯意菋着停止,而绿灯意味着前进类似地,当你用一个库访问文 件且需要把一个文件句柄传给函数时,如果输出函数把文件h a n d u句柄作为第一個参数输出 函授将其作为最后一个参数,而另一个把它作为中间参数那么这会令人感到莫名其妙。 当设计接口时你应该首先考虑如丅问题: ? 通过这个接口交换什么数据? ? 我到底需要什么参数 ? 大多数(或所有)的接口函数所共有的参数是什么? ? 这些参数最合乎逻辑的顺序是什么 把它们牢记在心中,一旦你决定采用何种方式去做你就应该在你的模块中保持参数一致 性。即使内部函数也应遵從这一点这一策略将使你以后能从接口中获得内部函数。另外当 )的一个快速替代,并且大部分人会 从调用e r e g r e p l a c e ( ) (接收相反顺序的参数)转到调鼡s t r r e p l a c e ( )当然,这种说法有一定道理 第1章认开发思想部分15 下载 但是为什么r e g e x函数按一种与字符串函数相反的顺序接收参数呢?因为在P H P中r e g e x函数反 映了在C中的相应函数。在开发一个应用程序的时候看到s t r r e p l a c e ( )从其余函数中突现出来 是很别扭的事。在勾勒下一个接口的轮廓时注意不要讓这种情况发生在你的身上。 1.3.6 将代码结构化为逻辑群 应用程序通常包含不同的函数群每一个函数完成一项特定的任务并(或)应用于特殊的 应用领域。例如在写一个支持数据库的应用程序时,一个函数群应该仅仅对处理数据库访问 负责这个代码确立了它自己的存在,能够安全地从程序的其余部分分离出来—只要你设计 得好逻辑上只从事一项特定任务的函数群应该用某种方法设计,以使他们能够被独竝地处理 这些函数在形式上也应该和主代码分开,建立一个模块在运行一个应用程序之前,你应该建 立一个能将所有函数归类在一起嘚函数清单形成一个模块,并为每一个模块创建一个各自独 立的设计计划要注意创建详细的数据流程图,以便使模块能够满足应用程序的各种要求做 一个书面的整体计划,其重要性不可低估由于篇幅所限,我们不能够再深入谈及这个问题 但我们建议你读一些关于設计方法的好书。 1.3.7 抽取单独的代码块 抽取代码块是一项在设计和实施阶段都应该做的事情通常一个函数应该能完成以下工作: 1)开一个攵件。 2)从文件中打读取数据 3)证实数据(将数据合法化)。 4)更正数据中的错误 5)将数据写入文件。 6)关闭文件 每一步都可以“包装”成单独的一个程序块,抽取这些块并从中创建单独的函数是一种很 好的方法这不仅使你能够在别的函数中重新使用每一个程序块(你可能在别的地方也需要文 件操作的支持),而且还能使代码更容易阅读和纠错你可以使被抽取的部分“放弹”,给它们 装备“纠错器”以支持更多的东西。如果你采用内嵌法无法做到这一点你的代码会很快变得 异常庞大而冗赘,另外如果你在其他的函数中,使鼡同样的程序块时产生需纠正的错误你 将不得不在使用此块的所有其他的函数中反复进行同样的纠正。 通过提取可以把关键部分放在Φ心位置,只要更改一行程序就可以改变所有相关函数 的行为。 1.4 使用文件将函数分类 我们已经论述过对源代码使用复合式文件是有好处嘚但我们也同样建议你为其他资源使 用文件。这些资源可以是配置数据、客户标题、页脚或其他模板以及任何从你的项目中可以 抽出來作为一个单独实体而存在的东西。 在一个项目中使用模块有很多好处: 16部分第一部分分高级PHP 下载 ? 可以获得更小更容易维护的源代码文件 ? 可以对每一个文件进行不同的修改,而不必在整个项目中进行检查以进行一个微小的修 改 ? 可以将部分资源从项目中分离出来,鼡在其他项目中 ? 许多开发组成员能够同时工作在一个项目上,而不必在检查时将所有的文件合并成修正控 制系统 以上论述适用于一個项目中存在的大部分资源。 文件应根据其内容加以命名如果一些文件从属于一个更大的群体,可以给它们加一个共 同的前缀文件一般应该放在项目根目标的子目录下。例如一个数据库提取层,其中有可访 问不同数据库的模块这些模块被“包装”成单独的文件, 每個文件名应冠以前缀d b a (这里 d b a代表database abstraction)这样你就得到了d b a m y s q l,d b a o d 文件有对整个项目的全局化“选项”该配置文件应该包含独立的源文件所需要大嘚,能使其在 全局范围内可用的选项这种“选项”可包括环境选项,如站点名、文件系统位置等等 停留在(普通的) 路径上 当某子目錄包含配置文件时,要一直使用相对路径以确保项目在文件系统及用户系 统上是灵活的—不依赖开发环境的任何特定条件就像在其他环境下一样。能保持一 般化的东西就要尽量让它一般化 1.5 编写文档 除了注释和结构化以外,文档也是值得注意的一个项目的文件记录可能昰你的用户将要 见到的项目的第一部分,而第一部分是至关重要的 规范化写出的文档应该是开发过程中惯例性的一步。正如你希望微型電话或其他哪怕是在 很小的商店中购买的技术产品都有一本写得很好的手册一样你的用户也希望从你那里得到较 好的文档(更不用说他們可能会为此而付一大笔钱了)。 和注释一样文件记录通常是在R A D工具的帮助下产生的,很不幸目前还不存在专为 P H P设计的相应工具,所鉯写手册是一项费力不讨好但却很有必要的—份工作。并且这并不 会影响你的工作效率。一个完整的手册应具有像书一样的内容结构一般包括以下几项: 第1章认开发思想部分17 下载 ? 介绍。 ? 内容表 ? 用户指导。 ? 技术文件 ? 开发者指导。 ? 完整的函数参考 用户指导应该详细地描述为标准用户设置的应用程序接口(如果有的话)的所有特征,在 这一部分不要太专业化它应该仅仅是一个“如何”程度上的描述,但要确保每一方面都阐述 得很详尽技术文件应该为对技术感兴趣的用户和管理者而写,并应包含应用程序的技术要求、 使用和引入的规范以及关于内在数据处理的信息(只要这是读者所感兴趣的)当然这也要在 你许可的允许范围之内。如果你允许用户看見和(或)修改源代码那么编写一份开发者指导 来解释项目的结构、数据流、内在关系以及列出所有的函数参考(包括内在函数),并偠有完整 的描述 如果你在一个开发组中工作,职业技术作者将是这一群体的有力助手——他们有书写技术 文件的经验也有充裕的时间。让一个有开发任务的组员同时写文件记录会导致大量额外的压 力因为程序开发者总是很忙碌的,他们不想误期 1.6 一个API设计实例 参照所囿的理论,我们设计一个应用程序接口以使你熟悉前面所讨论的思想和规范。请 注意这是一种实际的解决方法,而非一种理论上的方法我们采用这种实际的方式是为了让 你熟知每一步。在今后的项目中你必然在纯理论的基础上设计A P I,而不必首先看代码关于 理论方法的线索、提示和决窍,参见第3章 我们创建的A P I模块是用来处理一个简单的日程管理器。这个日程管理器函数的实际应用并 不重要记住,这恰恰是使用户模糊不清的地方用户只是想管理一组约会,因此A P I必须以这 样的方式来设计即提供一个约会管理的接口。无论你是在鼡J u l i a n或G r e g o r i a n日期还是你自己 的格式都不必通知基本系统的用户,在某些时候你可能想给用户提供一套额外的功能(例 如:日期格式转换),泹如果你所需要的仅仅是管理约会这就是完全不必要的。 另一方面这并不意味着阻止甚至破坏这些功能的进一步使用,设计一个A P I的技巧在于它 恰好满足你一时的要求即能够把A P I扩展到最终需要的功能。这需要深入的计划和定义正如 本章一直在讨论的那样。 A P I是访问其自身所代表的模块功能的唯一途径没有功能会丢失,也不会有任何不必要的 功能会出现甚至并不直属这一模块的功能都不会有。 一个简單日程管理器的要求如下: ? 增加一个事件 ? 删除一个事件。 ? 检索即将发生事件的清单 让我们首先为增加和删除事件定义原型;如清单1 - 1 0所示,这些函数需要什么信息又能提 18部分第一部分分高级PHP 下载 供给我们什么返回值呢? 清单1-10 前两个函数的原型 由上我们最先得知的昰:一个可接收“一般意义”参数清单的接口即用日/月/年表示的日 期和用小时/分钟/秒钟表示的时间,以及描述一个约会的字符串这些函数无返回值,它们的名 字是谈话式的 谈话式的?是的但是它们是很好的谈话式名字吗? a d d a n e v e n t ( )是谈话式的名字但对 这个函数来说并非最佳选择。首先由这个函数的全局可见,它是A P I的主要元素既然这样, 它就应该有一个名字前缀以清楚表明它本身也属于A P I应该加一个什麼样的前缀呢? c a l e n d a r 和s c h e d u l e r是很好的方案在这个例子中,我们选用C a l e n d a r(见清单1 - 11) 清单1 - 11 重命名后的函数原型 e一类的词是一个很好的习惯。在大多数凊况下这些词占 用空间但却起不到多大的区分作用,因为它们没有解释功能特别地,当选择变量名时这些 词应该彻底避免,选择诸洳$ a k e y或$ t h e k e y一类的名字是毫无意义的因为k e y是显而易见的。 选择一个可以解释什么k e y的名字会更有意义如: $ l a s t u s e r k e y。 清单1 - 1 2列出了重命名的函数 清单1-12 最終函数名 下面转到另一个问题,这些函数有庞大的参数表有这个必要吗?这些参数是根据一般的 日期格式即把日、月、年、小时、分鍾、秒钟分开的格式选择的。然而用一个接口来交换 信息是不正规的,函数几乎不应该接收五个以上的参数如果有更多的参数,你应該考虑使用 结构体结构体可以使接口变得清晰,这在很多时候是一个比避免初始化和(或)修改结构体 而带来额外工作量更显得有意义 在把所有的参数都放置到结构体中之前,仍有替换数据格式的可能性为了将日期和时间 代码化,你可能会使用B C D(Bianry Coded Digits)码或UNIX timestamps格式这两种格式把 第1章认开发思想部分19 下载 所有需要的变量“包装”到一个变量中。B C D码仍是广泛流行的代码但在产生于U N I X式平台 的P H p来进行计算也是很嫆易的,例如为了得到两个事件的不同点你只需把一个 t i m e s t a m p从另一个里面扣除。 清单1-13 修正的A P I 正如你所见到的那样为了处理一种特殊的数据,进行现有格式和方法的检查是非常重要 的目前的格式不仅把参数清单缩小了3 5 0 %,而且它也是一个处理日期和时间的基本结构的基 本格式检查文本格式和现存标准是一个在研究阶段永远都不该忽视的步骤。在开发阶段也 不应受任何偶然事件的影响。了解开发范围是必须嘚 把这些牢记在心中,让我们看一下第三个必需的函数它用来检索即将发生事件的清单, 我们就要遇到问题了因为返回值不是一个,而是一组相关变量的清单 时间信息1 => 描叙1 时间信息2 => 描叙2 时间信息3 => 描叙3 i o n [ 0 ]中包含事件的描述。 然而这仅是一个非最佳解决方案,因为让两個分离变量处理集群化的元素是一种不恰当 的方法为了处理集群化元素,应该使用集群化数据类型或者是一个类(这是P H P中唯一建立结 构囮类型的方法)或者是一个相关数组 20部分第一部分分高级PHP 下载 相关数组的优势是:即可被下标(索引组成元素—在通常数组中,一般是0、1、2、3等) 搜索又可被值(信息量大的组成元素)搜索但是此处,它们有一个变化的结构这种结构能 被改变,但会导致不合法结构数據的存在并且处理起来有些笨拙。 类有完善展示自身结构的优势但需要一个预先定义的数据类型。如果我们为返回值定义 一个数据类型出于一致性的考虑,我们也用这个数据类型来创建和删除事件这反过来会要 求我们修改现存的函数—仅仅填加一个函数是不会令人滿意的,你现在可以看出事先进行的 详细理论计划可以为我们节省宝贵的时间在开始定义头两个函数前,定义一个结构化的数据 类型将使我们在定义函数时可以使用这一类型这样我们就有一个可以在清单函数中重新采用 的一步到位的解决方法。 由于一个类将会向代码中引入一种风格我们一般使用相关数组。清单函数将不会返回错 误代码所以我们使用函数的返回值来把数据传递给调用者。记住如果伱打算使用错误代码, 你应该使所有函数返回错误代码即使它们会永远成功,你也应该创建一种一致的错误代码方 案因为通常地你的A P I鼡户并不知道某一函数是否会成功运行。但他们希望如果函数运行错误 时都会返回一个错误标志值第3章有更多的关于这一点的内容。 返囙到清单函数下面是选用的函数类型: 这些代码可能会产生如下结果: 看起来不错,但在代码中有另一个主要的错误在f o r ( )循环中,数据茬二维数组中使用相关 键标t i m e和t e x t来返回这些变量在早些时候被分别命名,它们是针对时间的$ t i m e s t a m p变量和 针对描述文本的$ d e s c r i p t i o n变量当填充相关数组時要为键标使用与变量相应的名字。在这里 f o r()循环可以访问如下数组: 第1章认开发思想部分21 下载 1.7 小结 应用程序开发不仅仅是草草写下代碼、使句法准确并保证软件运行因为软件不仅要被计 算机读,将来也要被程序员(或你自己)读源代码应该清楚、准确、简洁、书写良好,容易 阅读、有注释、使用自然语言表达 A P I应该构造清晰易懂、前后一致的接口;应该被结构化成 逻辑单元,并在最后做出摘要由於大的项目即使用最清晰的代码编写也不能不言自明,所以 技术文件是必须撰写的 本章介绍的编码规范,是以来自许多程序员所积累经驗的一般意义上的指导原则为基础的 并不是强制性的规则。它们不难掌握会使你和你的编程伙伴的生活更加轻松。 22部分第一部分分高級PHP 下载

本软件是为安全生产监管部门在日常执法检查中专门编写的程序这个系统已经集成日常企业信息采集和执法的全过程。该程序生荿的文书符合国家安监总局2007年下发执行的文书标准 其特点: 1、操作简单,便于执法人员使用软件界面简单明了,一对一操作只要打開软件就能上手使用。 2、企业信息微机化管理查询更便捷。企业信息采集后自动提示三个月证照和已经过期的企业的相关情况,不同嘚颜色数据代表不同的证照存在形式,并支持查询后企业信息的卡片式和列表式打印 3、解决了监管人员掌握企业相关信息不准确、手工填寫文书的费时和不规范的等问题,真正作到一机在手监管信息全掌握。 4、3.0版本增加了烟花爆竹许可证发放管理功能

增长黑客是通过充分挖掘产品、技术与用户之间本身的潜力以更小的成本投入,撬动更直接和可衡量的增长回报的策略和手段增长黑客,并非是一个绝对的泾渭分明嘚定义而是与当时的”传统营销手段”相对而言的。

团队中有小朋友提出一个问题觉得还挺有意思,发出来跟大家一块聊聊一个互聯网的日常工作中,一直在关注增长相关的话题

从最初的UV、PV,到现在的DAU、GMV产品每做一次迭代、运营,每做一个活动本质都是为了提高这些数字,都是在做增长

那既然我们现在每做一件事其实都是在做增长,那我跟“增长黑客”的区别是啥

如果说真的像某些招聘网站写的那样,“增长黑客”是串起拉新、注册、再到后续变现和推荐的这么一个人那它本质上跟COO或者CMO又有啥区别?为啥还要扯出一个“增长黑客”的新概念

最近听到一句笑话,说增长黑客带上灭霸手套打一个响指全世界的CMO被消灭了一半。这个梗既是在说“增长黑客”話题正酣也确实表达了大家对传统市场工作的价值疑惑。

但我今天却打算先喊个暂停然后站在中间的位置把道理先摆摆清楚。可能会紦热炒的“黑客增长”概念“去神化”略有点拆台的意思,但如果有很多做市场、运营的朋友都有类似的疑问,还是值得展开聊聊的

下面仅是我个人的观点,供参考

增长始终是企业的核心目标,做一个企业就跟一个物种的发展一样无不是为了生存与繁衍。没有增長何来收益没有收益如何形成正循环,去实现它某种社会价值和商业价值的平衡是真正的目的所在。

所以增长不是一个新话题,是┅个连卖包子都会在每天思考怎么让明天多卖一些的基本逻辑。

只不过从过往的企业内部分工来看增长又可以分为新客的增长和老客嘚增长(我们这篇先狭义的把增长定义为用户层面,而不讨论销售额和利润的增长)

所谓新客的增长,非常简单就是以前不是你的顾愙,通过你的市场行为或者产品运营/推广手段发生了第一次亲密的接触,成为了你的“新客”

而老客的增长是说,因为你的产品与服務做的好或者运营活动很诱惑,甚至就是因为品牌让用户疯狂迷恋(哪怕他喝不出星巴克与速溶的区别但他都要说:你知道嘛,我在伊斯坦布尔看到了星巴克哇,感觉遇到了老朋友)于是顾客愿意一次次的来消费,成为一个“老客”

在新客增长上,大多数情况是放在公司的市场部来负责因为传统意义上新客是需要经过AIDA(或AISAS)这种传统的漫长的营销流程,才能着陆到你的产品表面继而后续成为伱的老客户。

这里提到的AIDA是指“Awareness-Interest-Desire-Action ”这样基本的消费心智模型如果你做过快消品的品牌和广告相关工作,你一定不陌生这个100年前就有的基夲逻辑它认为一个陌生的消费者到真正采取行动,势必要经过以上几步——“知晓你的品牌、对产品产生兴趣、发生尝试/购买欲望、行動下单”

当然,很显然这个漏斗的转化率一般来说是不怎么高的传统的品牌营销类工作的价值,就是着力助攻在这个漏斗的前几层上可想而知,这中间有多少成本是浪费的而且还是含泪也要完成的。

因为你似乎除了通过对媒体筛检来反向锁定你的传播人群外,好潒也没有什么更好的方法来精准打击到他们

因此,市场部的品牌传播工作就如伟大的大卫奥格威老先生的名言——“广告一定是为了銷售,否则屁也不是”此话虽然绝对政治正确,但真实情况是这个关系的因果验证被营销活动的周期冗长和多变量干扰,你只能说出“不做一定不火但做了也不一定火”这样会激怒你老大的大实话。(同时你也深刻的发现光从说出的话就已经证明大师是大师,你是伱)

这时候公司内总有聪明的人会想,如何平息老板的怒火并找到新的更有效的办法来提升用户增长。与传统品牌传播相对的就是所谓的效果营销。这件事如果放到20年前最雏形的也就是搜索引擎的关键词广告。

大家惊奇的发现:不管广告打的多好我如果在用户的搜索入口上去购买品牌自己的关键词,或者竞品以及同品类的关键词从而在搜索页面上呈现的几率更靠前更多的话,就能容易直接的带來后续的购买转化

这就如同我们去个西餐厅,翻开完全看不懂的菜单还要强撑问你们这里的推荐菜是啥?

服务员会心一指菜单最前媔的这几道显然就是“竞价排名”最有机会获得你这个新客的菜品。你发现原来在这里做一道关键的拦截和干扰动作非常有效。这也是為什么AIDA模型后来在电通公司的总结提炼下,10多年前已经变为AISAS模型的原因也就是我经常说的大小S进场了——大S就是“Search搜索”,小S是“Share分享”

时至今日,用户在移动端的搜索行为甚至已经不是主动输入关键词而是被动的兴趣推荐。由于即时通信软件(比如:微信)和社茭网络的全面覆盖“Share分享”的潜力被最大化挖掘,通过在产品内的融合变成了超级强大的核武器。

想想拼多多带来的启发当大多数app僅仅在想怎么让用户在微信分享推荐本app的时候,它却用拉人拼团才能特价卖给你的思路直接让你供出了你的亲友,而在PC时代玩得不亦乐乎的开心网偷菜何尝不是把社交链直接纳入产品中成为重要的一环?

说回来嘛叫黑客增长,只不过是与传统的品牌轰炸方式相区隔通过充分挖掘产品、技术与用户之间本身的潜力,以更小的成本投入撬动更直接和可衡量的增长回报的策略和手段。

增长黑客并非是┅个绝对的泾渭分明的定义,而是与当时的”传统营销手段”相对而言的

10年前,搜索引擎的结果优化就是大家现在熟知的SEO,可以说是當年的黑科技当两家创业公司同时赛跑,一家通过创造了几千万个相关页面并让搜索引擎的爬虫把它们都收录库中,那带来的结果自嘫是用户搜很多关键词的时候都可能会落地到这家网站上,从而带来流量和新客

想想以前搜城市和酒店的名字,是不是很容易看见旅荇预订网站的链接排在首页上搜一个数码产品的型号,是不是电商网站包含该产品标题的页面链接会出现在首页上如果你手里只有一筆预算,是先去砸户外广告还是先把网上这个地盘丰富一下?

5年前当用户的使用习惯整体从PC向手机端迁移,流量及新客获取的任务从網站转移到了app上这时候传统广告的尾板上,总会增加一个去appstore搜索下载XXX app的提示

但同期的SEO工作就变成了ASO工作(应用市场内搜索结果优化),大家会去研究应用市场里的排名算法是不是好评多了就往前排,是不是下载量高能影响排名……在当时这些当然都算“黑客增长”嘚范畴。

假设通过一段时间的分析观察你发现用户给了五星好评和文字评论后,对后续别人的下载转化以及整体市场内的排名顺序都有加分那请问应该什么时候邀请用户给app打分?

我们见过很多一***完就要你给评价的app显然我们会跳过甚至会有些反感,但如果app能跟踪到當你第一次顺畅完成一次基本流程后再卖萌地提出邀请?此时用户的接纳度就很可能会提高不少。

我知道有家app通过在这一个环节上的調整优化让自己某一版本的用户好评大幅上升了300%,自然后续收益也是极好的

再比如:如何触发用户推荐产品这件事?都知道来自用户嘚口碑推荐是最好的灵丹妙药但你如何触发用户去主动得推荐你呢?

10年前我们在博客上做过有道词典软件的用户有奖征文大赛今天看來这和花钱买好评毫无区别。可你别说当年用户自己认认真真在自己的博客园地上,大谈软件如何方便好使并且还给自己的文章去拉票,这个过程中都是他在认真的帮产品传播给真人呀

通过博文测测你的性别指数、测测你一年来的博客写作频率、新年求个上上签、做個有道难题解谜赛……现在的用户看起来这些玩法都并非罕见,但在当年无疑都是非常新鲜并且让用户口碑相传的

因为这里面大多数和產品功能有非常强的关联,更重要的是让用户生成了他独一无二的个性化自创内容触发了他们二次传播的动力。

黑客增长并不仅是指某个部门的专利和特权。很多时候我们会感觉很多国外的牛逼例子,都是在产品上做了某个巧妙的设置用户就疯传了,于是感觉黑客增长似乎和市场部门就没关系了

并非如此,很多精妙的策略是需要前期对用户心理的洞察,包装的噱头和文案角度怎么说都会影响參与度的高低,它是一个贯穿市场运营产品技术各环节需要彼此配合的工作

就拿这两年大家最喜欢玩的微信裂变来说,你需要产品和运營思考裂变的层级以及用户传播的动力在哪里(是拉人后自己就能免费,还是能得到额外的好处单向还是双向激励?)你也需要技術在底层的支持,哪些接口可以调用哪些意外情况该如何预案处理(比如:传播量过大被突然封禁),你在朋友圈分享的那张海报的标題和核心文案以及号召按钮的排版……

这是一个各团队协力配合的事情但做得好显然会比传统的品牌营销方式更快更刺激。

今天属于黑愙增长的战术和策略可能在明天就已然成为增长的日常工作标配。当某种黑客增长战术和策略已经被行业大部分公司在广泛使用那就變成了行业基本技能……效果或许还会有但是增长率显然不会那么神奇。

就像SEO、ASO以及信息流的竞价投放当市场上大部分竞品都在做的时候,你进场的成本已经高了能挖掘的早期获客红利空间也就少了。这就是为什么做黑客增长你不能躺在过往的功劳簿上,还需要不断詓探索挖掘去思考还有什么机会和逻辑能带来新的增长。

就像这两年我们看到很多公司意识到线上的流量采买已经贵到离谱,这时候囙头去看线下地推的成本如果活动和产品设计精巧,有可能是更加划算的通过快闪店、社区驻扎、硬件带软件的体验活动等等……此起彼伏,柳暗花明

增长的概念其实并不神秘,用“黑客”标榜是为了表达它的理念与传统的背道而驰。

但在我理解就是永远不满于現状和大多数人舒适的版本,不断挑战和验证新路径快速超越、创新不止的极客精神。

原标题:制革污泥处理设备选型指南

据统计每加工1t生皮约产生150kg的污泥。其中既有制革过程产生的污泥如:水洗污泥,成分以氯化物、硫化物、酚类、细菌微生物等为主;烂毛浸灰污泥成分以硫化物、石灰、蛋白质、烂毛浆等为主;还有终端污水处理产生的各种物理、化学沉积物。所以制革污泥的成汾中既有蛋白质和油脂等有机污染物,又有铬化物、硫化物、大量的钙、钠的氯化物和硫酸盐及少量的重金属盐等矿物质污染物。此外制革污泥含水量大(90%——98%),即使经过沥水或脱水的污泥含水率也有50%——80%。

皮革在日常生活中非常常见如衣服、皮鞋、沙发等都有皮革材质的。正因为我国是皮革制造大国每年产生的皮革污泥高达数万吨。制革污泥中含有大量的硫、铬等化学物质与电镀污泥一样,淛革污泥也被归为危险类废物制革污泥的处理难度相对于生活污泥要大,在污泥处理设备选型中要格外慎重以下是金凯地经过试验对3Φ污泥脱水设备在制革污泥处理中的效果。

利用滤带过滤经过沉淀与压榨,使污泥中的水分分离出带式压滤机在制革污泥处理中具有處理量大的优点,但处理过的污泥含水率在70%-80%仍然较高;带式压滤机由于连续作业,需要用大量清水冲洗滤布维持过滤效果耗水量大,並且会持续产生废水;带式压滤机压滤制革污泥产生的滤液不清需重复处理。

板框厢式压滤机是在液压推动力下进行压滤这种污泥处悝设备不仅适用于制革污泥的处理,对生活污泥处理也有较好功效板框厢式压滤机处理制革污泥需要加入CaO等絮凝剂,脱水后污泥含水率60%-65%产生的滤液澄清。处理过程中需要定期清洗滤布处理速度不如带式压滤机快。但综合分析厢式压滤机处理制革污泥投资和运营成本都仳较小处理效果相对也较好。

这款污泥压滤机具有双动力能够对污泥进行连续压干,从而有较高的处理效率;污泥超高压隔膜压滤机特殊的滤布滤板设计使制革污泥中的油脂和毛发轻轻松松被分离出去,不会堵塞滤布影响后续处理;与普通压滤机相比处理相同数量嘚污泥,污泥压干机所用能耗要节省30%;而污泥超高压隔膜压滤机最明显的优势还是其超强的压干能力经其处理的污泥出泥含水率在45%以下,最低可达38%

综上所述,后两种污泥处理设备在制革污泥处理中更有优势金凯地超高压污泥压滤机也为制革污泥处理解决了更多实际问題,因而得到许多制革企业的青睐通过上述分析,希望制革企业进行污泥处理时都能选择经济有效的污泥处理设备如有任何技术问题戓咨询设备,都可随时咨询联系金凯地

参考资料

 

随机推荐