编程的异想世界

现在网络上的编程课程一浪接着一浪,什么少儿编程,成人编程,AI编程,层出不穷。

比如朋友圈火过一阵的Python编程,好像不学点Python都不要意思在职场混。虽然现在都喜欢打着Python的旗号来吸引大家学编程,但是笔者想表达一个观点:

编程不仅仅是学习一门编程语言

可以从编程的发展来论证这个观点,说到编程,就要讲到计算机。

编程与计算机

计算机的产生是用来解决数学问题,数学问题可以是逻辑问题也可以是计算问题。

最早的电子计算机用于弹道计算。现在对电子计算机的定义是:利用数字电子技术,根据一系列指令指示并且自动执行任意算术或逻辑操作串行的设备。这个定义通俗的讲,就是可以运来解决一些数学问题,比如求解二元一次方程,或者逻辑问题,比如你妈和你女朋友同时落水,你会先救哪一个。

电子计算机有四个主要部分:算术逻辑单元、控制电路、存储器和输入输出设备。目前算术逻辑单元和控制电路被集成到了一块电路上,就是CPU。CPU就是计算机实际执行指令的地方,计算机的运行过程大致可以描绘成先从存储器中获取指令和数据,然后执行指令,存储数据,再获取下一条指令。这个过程被反复执行,直至得到一个终止指令。

指令如同数据一样在计算机内部是以二进制来表示的,比如说,10110000就是一条Intel x86系列微处理器的拷贝指令代码。我们把一连串的指令叫做程序。

为了使计算机能够理解人的意图,我们就必须将需解决的问题的思路、方法和手段通过计算机能够理解的形式告诉计算机,使得计算机能够根据人的指令一步一步去工作,完成某种特定的任务。这种人和计算体系之间交流的过程就是编程。

编程就是编写完成某个特定任务的一连串指令。

现在我们使用的手机、笔记本、平板其实都是电子计算机,都拥有前面讲的4个部分。

编程与编程语言

计算机能理解的语言叫做机器语言,也叫指令。这些指令是以二进制表示的,我们识别和操作比较困难,所以一开始发明了汇编语言,把二进制的指令变成一些助记符,利用这些助记符来进行指令的编写。比如我们编写一个输入两个数,输出两个数相加结果的程序,我们先使用汇编语言来进行编写:

data1 segment
    var db 6,0,6 dup(0),'$'
    da1 db 2 dup(0),0ah,0dh,'$'
    da2 db 2 dup(0),0ah,0dh,'$'
    str1 db 'please input two variable!',0ah,0dh,'$'
data1 ends

code1 segment
    assume ds:data1,cs:code1
    start:
            mov ax,data1; 初始化
            mov ds,ax
            mov dx,offset var; 输入相加的数
            mov ah,0ah
            int 21h

            mov si,2    ;把第一个数移动到大da1
            mov cx,2
            lea di,da1
    loopda1:mov bl,byte ptr var[si]
            mov byte ptr [di],bl
            inc si
            inc di
            loopnz loopda1

            inc si
            mov cx,2
            lea di,da2
    loopda2:mov bl,byte ptr var[si]
            mov byte ptr [di],bl
           inc di
           inc si
           loopnz loopda2   

        lea di,da1
        lea si,da2

        mov cx,2

  loop1:sub byte ptr [di],30h
        sub byte ptr [si],30h
        inc di
        inc si
        loopnz loop1

        dec si
        dec di
        clc
        mov cx,2
        mov bp,0
  loop2:mov al,[di]
        adc al,[si]
        aaa
        mov [di],al
        dec di
        dec si
        loopnz loop2

        inc di
        mov cx,2
    loop3:
        add byte ptr[di],30h
        inc di
        loopnz loop3

        mov [var+4],'+'
        mov [var+7],'='
        mov dx,offset var
        add dx,2
        mov ah,09h
        int 21h
        mov dx,offset da1
        mov ah,09h
        int 21h
        mov ah,4ch
        int 21h
code1 ends
end star
————————————————
版权声明:本文为CSDN博主「loudyten」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/loudyten/article/details/8222373

隐约能看到add这个单词,表示是相加操作,上面这一段指令包含了很多直接操作CPU的指令,基本上描述了计算机的整个运行细节。但是人们觉得像这样根据机器语言进行编程,效率太低,而且容易出错。就希望能想平时说话写字,解答数学题目一样编程,有了这个目标,很多编程语言就被发明了出来(相对于汇编语言,这些语言可以统称为高级语言),比如C语言,用C语言实现两个数相加

#include <stdio.h>

int main()
{
    int a,b;
    scanf("%d %d",&a, &b);
    printf("%d\n",a+b);
    return 0;
}

是不是比上面的汇编简单了不止10倍,但是用高级语言编写的指令是没法直接让计算机理解了,这个时候需要一个翻译,把高级语言翻译成计算机能认识的机器语言,计算机才能运行。这就是每个高级语言都会带一个自己的编译器(C语言)或者是解析器(Python语言)。编译器和解析器都是用来将高级语言转化为机器语言的。

不同的任务可能需要不同的编程语言,比如制作网页结构需要HTML,编写安卓应用需要Java等等。但是语言只是工具,用工具的人才决定了产出的价值。

编程与应用程序

我们平时使用手机、电脑。其实是使用上面的应用程序,不管是打游戏,看视频,处理文档。我们都需要相应的应用程序,这些应用程序提供了我们想要的功能或者信息。而且这些应用程序都充分使用了计算机的输入输出设备,让我们可以和应用程序提供的信息进行交互。

要编写一个完成特定任务的应用程序,需要知道完成这个任务的每一步,然后把每一步转换成机器能理解的指令。这里简单来看有两个步骤:做什么和如何做。做什么编程这件事关不了,但是如何做就是编程需要操心的。

解决同一个问题,可能有很多种方法,编程的人首选需要找到解决这个问题的方法并且把它用某种编程语言进行实现。然后就有了这个应用程序。再抽象一点就是制定方案+实施方案。比如我们需要为编写一个程序解决下面这个问题:

你正在安装一个广告牌,并希望它高度最大。这块广告牌将有两个钢制支架,两边各一个。每个钢支架的高度必须相等。

你有一堆可以焊接在一起的钢筋 rods。举个例子,如果钢筋的长度为 1、2 和 3,则可以将它们焊接在一起形成长度为 6 的支架。

返回广告牌的最大可能安装高度。如果没法安装广告牌,请返回 0。

示例 1:

输入:[1,2,3,6]
输出:6
解释:我们有两个不相交的子集 {1,2,3} 和 {6},它们具有相同的和 sum = 6。
示例 2:

输入:[1,2,3,4,5,6]
输出:10
解释:我们有两个不相交的子集 {2,3,5} 和 {4,6},它们具有相同的和 sum = 10。
示例 3:

输入:[1,2]
输出:0
解释:没法安装广告牌,所以返回 0。

提示:

0 <= rods.length <= 20
1 <= rods[i] <= 1000
钢筋的长度总和最多为 5000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/tallest-billboard
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这个问题,数据大一点,人解决起来都很困难,更别说编程了。这就需要能想到一个能使用计算机语言进行表达的方案。一旦你想到了一个方案,使用什么编程语言来解决,就非常简单了。

下面来看一下使用一个方案,但是两种语言来实现的情况:

想法

对于每一根钢筋 x,我们会写下 +x,-x 或者 0。我们的目标是最终得到结果 0 并让正数之和最大。我们记所有写下的正数之和为 score。例如,+1 +2 +3 -6 的 score 为 6。

因为 sum(rods) 的大小限制,就说明可以利用这个性质。事实上,如果之前已经写下了一些数字,那么就不需要考虑这些数字是如何得到的。例如,rods = [1, 2, 2, 3],我们可以用 3 种方法得到和为 3,但只考虑最终的 score 为 3。数字之和的上界是 10001,因为只有 [-5000, 5000] 区间内的整数是可能的值。

算法

dp[i][s] 表示当我们可以使用 rods[j] (j >= i) 时能得到的最大 score,由于之前写下的数字和为 s(不统计在 score 内)。例如,rods = [1, 2, 3, 6],可以有 dp[1][1] = 5,在写下 1 之后,可以写下 +2 +3 -6 使得剩下的 rods[i:] 获得 score 为 5。

边界情况:dp[rods.length][s] 是 0 当 s == 0,剩余情况为 -infinity 。递推式为 dp[i][s] = max(dp[i+1][s], dp[i+1][s-rods[i]], rods[i] + dp[i+1][s+rods[i]])。

作者:LeetCode
链接:https://leetcode-cn.com/problems/tallest-billboard/solution/zui-gao-de-yan-gao-pai-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Java语言实现

class Solution {
    int NINF = Integer.MIN_VALUE / 3;
    Integer[][] memo;
    public int tallestBillboard(int[] rods) {
        int N = rods.length;
        // "memo[n][x]" will be stored at memo[n][5000+x]
        // Using Integer for default value null
        memo = new Integer[N][10001];
        return (int) dp(rods, 0, 5000);
    }

    public int dp(int[] rods, int i, int s) {
        if (i == rods.length) {
            return s == 5000 ? 0 : NINF;
        } else if (memo[i][s] != null) {
            return memo[i][s];
        } else {
            int ans = dp(rods, i+1, s);
            ans = Math.max(ans, dp(rods, i+1, s-rods[i]));
            ans = Math.max(ans, rods[i] + dp(rods, i+1, s+rods[i]));
            memo[i][s] = ans;
            return ans;
        }
    }
}

作者:LeetCode
链接:https://leetcode-cn.com/problems/tallest-billboard/solution/zui-gao-de-yan-gao-pai-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Python语言实现

from functools import lru_cache
class Solution:
    def tallestBillboard(self, rods):
        @lru_cache(None)
        def dp(i, s):
            if i == len(rods):
                return 0 if s == 0 else float('-inf')
            return max(dp(i + 1, s),
                       dp(i + 1, s - rods[i]),
                       dp(i + 1, s + rods[i]) + rods[i])

        return dp(0, 0)

作者:LeetCode
链接:https://leetcode-cn.com/problems/tallest-billboard/solution/zui-gao-de-yan-gao-pai-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

通过这个问题,想说明的是,编程包括了两个步骤:实现方案和把实现方用编程语言表达出来。

上面这个例子虽然是解决一个算术问题,但是到开发一个实际的应用程序原理是一样的。

编程与电影

如果把编程比作拍电影,那么剧本就相当于实现方案,拍摄器材相当于编程语言,演员相当于使用的开发技术,比如框架,第三方类库等(不是从头开始培养演员,而是有很多现成的演员可以拍这个电影),导演就是编程的人。

要是这样类比就能理解,会使用拍摄器材就能拍出小视频,能请到明星,拍出的东西肯定有流量,如果剧本好,群众演员也能拍出好的电影。但是同一个故事,不同的导演往往能拍出不同的水平,这其中的奥秘不是器材、演员和剧本能决定的。

从学好拍电影的角度讲,学习编程你可能需要知道如何使用开发技术,如何选取适当的编程语言,理清楚实现方案(可以从最简单的两个数相加问题开始)然后不断拍小视频检验自己的作品,能否算的上是一个好的短片(程序)。

所以编程其实不仅仅是学一门编程语言那么简单,语言只是解决了拍摄问题,能帮你处理远景,人物,调色等等问题,但是要拍什么,拍成什么样,表达什么核心观点,才是导演重点思考的问题,不然可能只是一名优秀的摄像师。

欢迎大家讨论。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,265评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,078评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,852评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,408评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,445评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,772评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,921评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,688评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,130评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,467评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,617评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,276评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,882评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,740评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,967评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,315评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,486评论 2 348

推荐阅读更多精彩内容

  • TITLE: 编程语言乱炖 码农最大的烦恼——编程语言太多。不是我不学习,这世界变化快! 有时候还是蛮怀念十几、二...
    码园老农阅读 5,300评论 2 35
  • …or create a new repository on the command lineecho "# au...
    JD2017阅读 291评论 0 0
  • 今天是腊月24,也就是我们南方的小年。 不知不觉这已经是我第二次在外面过小年了。 往年的小年夜都是和家人坐在一起共...
    烟程阅读 317评论 0 1
  • 卯时春雨阵阵急,庭前玉兰惊满地。廊下春燕瑟缩挤,唯有枣树几枝绿。贾照汉
    A贾阅读 192评论 0 0