热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

经典翻译:黑客与画家

我读完计算机本科以后,去艺术学校学习绘画。许多人感到奇怪,喜欢计算机的人也会喜欢美术吗?他们大概认为编程序和画画是两种完全不同的工作,编程需要冷静,精密,和正确的方法,而画画是表达某种狂热的情感。这种印象是不对的,编程和画画有很多共同之处,实际上,在我认识的不同类型的人中间,画家和黑客是最相似的。

注:本文为经典外文的翻译。

我读完计算机本科以后,去艺术学校学习绘画。许多人感到奇怪,喜欢计算机的人也会喜欢美术吗?他们大概认为编程序和画画是两种完全不同的工作,编程需要冷静,精密,和正确的方法,而画画是表达某种狂热的情感。

这种印象是不对的,编程和画画有很多共同之处,实际上,在我认识的不同类型的人中间,画家和黑客是最相似的。

画家和黑客的相似之处在于:他们都是创造者,就好像作曲家,建筑师,以及作家一样。黑客和画家类似,他们的目的是创造某种美好的事物。尽管在创造的过程中,也许会发现新技术,但他们的根本目的并不是研究技术。

我从来都不喜欢”计算机科学”这个词,因为这种东西根本就不存在。这门学科的内容,不过是由于历史原因偶然凑合到一起的大杂烩,就好像南斯拉夫国的形成一样。一头是数学家们,他们摆弄计算机是为了得到国防部的资金赞助,中间部分,一伙人在研究仿佛是计算机自然史之类的东西--比如网络上数据流算法的行为特征等等。在另一个极端上,是黑客们,他们编写有趣的软件。对他们来说,计算机是表达的工具,如同水泥之于建筑师,颜料之于画家。这三种人凑在一块的群体,就好像是数学家,物理学家和建筑师被分到一个专业里。

有时候黑客们干的事被称为”软件工程”,这个词也是一种误会。比起建筑师来,软件设计师离工程师的距离更远。建筑师和工程师的分界并不十分精确,但却是实实在在存在的。其分界在于做什么和如何做:建筑师决定做什么,工程师考虑如何做出来。

这两件事情也不能分得太开,如果你不懂得如何做,那么你设计的时候就会陷入难局。但是编程当然不是仅仅决定如何实现某种特性那么简单,在最好的情况下,编程实际上就是设计软件的特性--往往最好的设计方式就是实现它。

说不定哪一天,”计算机科学”会分裂成几个专业,就好像南斯拉夫最终分裂成几个国家那样。这也许是件好事。尤其是这意味着我所擅长的编程,会变成独立的专业。

这些不同类型的工作绑到一个专业里,当然有利于行政管理,但是却会引起智力上的困惑。这也是我不喜欢这个名词的另一个原因。处于中间部分的那伙人所干的,和经验科学差不多,但是另外两头的人,数学家和黑客,可不太象是在干真正的科学。

数学家好像并不为这个问题发愁,他们就象数学系的同行一样,很高兴地做着理论研究,不久就忘了办公大楼的牌子写的是”计算机科学系”。但是对黑客们来说,这个牌子就很成问题。既然他们干的事被称作科学,他们就会感到好歹要象那么回事,于是大学和研究所的黑客们觉得应该写论文,而不是写优美的程序。但是不幸得很,后者才是他们真正应该干的。

论文充其量不过是一个手续。黑客写出很棒的程序,然后再做一篇论文,论文表示软件上的成绩。但是两者之间的不协调引起了问题:好的软件比起糟糕的软件来,更加不适合做论文的题材。

好的软件不适合作论文的题材。首先,论文要有独创性的,写过博士论文的都知道,要想保证你开垦的那片地是处女地,就等于说是你划出一片别人都不想要的地来。第二,论文必须言之有物。糟糕的软件使论文材料充足,你有很多事实可以描述你是如何克服那些困难的。糟糕的假设总是会产生大量问题。大部分AI 研究就是好例子。比如,你假定,以抽象概念为参量的逻辑表达式列表可以用来表示知识,那你要论证的内容可就多了。就像Ricky Ricardo说的,Lucy,这下可够你解释了。

创造美好事物的过程,常常是对已有事物的细微调整,或者是把已有概念用新方式组合起来。这种事情,恐怕不太好做研究论文吧。

那么为什么大学和研究所还要用论文来衡量黑客呢? 同样的,为什么要用标准化考试来衡量学术才能呢?为什么要用代码行数来衡量程序员的工作量呢?这些考试的好处是容易实施,而且有一点效果,因此才会引诱我们继续采用这些措施。

真正的黑客能够写出优雅的代码,但是识别这种黑客的方法,真的很不容易找到。要有好的嗅觉才可能识别出真正优秀的设计。是否真的有这种嗅觉,和是否自信有这种嗅觉,这两者之间没什么关联,即使有,也是负面的。

真正的考验是时间。经过时间的考验,好的东西会发展壮大,坏的东西会丢弃。不幸的是,需要的时间往往太长,以至超过人的寿命。Samuel Johnson说,需要一百年的时间,才能形成一个作家的真正声誉。你得等到这个作家有影响的朋友都死了,他的追随者也都死了才行。

我想黑客不得不接受名声上的不确定性,这一点上,他们和其他创造者没什么不同。实际上比较起来还要幸运一些。在编程领域,一时的流行风气虽然也有影响,但没有绘画领域那么大。

还有比别人的误解更糟的事情。更糟的危险是你可能自己误解自己。你通常在相关领域寻找灵感。如果你在计算机系,很自然地会以为,编程的本质就是实现计算机理论。我读本科的时候有一种令我很不舒服的感觉,我觉得自己应当多学一点计算机理论,可是期末考试完了不到三个礼拜,我就把那些东西全忘光了。这让我觉得自己不够尽责。

现在我认识到我那时的想法都是错误的。黑客对计算机理论的了解程度,只要达到画家对颜料化学所了解的程度就够了。你应当知道怎样计算时间和空间复杂度,知道图灵机模型。也许应当知道状态机,至少知道这个概念,如果要写语法解析或者正则表达式库的时候会用得到。画家对颜料的学问上,要记的东西比这还要多一些呢。

对我来说,灵感的源泉不是来自于那些挂着计算机招牌的地方,而是那些聚集着创造者的地方。我从绘画方面得到的灵感比我从计算机理论上得到的,要多得多。

打个比方。我上学的时候,学生在上机之前,要把整个程序先用纸笔写出来。可是我觉得这不是我写程序的方式。我喜欢坐在计算机前面写程序,根本不用纸笔。我并不先在纸上写出程序并检验其正确性,我喜欢先敲一段代码,当然好多毛病,然后慢慢敲打成型。我受到的教育告诉我,调试应当是检查输入错误的最后一关,而按照我的方式,程序基本上就是调试出来的。

好长一段时间我都感到很沮丧,念小学的时候,我捉铅笔的方式和老师教的不一样,那时我也感到同此刻一样的沮丧。如果我那会知道别的创造者-比如画家和建筑师-的做法的话,我就早该知道这种方法的名字,那就是:打草稿。我可以告诉你,他们在大学时教我的方法是错的。你应当是一边写程序一边来确定程序的走向,这和画家,作家以及建筑师的做法完全一样。

这里蕴涵着软件设计的真义,认识到这一点,就意味着程序语言应当首先要具有延展性。语言要有助于在编程中思考,而不是仅仅表达思考的结果。它应该象铅笔,而不是象钢笔。如果程序员真的象大学里教的那样写程序,那么静态类型语言就是不错的选择。但是我所知道的黑客都不是那样子编程序的。我们需要这样一种语言,我们用它来随意涂抹。而使用静态类型语言编程序的感觉,就好象手放在膝盖上,小心翼翼握着茶杯,正襟危坐着和一个严肃的老太太谈话。

谈论静态类型,以及创造者这种话题,我们除去了另外一个困扰的科学的问题: 数学嫉妒。科学界的每个人暗地里都认为数学家比自己聪明。我想数学家们自己大概也这么认为。反正科学家们总是把自己的作品弄得象数学论文一样。这对物理学倒还没什么大害,但是你要是在自然科学上走得越远,就越发现这个问题的严重性。

印上一整页的公式,看上去很让人敬畏的样子,用上希腊字母就更加不得了。这种倾向可能诱惑你去研究那些可以公式化的问题,结果是忽略了真正重要的东西。

如果黑客认同创作者的身份,像是画家和作家一样,他们就不会受此诱惑。作家和画家才不理会数学呢,根本就是不相干的事情。我认为,黑客也应当这样看。

如果大学和研究所不让黑客做自己想做的事情,他们还可以去公司,可惜,公司和大学的做法是一丘之貉。大学和研究所要求黑客当科学家,而公司要求黑客当工程师。

我也是最近才发现这问题的。Yahoo买了Viaweb之后,他们问我的意向,我一向就不喜欢商业公司,我就说我还是想编程序。进了Yahoo以后,我发现在他们那里,编程序的意思就是代码实现,和设计没关系。程序员就是代码工人,他们把产品经理的愿望,以代码形式记录下来。

看起来这是大公司的一贯的做法。这样做的目的是减低工作的偏差。只有少数程序员真正懂得设计软件,而且这些有才能的人很不容易一下子识别出来。所以与其把软件的未来寄托在少数聪明人身上,不如把软件设计让一个委员会来作,程序员只管编码实现。

如果你想赚钱,那么记住我的话,因为我讲的,正是小公司取胜的机会。大公司采取保险的做法,意图规避风险。但是试图限制这种工作效果上的震荡的时候,固然避免了最坏的可能,但也失去了最好的。这对大公司当然不是问题,大公司取胜的原因不是因为发明了伟大的产品,而是因为犯的错误比其他大公司少而已。

如果你有办法和一个大公司竞争某种产品,这个公司的产品是产品经理们设计的,那么,他们永远赶不上你。不过这样的机会很不容易找到。你很难和大公司卷入软件竞争,就好比你很难和对手在城堡里徒手搏斗一样。写一个比微软的word还要好的字处理器是可能的,但是在操作系统这个微软独占的堡垒里,他们对你根本就不屑一顾。

软件竞争只能在全新的市场中展开,因为在那里还没有谁建立起防御工事。你有可能采取大胆的策略,集合那些既做设计又做编码的人,来赢得竞争。微软最初就是这样做的,苹果,HP也莫不如此。我想任何成功的创业公司都是走的这条路。

所以,创造伟大软件的一个办法就是创业开公司。不过这里面还有两个问题。第一,开公司以后,除了编程序,你需要做好多其他事情。在Viaweb的时候,我真的希望自己能挤出四分之一的时间编程就好了。实际上我四分之三的时间都是在做很讨厌甚至很麻烦的事情。对此我深有体会,有一次当我开完董事会去补牙,坐在诊所的椅子上,我觉得简直抵得上度假了。

还有另一个问题。写有趣的软件,和写赚钱的软件,经常是没多少共同之处。设计语言是很有趣的工作,微软的第一个产品就是。但是现在没人会花钱买语言。要想赚钱就得写那种很麻烦的,没人会免费干的软件。

所有的创造者都会面临这个问题。价格是供求关系决定的,对有趣软件的需求总是比较少,而解决一般用户的平凡问题的需求,总是多一些。在高速公路边上演出,观众一定少,在庙会搭个台子演出,观众一定多。写长篇小说的收入,比不上写广告词的收入,虽然那些广告最后的归宿是垃圾箱。设计一种语言的回报一定不多,而搞定某些公司的老掉牙的数据库和web server的连接问题,回报会丰厚得多。

我认为这个难题的答案,是创造者们应当找一个养家糊口的”日常工作”。这个名词最初是惯于晚上演出的音乐家们使用的。它的意思是: 你做一个工作是为了赚钱,另一个工作是因为你喜欢。

几乎所有的创造者在他们职业生涯的早期,都有日常工作。其中最为人所知的就是画家和作家。如果能赚钱的日常工作刚好是你所喜爱的工作,那你就太幸运了。音乐家就经常在唱片店工作。正在用某种语言或者操作系统的黑客,也应当找个相近的系统管理或维护的工作。[1]

黑客应当找个日常工作糊口,业余时间做自己喜爱的程序。我的这个说法并不是独出心裁。所有的开源社区的黑客都是这样做的。我要说的是,开源社区的模型也许是正确的模型,因为这种模型被其他创造者分别独立地验证过。

一般的雇主都不太愿意雇员参与开源项目,这让我有一点惊奇。在Viaweb则相反,我们不愿意雇佣没有做过开源项目的人。面试程序员的时候,我们考虑的一个首要问题就是,他们业余时间写什么软件。你要不是真的热爱这个工作,就不可能干的出色。如果你热爱编程,就必然会有自己热爱的业余项目。[2]

黑客是创造者,不太象是科学家。黑客寻找灵感的地方,不应当是科学领域,而是其他创造者工作的领域。那么,我们从绘画上,能够得到什么启示呢?

第一件可以从绘画领域学习的,或者说可以验证的,就是怎样学习编程。绘画都是在实践中学会的,编程亦然。大部分黑客都不是因为念大学计算机课才走上编程之路的。他们13岁年纪就开始学着写程序。即使是上了大学计算机课,你真正学会编程,大多也是通过自己实际写程序。[3]

画家通常会留下一系列作品,你可以从中观察到他们在实践中学习的过程。如果你按年代顺序观察一个画家的作品,你会发现后一个作品在前一个作品基础上的提高。如果一幅画中的某样东西特别出色,你多半会在更早的作品中发现其发展成熟的轨迹。

我认为大多数创造者都是这样工作的。作家和建筑设计师也不例外。对于黑客而言,我觉得这样的做法大概比较好: 从一个大概的草稿开始起步,不断尝试采纳新的想法,做修订版,而不是连续几年埋头做一个题目。

这种工作模式是区别黑客和科学家的另一个显著标志。科学家并不通过干活来学习科学,他们通过做实验和解题来学习科学。科学家总是从完美的东西开始,也就是说他们重复前人已经做过的工作,最后达到某种高度,才开始做自己创造性的工作。而黑客呢,一开始就是做创造性的工作–当然这时候作品还不成样子。黑客从创造开始,最终达到完美。而科学家从完美开始,最终达到创造。

创造者学习的另一种方法是观摩杰作。对画家来说,美术馆是技巧的宝库。几百年来,美术馆都是画家学习和借鉴大师作品的地方,它成为传统教育方式的一个部分。观摩杰作强迫画家仔细观察那幅画是如何画成的。

作家也是如此。本杰明-富兰克林曾经总结Addison和Steel的散文的特点,并加以模仿。Raymond Chandler也是这样学写侦探小说的。

同样,黑客也是通过看优秀的程序来学习编程–不仅看它的外在表现,而且要看源码。开源软件有一个少人提及的优点就是: 你很容易从中学习编程。我学编程的时候,不得不依赖书里的例子。其中有一大堆代码是属于Unix的,但Unix也不开源。大部分人是读John Lions的书里的源代码,而这些内容是不合法的。这本写于1977年的书,直到1996年都还被禁止出版。

绘画的过程就是不断改进的过程,这是值得我们学习的另一个地方。绘画通常从草图开始,逐渐地添上细节,但又不仅仅是添上细节那么简单。有时候会发现最初的想法是错的。无数的人像作品,在x光照射之下,会发现面部轮廓修改过,嘴的位置也移动过,诸如此类。

这就是我们应当学习的榜样,编程也应当遵循同样的做法。想要假设软件的规格设计完美无缺,这显然是不切实际的。预先接受这种现实对你有好处,写程序的时候就会有所准备,随时应对可能发生的设计规格上的改变。

(大公司很难做到这一点,这又是一个小公司可以发挥优势的地方。)

现在差不多每个人都知道过早优化的危险。我认为我们也同样应当顾虑另外一个问题,就是过迟确定软件的设计规格。

好的工具可以帮助我们避免这个危险。好的语言也可以帮助你较容易地改变主意。动态类型语言就有这个优点,你用不着预先就指定数据的表现形式。不过,我认为弹性的关键之处在于,它使语言具有较高的抽象度,如果一个程序比较短,那它就比较容易修改。

这似乎听起来让人迷惑。但是伟大的作品总是精益求精。例如,达芬奇在国家美术馆画Genevra de Benci像的时候,头像后面是桧柏树丛,他仔细地描绘每一片叶子。许多画家也许认为,这些东西是衬托头像的,没人会仔细看。

达芬奇并不这样认为。他绘画的认真程度,并不取决于看画的人的认真程度如何。达芬奇和米开朗琪罗一样,都是一丝不苟。从总体看去,那些似乎看不见的细节也会变得显著。这是一丝不苟的重要之处。观众经过这幅画的时候,注意力一下子就被吸引过去,那些原本不易觉察的细节,综合在一起产生了惊人的效果,就好像一千个细微的声音唱出的和声一样。

伟大的软件对于美的追求,也需要超人的投入。当你仔细查看好软件的时候,会发现那些不为人注意的部分同样优美。我不是说我自己写的软件是伟大的,但我知道,写代码的时候,要尽量写得清晰易读。有的程序变量名取得丑陋极了,有的程序行缩进乱七八糟,读这样的代码真能让我发疯。

如果把黑客仅仅当作代码工人的话,那他会像工人挖水沟一样从一头干到另一头。但是如果把黑客当作创造者的话,我们就必须考虑灵感的因素。

编程序的过程和绘画的过程类似,也会有起有落。上新项目的时候,一天干16个小时不知道累,也有时候,无论如何都提不起兴致。

这种状况也必须考虑在内,你应对的方法不同,效果也会不一样。当你开着手动档汽车过山的时候,有时候为了防止抛锚,不得不松开离合器。松开离合器可以防止抛锚。在绘画和编程之中,有一些是关键的东西,另外一些是常规的工作,留下一些容易作的工作,等你厌倦的时候,就做这些较轻松的工作。

比如说,在编程时可以故意留一些bug,我比较喜欢找bug。这时候,黑客这个词的含义可以说恰当极了。你面临的问题总体上是有限制的,你要做的就是解决掉它。假定你的程序应该做x,结果却做了y,哪里出了问题? 你可以断定最终一定是可以解决的。这个活跟刷墙一样,是不错的调剂。

绘画不仅可以教我们如何处理自己的工作,还教我们如何协同工作。过去很多伟大的作品都是由一群人共同完成的,尽管在美术馆的标签上可能只写着一个人的名字。达芬奇在Verrocchio 的工作室当学徒时,就参与绘制<<基督受洗>>中的天使。这样的事情当时很常见。当米开朗其罗坚持要自己一人绘制西斯廷教堂屋顶的人像时,就被认为是很不得体的事情。

就我所知,画家们一起作画时,他们并不是一起画一个共同的部分,而是一个主要画家画主题人物,他的副手画背景和其他部分,绝对不会有人掺和别人正在画的东西。

我认为这种模式也适用于软件开发,不过别走得太远。如果一段代码有三四个程序员分别写过,那么没人真正对它负责。结果就会变成公用房间一样没人收拾,又冷清又灰暗。正确的做法是把程序分成严格定义的模块,每个模块有专人负责,仔细设计模块之间的接口,使之尽可能像程序语言本身那样,精确地表达出来。

软件和绘画一样,都是为人而做的。黑客也应当像画家一样,努力创作出伟大的作品。你必须为用户的立场着想。

我小时候,就听人讲要学会从别人的立场来设想。意思就是做别人想要你做的事情,而不是做你自己想做的事情。这当然给” 换位思考”这个词带来了坏名声。因此我一直不愿意这样做。

可是,我错了。换位思考确实是成功的秘密,这并不意味着放弃自我。理解别人的观点,并不是说你要按别人的兴趣办事。在某种情况下刚好相反,举个例子,打仗的时候,理解敌人观点,其目的恰好是要反其道而行之。[4]

大多数创作是为人的,你得理解人的需要。差不多所有伟大的作品主题都是人,因为人最感兴趣的,就是人类自身。

好程序员和伟大的程序员之间的唯一的差别,就是体察别人的能力。有些程序员很聪明,但论到”换位思考”,则是完全的自我主义者。这样的人不可能设计出伟大的软件[5],他们从来不懂得理解别人的观点。

判断一个人换位思考的能力如何,最好的办法是看他怎样向那些不懂技术的人讲解技术问题。我们大概都见过那样一些人,不管多么聪明,这件事情上却是糟得很。如果有人问,什么是编程语言,他们会说,呃,就是一种高级语言,能经过编译器处理产生目标码。高级语言?编译器? 目标码? 不知道编程语言的人,难道会知道这些东西?

软件的目标之一,就是解释自己。你要写出好程序,就应当知道用户对软件了解甚少。他们用软件时,全无思想准备。如果软件的行为刚好合乎他们的设想,那就最好了。别指望用户会去读操作手册。这方面,我见过的最好系统是早期的苹果,那时候还是1985年。苹果干了所有软件都做不了的事情,那就是能正常运行。[6]

源码同样也应当解释自己。如果让人回忆关于编程的名言,经常提到的是结构化和解释语言初期的一句话:

程序写出来是给人看的,碰巧机器也能运行。

你不但要为用户设身处地地着想,对读者也是一样,因为读者可能就是你自己。好多程序员写了程序,过半年再看,简直看不懂究竟是怎么回事。我就见过有几个人因为这原因放弃了perl。[7]

缺乏换位思考的能力仿佛是高智商的特征,尤其在某些地方,这都成了一种风尚。但我不觉得真的有什么关联。数学和自然科学和人类感情无关,这些领域的人显然都很聪明,于是乎高智商就和”不通世故人情”挂起构来。事实上好多平常智商的人在这方面也不行。看看脱口秀节目里那些站起来发问的人,那些问题问的,真叫拐弯抹角,主持人得重新梳理一遍,才能搞得清是啥意思。

如果编程和绘画写作一样的话,它也一样酷吗? 毕竟,人只有一次生命,最好是做有意义的事情。

这问题真难回答。在赢得名气上总是有很大的滞后。这就好像遥远的星星发出的亮光,要经过好多年才能到达我们眼里。绘画行业光芒四射是因为500年前就产生的杰作。那时候,没人会象我们现在这样看重这些作品。我们现在所知的Urbino公爵Federico daMontafeltro先生的形象,是从Piero della Francesca的作品里的高鼻子男人哪里得来的。这在当时的人眼里看来,一定是非常奇特的。

所以当我说编程没有绘画那么酷的时候,我们应当记住绘画在它古老的光辉年代,同样也不见得那么酷。

我们可以自信地说,现在正是黑客事业的光辉年代,在大部分领域,伟大的作品诞生很早。1430-1500年代的绘画现在仍难以超越,莎士比亚彷佛生来就是戏剧家,把这门艺术推进到如此之高的程度,以致于后来的剧作家都生活在他的阴影里。Albrecht Durer之于雕刻,奥斯丁之于小说,也是如此。

一次又一次,我们看到同样的模式。新的媒体诞生了,人们热情高涨,短短几代人就把它的能量发挥到极至。黑客事业似乎也正处于这样的时期。

达芬奇时代的绘画行业并不酷,是他的杰作造就了绘画行业的酷。黑客事业之未来,全依赖我们今日之创造。

作者注:

[1] 照相术的出现,毁掉了画家的日常工作。历史上很多画家靠替人画像维持生计。

[2] 我听说微软不鼓励员工从事开源项目,业余搞也不行。不过现在有那么多黑客都在做开源项目,这种政策也许会令他们难以招募到很多一流程序员。

[3] 大学所能学到的编程技术,其状况相当于你学到的关于读书,打扮或者约会的知识: 你上高中那时候的品味多差啊。

[4] 这里有一个”换位思考”的例子。在Viaweb的时候,如果在两个选择之间下不了决心,我们就会问: 我们的对手最恨什么? 当一个对手在软件里加了个没用的特性,这个特性我们没有,他们就在媒体上大作文章。我们当然也可以解释说这个特性根本是废物,但是我们还是决定也实现它,因为这样的话,对手会更生气。于是当天下午我们就加上了这个特性。

[5] 不包括文本编辑器和编译器。因为这两样东西黑客自己也天天用,自己就是典型用户,所以用不着了解别人的观点。

[6] 差不多如此。他们在内存使用上弄巧成拙,产生好多很麻烦的磁盘交换。几个月后,我买了个新驱动器加上,这问题就解决了。

[7] 给程序加注释,并不是增加易读性的好办法。我把Abelson和Sussman的话再发挥一下:程序语言是用来表达算法的,碰巧也能在机器上运行。好的编程语言,表达软件的能力比英语更好。只有在代码含义复杂难解的地方,才有必要加注释,就好像高速公路上急转弯的地方才会有警告标志。

感谢Trevor Blackwell,Robert Morris,Dan Giffin,和Lisa Randall阅读本文的草稿,感谢Henry Leitner和Larry Finkelstei邀请我讲话。

本文地址:http://www.nowamagic.net/librarys/veda/detail/1263,欢迎访问原出处。


推荐阅读
  • 软件测试行业深度解析:迈向高薪的必经之路
    本文深入探讨了软件测试行业的发展现状及未来趋势,旨在帮助有志于在该领域取得高薪的技术人员明确职业方向和发展路径。 ... [详细]
  • 本文总结了一次针对大厂Java研发岗位的面试经历,探讨了面试中常见的问题及其背后的原因,并分享了一些实用的面试准备资料。 ... [详细]
  • QQ推出新功能:个性化QID身份卡
    您是否还记得曾经风靡一时的即时通讯工具QQ?近日,QQ悄然上线了一项新功能——QID身份卡。这项功能将如何改变用户的社交体验?本文为您详细解读。 ... [详细]
  • protobuf 使用心得:解析与编码陷阱
    本文记录了一次在广告系统中使用protobuf进行数据交换时遇到的问题及其解决过程。通过这次经历,我们将探讨protobuf的特性和编码机制,帮助开发者避免类似的陷阱。 ... [详细]
  • Bootstrap Paginator 分页插件详解与应用
    本文深入探讨了Bootstrap Paginator这款流行的JavaScript分页插件,提供了详细的使用指南和示例代码,旨在帮助开发者更好地理解和利用该工具进行高效的数据展示。 ... [详细]
  • 实践指南:使用Express、Create React App与MongoDB搭建React开发环境
    本文详细介绍了如何利用Express、Create React App和MongoDB构建一个高效的React应用开发环境,旨在为开发者提供一套完整的解决方案,包括环境搭建、数据模拟及前后端交互。 ... [详细]
  • 本文详细介绍了在 Python 中如何有效去除浮点数末尾的无意义零及不必要的点,提供多种实现方法,并深入探讨了浮点数在计算机中的表示方式及其可能带来的精度问题。 ... [详细]
  • 1、什么是过滤器管道使用竖线(|)将两个命令隔开,竖线左边命令的输出就会作为竖线右边命令的输入。连续使用竖线表示第一个命令的输出会作为第二个命令的输入,第二个命令的输出又会作为第三个命令的输入, ... [详细]
  • 使用 Vue3 Script Setup 语法糖构建双人联机俄罗斯方块
    作为一名前端开发者,Vue3 是一个不可或缺的工具。本文通过一个实战项目——双人联机俄罗斯方块,详细介绍如何利用 Vue3 的 Script Setup 语法糖进行开发,帮助读者掌握最新的前端技术。 ... [详细]
  • 基于MATLAB的TDOA定位:Chan算法与Taylor算法对比仿真
    本文通过MATLAB仿真,详细比较了TDOA定位中的Chan算法和Taylor算法的性能,探讨了不同雷达测距误差下的定位精度。 ... [详细]
  • 本打算教一步步实现koa-router,因为要解释的太多了,所以先简化成mini版本,从实现部分功能到阅读源码,希望能让你好理解一些。希望你之前有读过koa源码,没有的话,给你链接 ... [详细]
  • 整理于2020年10月下旬:总结过去,展望未来Itistoughtodayandtomorrowwillbetougher.butthedayaftertomorrowisbeau ... [详细]
  • 本文将深入探讨C语言代码的可重用性,解释其重要性和实现方法。通过具体示例,我们将展示如何通过封装和模块化设计提高代码的可重用性。 ... [详细]
  • 本文探讨了数据结构与算法之间的关系,从基本概念入手,逐步解析二者如何相辅相成,共同构建高效的计算机程序。文中结合实际案例,对数据结构和算法进行了详细说明,并提出了一些思考问题。 ... [详细]
  • 本文介绍了在Java中遍历HashMap的三种常见方法:使用entrySet()、keySet()以及Java 8引入的forEach。每种方法都有其特点和适用场景。 ... [详细]
author-avatar
一坛苦水_179
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有