我对程序的一点理解

从直观的说起

这一段和后面联系不大,但写这个东西的第一目的是作为自己的想法和笔记,首先要跟随自己的思路走,所以随意吧。我小学的时候第一次见到微机时,以为那个大电视才是本体——因为画面都在上面。以前的游戏,受限于性能,画面是像素风格的:
像素马里奥

一个“采蘑菇”里的小人,分辨率只有20×10,而现在出的笔记本电脑,分辨率最低也是1366×768,所以即使是一个对话框,也有100×50以上的像素。放大之后,才会发现颗粒感。从电影到电视机再到电脑,原始的像素游戏到视网膜屏幕,原理其实一直都没变,只是量变给观感带来了质变。
像素对话框

顺便提一下,3D画面是这样实现的:

在 320x200 的解析度下,从摄像机中心射出 320x200条光线,屏幕上每个点对应一条光线,首先碰撞到的物体的位置颜色,就是屏幕上这个点的颜色:

3D渲染

代码如下:

for (int y = 0; y < 200; y++) {
   for (int x = 0; x < 320; x++) {
       DWORD color = RayCasting(x, y); 
       DrawPixel(x, y, color);
   }
}

来源:256字节3D程序是如何实现3D引擎的呢?

同样的一个马里奥,在玩家眼里和在计算机的存储里,是不同的格式。这是因为,在计算机内部,图像是以数据的形式表示的。其实不止图像,所有的信息都以数据的形式在计算机内部表示。玩家不用关心马里奥在计算机里是怎么表示的,但开发者需要了解。
不同的马里奥

抽象

抽象是程序开发里非常重要的概念,我们用Mario来指代刚才的那个像素小人,然后直接让Mario做动作。而矩阵的每个点(x,y),左移一步坐标从(x,y)变成(x-1,y)...交给计算机就好:

#这里是伪代码
Mario = 矩阵[[x1,y1,red],[x2,y2,green]...] #初始化每个点的坐标和颜色
Mario.MoveRight() #任一x+1
Mario.MoveLeft() #任一x-1
Mario.Jump() #任一y+1
Mario.Down() #矩阵变化为蹲的状态
...

之所以提到抽象,是为了引出:

流水线与程序

这里是完整的薯片生产流水线,如果有兴趣可以点进链接,下面只贴一下必要的工序

清洗去皮
清洗去皮
切片去淀粉
切片去淀粉
油炸调味
油炸调味

把这条生产线用程序员常用的时序图(sequence)抽象一下,就像这样(sf太坑了,不支持时序图):
薯片生产线

那这个和程序有什么关系呢?举个例子,虽然淘宝百度的首页风格不同,但在程序员看来都是相似的:

  1. 搜索框中输入,传入到服务器
  2. 服务器接收到信息,查询数据库
  3. 数据库返回结果到服务器
  4. 返回查询结果

搜索流程

当然,实际过程中会根据需求有所不同,比如服务器会有负载均衡、用户验证、信息验证等中间过程。

这个过程的实际代码是这样的:

前端:

$.ajax({
    url: "www.innate.com/search", //服务器地址
    data: "keyWord", //搜索关键字
    successful: function a(){}, //成功的处理方式
    error: function b(){}, //失败的处理方式
});

服务器端:

@RestfulController
@RequestMapping("/search") //接收传给www.innate.com/search的请求
public String search(String keyWord){
  String result = sql.Search(keyWord); //在数据库中查询
  return result; //返回查询结果
}

数据库:

select table.col1, table.col2, table.col3
  from table
 where table.col1 = keyWord -- 查询table中col1为keyWord的记录

这些代码也可以看作各个API的流水线处理

ajax() -> @RequestMaping -> (select语句) -> 返回到ajax()处理

在程序员的眼睛里,这些API就和薯片流水线上的各项机器一样,而且可以自订规则,比现实里的设备更灵活。

clipboard.png

程序员的未来

知乎上有个问题很有意思:程序员做到什么程度才不会被算作 API caller?

拿WEB开发来说,大部分的功能都已经确定了:首页、导航、文章、帖子、搜索、图表报表、上传、下载、发送邮件...有一些框架(比如说SpringMVC)把这些功能已经整合封装成ajax这样的API了,开发的时候根据需要调用就可以了——大部分IT培训机构就是教你怎么用某套框架做一个项目出来——也是我现在的状态。

可是为了提升效率、安全、稳定,每隔几年就会有新的框架或者版本出现,比如最近几年出现的Vue/Angular/React,虽然都是JS,写法和背后的原理却有很大的区别。为了使用这些新技术,大多数程序员都要不断的学习。

三种不同JS框架输出HelloWorld :

//Vue.js
<body>
    <div id="app">
        <p>{{message}}</p>
        <input v-model="message">
    </div>
    <script>
    var exampleData = {
        message: "hello world"
    }
    new Vue({
        el: "#app",
        data: exampleData
    })
    </script>
</body>

//Angular.js
<body>
    <div ng-controller="helloworld">
        <p>{{1+1}}</p>
        <p>{{helloworld}}</p>
    </div>
</body>

//React.jS
<body>
  <script>
    ReactDOM.render(
      <h1>Hello, world!</h1>,
      document.getElementById('root')
    );  
  </script>
</body>

此外,既然程序工业流水线可以类比,那么现在的程序员产业工人也可以类比。将来程序员这个职业,一定会发生分化:

  1. 随着智能手机的普及,必然使更多的人接触编程,能自己写一些小程序、小工具的人会越来越多。那么像我这种,只会调用API写一个小模块的人,肯定会泯然众人
  2. 程序工人与工程师之间的区分在于产品的稳定性能健壮等。比如我有一次需要清除某张1500万表里的1000万条数据:

    • 最初我直接用SQL语句执行,2个小时没有执行完
    • 之后使用存储过程,1个小时也没有执行完
    • 最后使用存储过程,将其余500万条取出到一张临时表里,只花了不到20分钟,然后truncate该表,大概20秒完成
    • 接着将临时表里的数据放回到该表里,花了不到10分钟
  3. 除去上面提到的性能,工程师在设计系统的时候也会考虑系统承载能力、故障隔离、冗余备份等等。这会是工程师和程序工人的一个区分
  4. 有个段子说:三流的程序员写模块,二流的程序员写架构,一流的程序员写算法,顶级的程序员种头发。算法是什么呢?不聊OI/NOI/ACM这些算法竞赛,说一个生活中简单问题的建模:

    编程到底难在哪里
    程序员:我今天要买一斤苹果。因为我只喜欢红富士苹果,所以我只买红富士苹果。我能接受的最高价格是10元/斤。正常情况下一斤苹果用一个袋子能装下,但是为防万一,我会带两个袋子。我知道附近的3家水果店,所以我会依次访问这3家水果店。

    链接里的答案很长,但是很有意思,上面提到很多系统的功能早已模块化,多少人在工作里也只是把分配下来的任务完成就好,下班之后从不研究技术,或是去写一点自己想做的东西呢?

  5. 程序员的工资高不仅是因为写出一套软件之后,复制第二套的成本很低,还在于这几年资本的涌入。很多虚高的工资都是就像滴滴和Uber为了占领市场发起的补贴大战,如果这一阶段结束了,还会有公司开这么高的工资吗?
    而且开工资的毕竟是资本,随着可以讲故事的地方越来越少,资本开始撤离或是要求回报,又会是什么样呢?我只听说2001年有过一次互联网的冬天,但之后,程序员们就没怎么过过苦日子吧,我想还是可以提前准备一下。

程序能做什么

说起来,也写了几年的程序,但对程序的意义思考还很少,只能勉强说一说

  1. 把信息数据化
    图片描述

    程序很大一部分和IT(Information Technology)有关,计算机用数据来存储信息,上图里的杂志、字典、照片、打印、电话、地图...无一不是信息的载体,30年间这些东西都已经变成了计算机里的数据。这是很多程序设计的基础:CAD软件、MIDI音频制作、Office套件、写作、绘画等等,转化成数据之后记录更容易,并且产生了新的形式,比如网络小说。
    信息没有实体,但可以作为现实行为的抽象,比如把流水线抽象成模块;游戏把现实里的动作抽象为技能/CD,并没有让人感到违和。

    先主曰:“朕令吴班引万余弱兵,近吴寨平地屯住;朕亲选八千精兵,伏于山谷之中。若陆逊知朕移营,必乘势来击,却令吴班诈败;逊若追来,朕引兵突出,断其归路,小子可擒矣。”

    这一段可以用“亚瑟在草里蹲着,残血后羿去线上浪一波,对面韩信来抓就反杀他”比喻。
    看过马亲王的这篇怎样让大明变得透明,可以详细的了解历代王朝是怎么根据文书里的数据进行管理的——就像今天的大数据一样。数据,或者说把数据信息化,可以发挥计算机的长处。
    插入计算是什么?加减乘除/移动数据/转换/输出信息

  2. 提升效率

    在计算机内部,一次操作就是一次运算。不限于加减乘除,读取键盘的输入、把数据从存储里读取出来或是把信号输出到显示器都是运算。现代CPU的运行频率普遍在1GHz以上,也就是说一支笔从桌子上滚落,到接触地面的时间里,CPU已经进行了5亿次以上的运算——即使人脑运算2+3只需要1次运算,计算机运行2+3需要1万次运算,也比人脑快5万倍。
    所以在网页或者记事本里,用Ctrl+F进行关键词查找,一定比人肉搜索更高效。
    再举一个例子,很多同学为了考四六级、考研、雅思/托福都会背单词,但只会从abandon,abortion...背下去,既不得要领,也坚持不下去。如果会写一点小程序,统计历年真题里出现的高频词汇,重点理解,既提升了效率,也能随时看到效果,事半功倍。
    《魏略》说,孔明在荆州,与石广元、徐元直、孟公威俱游学,三人务于精熟,而亮独观其大略。有的时候,我们应该把网络、硬盘、搜索当作自己的记忆,而在大脑里保存一份知识框架就好。即使最强大脑里选手练习得再快,也比不上魔方机器人0.38秒还原,更别说思考还原步骤的时间了。

  3. 解决可重复的工作
    前段时间很火的为所欲为表情,已经有了生成模板——为所欲为生成器。此外还有比价软件、网页爬虫、闹钟、QQ群特别关注等。这些都是把人从重复的动作里解脱出来。
    人的注意力和精力都是有限的,一般来说,最多能同时关注7件事情。但程序开启多线程之后,只要资源允许,可以无上限的同时处理多个任务。
  4. 控制注意力
    赫胥黎在《美丽新世界》里说:我们终将毁于我们所喜欢的东西上。想想很多人刷了一天的短视频,有多少深刻的印象?丰富的信息是水,水能载舟,亦能覆舟。

见识浅薄,难以概括程序的意义,但是涉及到信息、重复的工作,就完全可以用程序来替代或者提高效率。而且IT行业一直在加速发展,20年前多少人有手机?10年前多少人有电脑?5年前多少人用手机购物?总之,作为一个朝阳行业,虽然现下也存在泡沫,但长远看来,至少还有20年上升期,这一代的程序员们,真的是处在了“黄金时代”。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值