返回介绍

写给初学者:编程的本质

发布于 2025-02-16 11:28:26 字数 2122 浏览 0 评论 0 收藏 0

俗话说,开卷有益, 前几天又翻了下《计算机程序的构造和解释》,看到一个采用牛顿法求平方根的例子,产生了点新的感想,和大家分享下。

平方根的数学定义是这样的,对于一个数 x , 如果有另外一个数 r, r 大于等于 0 ,并且 r 的平方等于 x , 那 r 就是 x 的平方根。

这个定义描述了平方根的一般性事实,但是这是一个声明性的描述,并没有告诉我们一个具体的计算过程。 假设我们要写一个程序,给定一个数 x , 怎么求得它的平方根呢?

初学者可能会觉得, 我可以写个这样的程序啊:

square_root( x ){

找到一个 r ,确保 r 的平方等于 x

返回 r

}

但是这个函数一点用都没有,只不过把原来的问题给重新描述了一遍而已。

如果有一个这样的编程语言,程序员会非常高兴: 我们可以用声明性的方式来写程序了!只需要告诉计算机说,找到一个 r ,使得 r 的平方等于输入 x 即可。

但是在当前的计算机体系下面, 这是绝对不可能的,计算机是个笨家伙,它只能按照人类的告诉他的指令一步步的工作, 它突出的优势只是运行得比较快而已。

程序员必须要告诉计算机到底该怎么做,怎么去找到那个 r, 第一步怎么做,第二步怎么做。。。。。什么时候结束。

针对于求平方根的例子, 程序员需要找到一个算法,然后把这个算法的步骤和计算过程用计算机语言描述出来,形成计算机指令。

这个计算过程大概长这个样子:

先猜测 r = 1 , 判断 r 的平方和 x 是不是非常接近(例如相差 0.0001)

如果不接近,让 r = (r+x/r) / 2, 继续判断 r 的平方 与 x 是不是非常接近

如果不接近, 继续让 r = (r+x/r)/2 。。。。。

对于 x =2 , 其计算过程如下:

很明显,这是一个逐渐逼近的过程,计算的次数越多,越逼近真正的平方根。

改写为编程语言描述:

请暂停阅读 10 秒钟, 仔细体会上述的计算过程,它和之前声明性描述有什么区别。

一个描述平方根是什么, 另外一个描述求平方根计算机具体怎么做。

无论多么复杂的程序,无论的前端之王 javascript , 还是后端的 java ,无论是面向过程的还是面向对象的,最终的做的同样的事情:把用户描述的需求(通常是声明式的)变成计算机可以理解,可以运算的步骤。

“是什么” 和 “怎么做”之间有着巨大的鸿沟,这个鸿沟就需要程序员的大脑去填补 。 求平方根是个非常单纯的例子,已经有数学家们想好了具体的计算办法, 程序员翻译一下,变成计算机语言就行。

现实中这样的好事儿是不多的, 比如说你们公司要搞个社交化的促销: 用户连续 x 天转发某个活动到朋友圈就可以获得奖品, 转发的有效时间是早上 9 点至晚上 10 点, 同一天转发多次只算一次。

在实现上你首先得记录用户什么时间转发的,然后对转发时间排个序,过滤掉那些无效的转发,计算这些用户的转发时间没有连续性, 连续的天数到了指定的数值没有。 --- 这就不存在现成的算法,程序员需要自己想出计算的步骤,然后用代码实现。

可以看出,这 不需要高深的数学知识 ,就是找到一个合适的算法和数据结构来描述它,这是编程最最基本的能力。

对于小白来说, 通过自学和培训,可能很快学会一个语言的使用, 可是基本能力不加强,早晚要吃亏的。最突出的表现是给他一个很简单的业务,他花了很长时间才写出一个漏洞百出的版本。

随着业务越来越复杂,一个领域的问题会和其他领域的问题交织纠缠在一起,让复杂度大大增加,简单的一个或几个算法和数据结构是搞不定的, 这时候必须得用一些辅助的手段才能解决,比如使用封装、分层、模式、分布式等等, 这是属于另外一个维度的设计能力了, 这种能力和编程语言都没有关系。

初学者完全可以先学会编程语言和框架,先具备工作能力,然后必须加强数据结构和算法的训练,随着经验的积累,慢慢地扩展到设计和架构层面。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文