`
TxjDsk
  • 浏览: 94346 次
  • 性别: Icon_minigender_1
  • 来自: wuhua
社区版块
存档分类
最新评论

编程:是一门艺术

阅读更多
作者:佚名
摘要: Knuth在他的多卷书《计算机编程艺术》中向我们展示了计算机编程的技巧和艺术性,并在其图灵奖演说中论述了计算机编程和艺术的关系。这篇文章受Knuth著作的启发,进一步阐述为什么计算机编程应该是一门艺术并通过代码展示艺术的主要表现形式。

图片来源:accidentally in code

  1. 引言

"(program(computers) == *art) ? so : what"
“只有大约5%的程序员能够在编写代码时创造出艺术。其他95%一定是为了取得成功的科学家,不是艺术家。”

  谈及“艺术”,人们自然会联想到“美”、“技艺”、“灵感”等词,但很少会把它和“计算机编程”这听起来似乎无趣的词联系在一起。而Donald Knuth,《计算机编程的艺术》多卷书的作者,通过他的著作,成功地展现了计算机编程的艺术。随后他又在图灵奖演说[1 ]中对计算机编程的艺术做了科学地论述和诠释。他不是第一个这么做的人,但无疑他是最成功的一个。Guido van Rossum,Python的设计者,如是说:

“我同意Knuth对‘艺术’一词的定义(或使用)。对于我来说,它和创造性联系十分紧密,而这对于我的工作非常重要。如果(计算机编程)其中没有艺术,它将没有任何乐趣,而我也不会在30年之后仍然从事它。”

  编写优美的程序需要灵感和高超的技巧,就像诗人写诗,画家作画,建筑师构筑,充满了乐趣、挑战和美。优雅的程序会像诗歌一样耐人寻味,像名画那样大开眼界,像教堂一样堂皇华丽。所以,计算机编程也同样是一门艺术,程序员就是创造这种艺术的艺术家。

  2. 编程之美

  什么样的程序才是美的程序?这个问题似乎没有完整的答案。一个很酷的Demo或一个很炫的视频游戏都能让我们赞叹不已。Doom和Half Life可以说把3D技术推向了极至,这种程序总能给人一种视觉上的美,就像画家手中的美丽油画,只是程序员们的画布在电脑屏幕上,画笔是键盘。 Linux也是一种美,一种开放的美,从Unix那里继承来的优雅的设计,强大的可移植性,丰富的工具,这让它看起来像优秀建筑师们设计的一座富丽堂皇的 教堂。这些美是显而易见的。还有一种美,隐藏在程序背后,流动于源代码之中。什么又是美的代码呢?可能它们一看上去就很美。这里有一个惊人的宏定义的C代 码集合[2 ]:允许程序建立常量,使它们看上去像是屏幕上的图形!程序的自描述能力大大加强!

#define

 X )*2+1
#define

 _ )*2
#define

 s ((((((((((((((((0 
static

 unsigned short

 stopwatch[] =
{
s _ _ _ _ _ X X X X X _ _ _ X X _ ,
s _ _ _ X X X X X X X X X _ X X X ,
s _ _ X X X _ _ _ _ _ X X X _ X X ,
s _ X X _ _ _ _ _ _ _ _ _ X X _ _ ,
s _ X X _ _ _ _ _ _ _ _ _ X X _ _ ,
s X X _ _ _ _ _ _ _ _ _ _ _ X X _ ,
s X X _ _ _ _ _ _ _ _ _ _ _ X X _ ,
s X X _ X X X X X _ _ _ _ _ X X _ ,
s X X _ _ _ _ _ X _ _ _ _ _ X X _ ,
s X X _ _ _ _ _ X _ _ _ _ _ X X _ ,
s _ X X _ _ _ _ X _ _ _ _ X X _ _ ,
s _ X X _ _ _ _ X _ _ _ _ X X _ _ ,
s _ _ X X X _ _ _ _ _ X X X _ _ _ ,
s _ _ _ X X X X X X X X X _ _ _ _ ,
s _ _ _ _ _ X X X X X _ _ _ _ _ _ ,
s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
};

  这种只能在Usenet或混乱C代码竞赛中才能见到的代码虽然没有多少实际用处,但它的确能让我们感受到代码 —— 一堆有规则的符号 —— 也能创造出视觉上的美。也可能是程序使用的技巧 —— 算法很美,就像汉诺塔程序,快速排序程序,自然而然地使用递归让它们看起来很紧凑,易读,这当然也是一种美,是只有程序员才能体会到的美。还有一种美,深 藏在代码之后,是程序的设计思想之美,一种需要领悟的美。Unix带给我们的不仅是它的强大功能,还有它那深邃的设计哲学[3 ]:

“小巧就是美的。”(Small is beautiful.)
“让每个程序都擅长做一件事。”(Make each program do one thing well. )
“一切都是文件。”(Everything is a file.)
“沉默是金。”(Silence is golden.)
“让操作系统内核小而轻巧。”(Make operating system kernels small and lightweight.)

  这些思想在Unix设计中不失为黄金法则。这种美将穿越时空,千古流传,让Unix不仅仅是一个优秀的操作系统,而成为一门计算机领域的哲学。

  人们都喜欢美的东西,程序员们更是珍视美的程序,我们把那些创造美好程序的人尊称为“黑客”。 Paul Graham认为黑客和画家很相似[4 ]:

黑客和画家的共同之处是,他们都是创造者。和作曲家,建筑师,作家一样,黑客和画家尝试去做的也是创造好的东西。他们本身并不做研究,但是如果在创造好东西的过程中发现了一些新的技术,那就更好了。

  好的画家是艺术家,那么好的程序员——黑客——也是艺术家。这也就不难理解为什么很多Unix内核黑客都留着艺术家式的络腮胡了。

  3. 编程之巧

  灵巧的程序像含蓄的诗歌,需要仔细领悟,用心去体会,茅塞顿开后方能回味无穷。真乃“会当临绝顶,一览众山小”!同样是求pi,但是只有简单的四行C代码却能打印出pi的前800位的程序定会让我们大开眼界[5 ]:

int

 a=10000

,b,c=2800

,d,e,f[2801

],g;
main(){
for

(;b-c;)f[b++]=a/5

;
for

(;d=0

,g=c*2

;c-=14

,printf("

%.4d

"

,e+d/a),e=d%a)
for

(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);
}

  黑客们不会墨守陈规,他们不断地创新,寻找更巧的方法来解决同样的问题。曾经流行编写这样一种程序,它能够打印它自己的全部代码。程序员们努力寻找最短的这种程序。这虽然没多大实际用处,但是充满了挑战性,黑客们把这当作乐趣。看看下面的程序[6 ]是多么怪异。

char

 *f="

char *f= %c%s%c;main(){printf(f,34,f,34,10);} %c

"

;
main(){printf(f,34

,f,34

,10

);}

  计算机编程吸引人的很大一部分在于它需要高超的技巧,也正是这些技巧才使我们看到了美,从中得到了乐趣。而且,我发现,当限制增加时,技巧将会 更高,乐趣也会随之增加。来写这样一段程序,让它在屏幕上打印1~1000之间的数字。这对于一个新手来说也是小菜一碟,一个for 循环就搞定。好,我们加一个限制,不许使用任何循环。这时你得动一番脑筋了,不过你还是会想到用递归可以完成。不错,我们再加一个限制,也不许用递归。这 可能把你难住了,你可能会认为不可能有这样的程序,那看看下面的程序吧:

#include <stdio.h>
#define

 A(x) x;x;x;x;x;x;x;x;x;x;
int

 main (void

)
{
int

 n = 1

;
A(A(A(printf ("

%d 

"

, n++))));
return

 0

;
}

  既没有用循环,也没有用递归,而是使用了宏!我们常常惊讶于世界各地著名的Warez组织推出的64k的3D动画,那么小的程序,往往有难以想 象的效果。它们把64k的限制和汇编的威力运用到了极限,这种技术让人叹为观止。64k似乎并没有限制住其艺术性,反而起了促进作用。并且,当你对系统有 足够的了解时,乐趣将会更多。因为你可以使用技巧和系统开玩笑了,欺骗它,作弄它,甚至攻击它。看下面的程序:

void

 main() {
int

 x;
x = 0

;
x = 1

;
printf("

%dn

"

,x);
}

  想一想,如何才能让程序跳过“x=1;”这一句而在屏幕上打印0?如果你对系统堆栈了解的话,你可能会给出类似下面的程序[7 ]:

void

 function(int

 a, int

 b, int

 c) {
char

 buffer1[5

];
char

 buffer2[10

];
int

 *ret;
 
ret = buffer1 + 12

;
(*ret) += 8

;
}
 
void

 main() {
int

 x;
 
x = 0

;
function(1

,2

,3

);
x = 1

;
printf("

%dn

"

,x);
}

  它利用了调用函数时堆栈的变化,改变函数的返回地址,跳过了“x=1;”这一句而直接执行下面的printf!它成功的欺骗了系统!如果把返回 地址改成你预先放置的一段代码的首地址,那么你将会劫持系统,让它运行你的那段代码。如果那段代码足够巧,你将能获得系统的完全控制权!这也是缓冲区溢出 的基本原理。我想,这种技巧将会让你兴奋不已,丝毫不亚于陶醉在自己诗里的诗人。我们已经看到:巧妙产生美,并与之形成艺术的雏形。

  4. 编程之乐

  计算机给人的乐趣在于,如果你有什么好的想法,你可以马上实验去得到结果。当然,你可能不会立刻得到正确答案,而必须坐下来,盯着电脑屏幕,苦 思冥想求解问题的有效方法,通过不断的尝试去验证你的结果。可以通过找到正确的方法,使问题突然消失,也可以换一个角度,突然灵光闪现:原来是这样!

  编程是对创造力的训练,好的程序员不会循规蹈矩,不会使用平庸的方法去解决问题,而是根据自己的见解去寻找更简单的方法,因为他们能看到隐藏在 问题背后的实质。然后他们会写出全新而漂亮的程序去验证他们的方法。“不过还是很难说清楚,闭门苦思冥想地要找到解决某个问题的漂亮答案,为什么竟会有如 此巨大的魅力。但是,你要是曾经有过找到更好方法的经历,你就会明白,这简直是无以伦比的感觉。”[8 ]这种感觉能让我们快乐得像一个孩子,乐不知疲。

  这种“无以伦比”的感觉,流动在程序员体内,让程序员们为之痴迷,疯狂。而痴迷的程序员从他艺术性的创造中得到了难以言传的乐趣,并让为之上瘾。 Linux之父在他的传记[8 ]中这样谈及他所体会的编程的乐趣:

编程给人带来最初的兴奋很好解释:那就是通过编程你可以支配一台计算机,你叫计算机做什么,它就做什么,永远准确无误,而且毫无怨言。这本身就很有意思。

它比下棋之类的游戏更有乐趣得多,因为它可以由你自己来制定游戏规则。而你制定什么样的规则,也就会导出与此规则相符合的结果。

在电脑世界中,你就是创世者,你对所发生的一切拥有最终的控制。如果你功力深厚,你可以是上帝——在一个较小的层面上。

  无疑,乐在其中,外行人永远体会不到,毕竟“子非鱼安知鱼之乐”。无穷无尽的乐趣让程序员们模糊地体会到了作为艺术家的快乐,并且开始享受他们的工作。

  5. 结论

  Rob Pike曾悲观地叹息:“那种艺术消失了。”[9 ]但是,我想当他看到诸如《汇编语言的艺术》和《Unix编程艺术》之类的书时,他也会高兴。这种艺术并没有消失,而且还会流传下去。我们不应该因“为艺术而艺术”而感到不好意思。正如Knuth所言[1 ]:

“我们已经看到,计算机编程是一门艺术,因为它把积累的知识应用于世界,因为它需要技巧和灵巧,尤其是因为它创造出了美的目标。模糊地意识到自己是一个艺术家的程序员将会享受他所做的工作,而且将会把它做得更好。”

  或许,我们应该为了“艺术”的圣杯,举起我们的双刃剑打斗一番。但是,比起剑来,我更喜欢犁头,我本人。

  6. 致谢

  特别感谢王亚刚老师,他能不厌其烦地阅读此文并给我提出宝贵的意见,没有他的指点我不可能完成这篇论文。

  参考文献

   [1]DonaldE. Knuth, Programming As An Art , ACM Turing Award lecture,1974.
   [2]Peter van der Liden, Expert C Programming ,Prentice Hall, 1994.
   [3]Mike Gancarz, Linux and the UnixPhilosophy , Digital Press, 2003.
   [4]Paul Graham, Hackersand Painters , O'Reilly, 2004.
   [5]International Obfuscated CCode Contest, http://www.ioccc.org.
   [6]Eric S. Raymond, JargonFile , http://catb.org/jargon/html/index.html.
   [7]Aleph One,Smashing The Stack For Fun And Profit ,http://insecure.org/stf/smashstack.html.
   [8]Linus Torvalds andDavid Diamond, Just for fun , Harper Business, 2001.
   [9]RobPike,
  SystemsSoftware Research Is Irrelevant ,http://herpolhode.com/rob/utah2000.pdf, 2000.

分享到:
评论

相关推荐

    电力日负荷曲线预测程序和数据集(预测未来一天的负荷曲线)

    电力日负荷曲线预测程序和数据集(预测未来一天的负荷曲线)

    勾正科技向新而生智赢未来-2024年H1中国家庭智能大屏行业发展白皮书83页.pdf

    勾正科技向新而生智赢未来-2024年H1中国家庭智能大屏行业发展白皮书83页.pdf

    成绩分析问题-总文件压缩包(代码+所有磁盘文件)

    题目2.2(成绩分析问题):设计并实现一个成绩分析系统,们能够实现录入、保存一个班级学生多门课程的成绩,并成绩进行分析等功能。

    源代码-非零坊ASP友情链接 v5.0.zip

    更多毕业设计https://cv2022.blog.csdn.net/article/details/124463185

    java-springboot+vue应急救援物资管理系统源码.zip

    系统选用B/S模式,后端应用springboot框架,前端应用vue框架, MySQL为后台数据库。 本系统基于java设计的各项功能,数据库服务器端采用了Mysql作为后台数据库,使Web与数据库紧密联系起来。 在设计过程中,充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。

    鸿蒙应用开发领域中DevEco Studio的安装、使用技巧及性能分析工具详细介绍

    内容概要:本文主要介绍了鸿蒙原生应用开发过程中可能遇到的内存问题以及相应的解决方案。针对这些问题,华为提供的 DevEco Studio 包含了性能分析工具 DevEco Profiler,提供两种场景化的分析模板——Snapshot Insight 和 Allocation Insight,支持实时监控、ArkTS 和 Native 内存的深度分析。这使得开发者能够有效识别、定界定位并优化内存问题,大幅提升应用的稳定性和性能。此外,文章还介绍了 DevEco Studio 强大的模拟器功能,该模拟器能仿真各类设备及场景,包括GPS定位、导航和低电量管理,极大提高了开发效率和测试灵活性。最后,文中详细列出了常见的快捷键,并给出了保持 DevEco Studio 与 Android Studio 快捷键同步的方法。 适合人群:专注于鸿蒙生态系统内的应用开发的技术人员,特别是有一定经验的中级至高级程序员。 使用场景及目标:本文旨在帮助开发者更好地理解和掌握 DevEco Studio 的强大工具链,尤其是解决开发过程中经常遇见的内存管理和多设备兼容问题,目标是优化开发流程,减少调测时间,增强产品的质量和用户体验。 阅读建议:开发者可通过鸿蒙官方提供的资源链接下载最新版本的 DevEco Studio 并探索相关技术博客,以获得最新的技术和使用技巧。建议在实践中逐步熟悉各个功能模块,并积极利用性能分析工具和模拟器来解决现实中的问题。

    我是谁啊我耽误 的耽误是

    我是谁

    精美导航引导页HTML源码 自适应手机/电脑,无后台

    精美导航引导页HTML源码,自适应手机/电脑,无后台,上传网站根目录就能用,首页内容在index里面修改 可以双页切换,亲测可用,搭建简单,附带修改教程

    hap手机软件包测试用

    hap手机软件包测试,测试使用

    电气工程领域的Altium Designer电子线路CAD训练-从基础入门到PCB设计实践

    内容概要:本文档是一份针对自动化专业的《电子线路CAD训练》实习报告,详细介绍了通过使用Altium Designer冬春软件进行电子线路的原理图设计、元件库文件设计、PCB板设计及元件封装库设计的过程。文档首先概述了训练的目的和重要性,随后逐步讲解Altium Designer Winter的安装与配置,然后重点展示了具体元件的设计细节,如温度传感器、AD输入通道、四双向模拟开关等的实际应用。此外,还详细阐述了自动布线和手动布线的具体步骤与注意事项,最后通过对此次实习的回顾,强调了本次训练对于提升电路设计能力和后续学习的支持。 适用人群:本报告适用于正在学习自动化及相关专业的在校大学生或从事电气工程领域的工程师和技术人员。 使用场景及目标:旨在帮助读者深入了解电子线路CAD的基础理论知识及其实际应用场景,特别是在Altium Designer环境下的操作流程。目标在于强化学生或技术人员的专业技能,以便他们能够在未来的工作或研究中有更强的设计能力。同时,该报告也可作为相关课程的教学材料。 其他说明:附录部分提供了完整的电路原理图和详细的元器件列表,供读者进一步理解和参照练习。

    2019年 金融网点分县统计数据.zip

    “2019年金融网点分县统计数据”提供了中国县域金融机构布局的详细信息,覆盖国有大型商业银行、股份制商业银行、城市商业银行及农村商业银行的网点分布特征。截至2019年底,全国银行网点总量为197,719个,其中县域地区分布87,003个,占比44%;市区网点110,716个,占比56%。 从银行类型看,国有大型商业银行县域网点数量最多(46,481个),但分布不均,如交通银行县域网点仅占9.01%,而邮政储蓄银行县域覆盖率高达59%。股份制商业银行县域网点仅占10%,主要集中于华东地区(73%)。农村商业银行县域网点占比60%(34,525个),华北和华中地区占其总量的53%。 区域分布上,华中地区县域网点占比最高(57.66%),其次是华东(34%)和西南(46%);华南地区县域网点最少,仅占7%。国有大行在华东地区县域网点占比32%,农村商业银行则集中在华北(32%)和华中(21%)。 该数据为研究金融资源城乡配置、普惠金融发展及区域经济差异提供了基础支撑。例如,国有大行2019年县域网点数量较前一年增加,反映其下沉服务趋势;而农村金融机构通过人缘地缘优势持续优化县域服务。数据格式包含分银行、分地区的统计表格,适用于量化分析金融网络覆盖与经济社会发展的关联性。

    GFP-ATOMIC参数的含义

    GFP-ATOMIC参数的含义

    ollama国内源,bash使用

    ollama国内源,bash使用

    电动汽车制造商迁移至Snowflake的数据平台现代化解决方案与实操

    内容概要:本文详细介绍了一家电动汽车(EV)制造商面临的数据处理挑战以及为解决这些问题所采取的举措——将现有数据平台迁移到Snowflake云平台上。文中阐述了制造商目前遇到的问题,如查询速度慢、运营成本高、难以整合结构化及非结构化的数据来源,并提出了具体的改进方向和技术细节。为了帮助潜在技术人员更好地理解和准备相关技术测试,还提供了一个详细的步骤指南来构建数据管道。具体要求分为两大部分:一是在当前架构上进行操作演示,二是利用Snowflake完成未来状态架构搭建并做技术示范,同时提供了预期产出物列表、所需技能概述及观众构成等关键信息。 适用人群:对于想要深入理解数据仓库迁移流程及其技术实施的专业人士非常有价值,特别适合作为数据工程师、数据科学家和其他IT专业人士参与面试的技术评估资料。 使用场景及目标:旨在展示候选人在构建现代数据工程基础设施方面的技术和创新能力。此外还可以作为内部培训材料供团队成员提高技能,或者为计划类似转型项目的企业决策层提供借鉴参考,从而优化其自身的数据管理策略和架构规划。 其他说明:演示时间被安排为60分钟,其中包括用例讲解(5分钟)、架构讨论(10分钟

    自动封装javaBean的工具类

    自动封装javaBean的工具类

    源代码-飞翔非主流ASP爬虫伪静态缓存版 v2.0.zip

    更多毕业设计https://cv2022.blog.csdn.net/article/details/124463185

    源代码-简洁快速趣味的开源ASP论坛 GBABOOK BBS v1.01 for SQL Server.zip

    更多毕业设计https://cv2022.blog.csdn.net/article/details/124463185

    wireshark log for ethercat io

    wireshark log for ethercat io

    TM1629A 驱动程序和数据手册.rar

    TM1629A 驱动程序和数据手册.rar

    Java-SpringBoot+vue的婚恋交流和信息管理系统毕业设计源码.zip

    系统选用B/S模式,后端应用springboot框架,前端应用vue框架, MySQL为后台数据库。 本系统基于java设计的各项功能,数据库服务器端采用了Mysql作为后台数据库,使Web与数据库紧密联系起来。 在设计过程中,充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。

Global site tag (gtag.js) - Google Analytics