You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mabbs/_posts/2018-06-20-Coding.md

45 lines
28 KiB

---
layout: post
title: 编程与设计(演讲稿)
categories: [演讲稿]
tags: [编程, 设计, 演讲, 程序]
---
大家好我是mayx今天由我来带领大家了解计算机编程的本质和程序设计。<!--more-->
当提到电脑时,大家首先想到的什么呢?打游戏?聊天?……没有问题。你们享用了电脑所带来的便利,有考虑过它的原理吗?当然,有些东西是不需要知道原理的,毕竟即使你不知道互联网传输协议也可以上网,不知道焦耳定律也可以做饭嘛……但是,我希望今天大家听了我的讲座后,能知道了解其原因后能更好的利用它们。
首先,今天我要讲的东西有以下三大类:一、计算机简介;二、编程;三、设计。
对于计算机,我想大家已经了解很多了吧,在这里我不做过多的介绍,只讲一下比较少见的知识。
大家都知道IT信息技术对吧我们有一门课就是信息技术不过你们知道CS吗我要讲的CS可不是反恐精英而是计算机科学Computer Science。CS只是和IT有交集吧IT研究的不只是计算机包括发邮件等通信方式不过想来主要还是应用了计算机科学。有很多人总会把它们误用就好像动画和动漫不是一种东西一样。
接下来我要讲的是计算机科学中的硬件部分。不过我的物理不是很好所以硬件部分我不会讲太多我想大家也都应该知道计算机大概都是由什么组成吧从微观上来说就是由硅做半导体部分铜银金等导电金属作为主要的电能以及信号传导等等的电路……往大了讲就是CPU中央处理器Central Processing Unit、内存、外存、主板、I/O输入输出 Input/Output等作为主要部分的机器。而更细的东西我也不了解逻辑电路什么的如果有会在Minecraft上做红石电路的人也许还能讲讲CPU的运行原理吧……
硬件的组成,也就是计算机组成体系,关于这一方面,大家应该都知道冯·诺依曼结构的计算机吧,我们平时用的电脑就是这个架构的,我相信只要了解一些计算机的人应该都知道这些。不过我觉得应该很少有人知道哈佛结构吧,它和冯氏很相似,只不过它的并行处理能力更好一些,因为冯氏结构不能同时读取指令和数据,而哈氏结构可以。手机一般就用的是这个结构的。
硬件部分我就讲到这里吧,想要了解更多有关硬件方面的信息,问物理老师都比我靠谱。
接下来就是软件部分了,程序是软件的子集。那么接下来我就来讲讲如何写程序吧。
首先,什么是编程?编程就是编写程序的简称,编写程序是为了解决一些需要运算而得出结果的东西。毕竟是计算机嘛,本质上就是为了运算而产生的。但是,并不是说程序只能在电脑上运行,人脑也可以,甚至是用多米诺骨牌之类的东西都可以执行程序。只是计算机的运算速度比它们都快,所以一般的程序都是在电脑上运行的。只有一些丧心病狂的面试官和考官才会让人脑去想计算结果呢。而让非计算机的东西执行程序,不是为了研究计算机的组成就是一些极客了吧……
现在写程序比以前简单多了以前写程序不知道计算机的运行过程根本写不了程序打孔纸带不说就光机器码都几乎没人能看得懂。不过为了让机器看懂人们也只能这样做了。后来为了让人能更好的写程序发明了汇编语言。不过汇编语言本质上还是将机器码用一些其他的方式简化了本质上仍需了解计算机的运行过程。以上所说的语言都算是低级语言因为必须了解计算机的本质太过复杂而且跨平台性也很差。再后来人们发明了FORTRAN公式翻译 Formula Translation这是人们发明的第一个高级语言。直到现在已经有上千种高级编程语言了它们的目的几乎都是将人能看懂的语言而计算机看不懂的语言转换为计算机可以看懂的语言即为机器码。能被直接转化为机器码的编程语言叫做编译型语言编译它们的东西叫做编译器它的特点是编程语言被编译生成机器码后只能在编译它的这类机器上执行在其他种类的机器无法执行。这种语言的优点是执行速度快毕竟计算机可以直接使用机器码执行只用翻译一次没有第二次。而缺点则是编译后将无法再编辑除非你会机器码或汇编或将它反编译否则就看不到它编译前的代码。除此之外它也不能在不是编译它的计算机或同种计算机上执行。编译型语言以C语言为代表。为了解决无法编辑和跨平台的问题人们造出了另外一种语言即为解释型语言。
解释性语言是将程序源代码一句话一句话解释为机器码所以它可以不用将源代码转换为机器码这样的好处就是可编辑而且因为是一句话一句话的解释所以在所有机器上均可执行。但也正是因为它是一句话一句话的解释所以执行效率低速度也慢。解释型语言的代表是Python语言。工程师是有创造力的人也是无法容忍问题的人。为了解决速度慢的问题他们又创造了一种新的语言它既有编译的高速又有解释的跨平台性。这种语言可以在写好后先编译为一种中间语言它已经有很多接近于机器码的部分但是为了跨平台性它把那些需要在不同种类的机器上语句不同的地方用其他的方式标记出来然后发布时只发布这个由中间语言构成的的程序在其他电脑上执行时它会把那些特别的句子再解释执行。这样的话不就又有很好的执行效率又有很好的跨平台性了吗以此类为代表的语言是Java语言。
刚刚介绍的仅仅是人们让电脑如何理解人们的语言,而接下来要讲的是让人们理解人们的语言了。我说过,编程语言到现在为止已经有上千种了。如果仅仅是为了让电脑理解人类的语言,有那么几种不就够了吗,为什么还要发明那么多种语言呢?人们不了解电脑,电脑也不了解人,而且人与人之间也是互相不了解的。有些人说话的方式是这样的,有些人说话的方式是那样的,他们可能互相都无法理解对方。编程语言不仅仅是给电脑看的,也同样是给人看的。毕竟是人在写程序。编程语言也是人发明的。所以有些人可能觉得这种编程语言写起来不舒服,就会发明新的语言来让自己和与自己相似的人舒服。工程师不只有强迫症,还是完美主义者。
虽然编程语言各不相同,但是电脑就那么几样东西嘛,再多也多不出来个什么。所以编程语言也有很多相似之处。正是因为它们有很多相似之处,所以说你只要会其中一种编程语言,基本上其他编程语言只要学学语法就能直接上手。编程也不仅仅是写出程序而已,它是为了表达自己想法的一种工具。在之后的设计里我会讲一讲设计程序的一些思想。
那么编程语言有哪些最基础的东西呢?首先是它的表达,计算机,或者说任何事物,与人的交互不就是两种吗,也就是输入和输出,五感来接收外部信息,身体活动来改变外界。程序里面获取数据的方式也有两种,一是人们输入的东西,键盘、相机等等都算,二是硬盘中文件的内容;输出也一样,一是输出到如同屏幕或扬声器等地方,将其转换为物理方式,然后被人接收。二是输出到文件,这样既可以让别的程序再利用,也可以等到人们想看时再输出到输出设备。那么除了表达之外就是程序内部的计算了。
这也就是编程与数学的联系编程除了输入输出就是算法了组成算法的除了循环结构之外还有计算、变量与函数。计算和变量与数学的概念差不多但是函数不太一样。虽然说计算机中的函数也是通过计算来将带入的值转换为一个结果但是大多数时候它的主要作用不是计算出一个值而是执行一段指令最终得到的值通常都是0甚至有的时候是空的NULL也就是没有结果。虽然没有得出值但是只要执行了指令就可以得到真正想得到的东西。
但也不是说一个程序一定需要函数那只是为了更方便理解而且编程语言并不一定是给电脑使用的。我之前也说过程序也不一定非得在电脑上执行。为了更好的理解编程语言的执行过程我给大家介绍一种特别的编程语言BrainF\*\*k。BrainF\*\*k是一种极小化的计算机语言它是由厄本·穆勒在1993年创造的它的语法十分简单只有8种符号。分别是加号减号大于号小于号左中括号右中括号逗号和句号组成。整个程序里没有一个英文字母如果在程序中遇到英文字母解释器会将其忽略掉。在执行的过程中它会创建一个很长的数组可存储30000个数字我们可以把它看做是30000个格子每一个格子可以存储的最大数字为255。在程序开始之前会有一个让你处理格子里面内容的指针在执行程序时如果一个符号要想操纵对应的格子必须想办法让指针先移动到那个格子里。这8种符号的作用如下大于号指针向右移动一格小于号指针向左移动一格加号指针所指向的格子中的数字加一减号指针所指向的格子中的数字减一句号将所指的格子里的数字转换为ASCII表格里的对应字符并输出逗号将输入的内容按照ASCII表格里的内容转换为对应的数字并输入到所指的格子里中括号如果程序执行到右中括号时指针所指的数字是0则执行前一个左中括号之后的指令否则忽略这个中括号。听起来是不是很复杂没关系让我来演示一下你就明白了<https://fatiherikli.github.io/brainfuck-visualizer/>(演示)
这个语言是为了帮助理解编程语言的运行过程想来这也就是图灵机的基本思想了有兴趣你们回去可以再研究研究。但是BrainF\*\*k本身并不适合用于给人们用来编写计算机程序如果想要学习真正的编程我建议学习Python语言它的语言功能强大语法简单初学者以及程序员均可使用的语言而且对应的中文教程也很多。所以如果有想学习编程语言的同学我推荐学Python。
当然作为编程语言有很多选择Python有着简单的语法强大的功能很高的兼容性。但是如果要是做一个网站用世界上最好的语言——PHP超文本预处理器Hypertext Preprocessor语言则是一个更好的选择。如果你打算做在单片机上的程序那么C语言似乎更好。如果你想要做手机软件就不得不了解一下Java语言……
编程语言仅仅是一个工具,如果想要写出程序,还要学习如何设计它。接下来我们就进入第三个模块:设计。
在说设计之前我先说说我自己。我有一个特别的能力是什么呢我在使用任何一款现代的电子产品或现代设计的机械我基本上在10分钟之内搞清楚它的使用方法。当然太过古老的比如ENIAC那种不是学过电路的就完全看不懂的那种东西除外。为什么我可以做到这一点呢首先我见过的电子产品本来就很多所以有一些经验。除此之外就是我可以了解那款产品在被设计时到底是为了什么。这也是我为什么想为大家准备这个讲座的原因想让大家明白如何了解一个陌生的产品的用法当然如果能做出来那就更好了。
人们设计产品是为了什么,设计的初衷是什么?当然是为了让人们的生活更方便,使用更舒适。如果你心中突然有一个想要做的东西,会让它令人感觉使用起来很不适吗?我觉得一般的人都不会这样做的吧。所以说设计师在设计产品时也会想客户到底是如何使用他生产的产品,有的时候觉得自己可能想的太过片面,会弄出调查问卷或反馈之类的功能来帮助他们改善他们的产品。
但是设计一个产品很简单,造出来又是另外一回事。有时候设计这个功能有可能可以做到的,可是最终实现它又有可能花费的东西与得到的东西之间算下来不划算。出现这个问题有可能是设计的不好,也有可能是按照当前的科技水平做不到更加合理。
我们今天讲的内容既然是有关计算机的当然要讲程序的设计不可能讲现实世界中的设计。那么接下来让我来讲讲UI设计吧
什么是UIUI即User Interface用户界面的简称在设计UI时不仅要让用户看起来很美观更重要的是要让用户用起来感到舒适、简单、自由。这里我要讲界面设计中比较好理解的两部分1.外观设计也就是让这个UI看起来更加美观2.功能设计这个说明了这个UI从整体看起来的实际功能。那么首先来考虑一下美观吧毕竟大家都喜欢第一眼看上去很酷的东西。外观设计的风格有很多比如现在很流行的扁平化风格以及大家很常见的Windows 7 Aero风格等等。扁平化的设计很好啊不仅界面简洁、美观而且设计起来简单在实际使用时也比较省资源。所以现在很多软件设计界面时都开始使用扁平化设计了。比如Windows 8到Windows 10以及Android 5.0和iOS 9以上的系统几乎都使用了扁平化设计。而刚刚所述的系统几乎都是在移动端设备或者说包含移动端设备的操作系统。所以说这也是它的缺点在非移动端设备上使用扁平化设计可能甚至会令人感到反感。而且扁平化的设计虽然似乎有那么一些科技风格但也正是因为这样它让人感受不到亲切的感觉。在此之前我们有另外一种方法来解决这个问题那就是拟物化设计。我觉得Windows 7的毛玻璃应该也算拟物化。拟物化的好处是什么呢当然是让人感觉更加亲切因为贴近于日常生活所以说对于用户来说也更容易学习。坏处当然也很明显就是设计成本太高有些东西设计师要想很长时间才能想出来如何才能让它更贴近生活。除了设计成本太高外消耗的资源也很多看起来也会让人可能感觉起来太花哨。以此为代表的产品是锤子手机锤子手机上用的系统经过高度定制每一个设计都似乎使用了身边的东西。我用过锤子手机说实话那个似乎很贴近人生活的设计并没有引起我的注意而这个设计所带来的比一般手机增加的将近一倍的内存消耗令我恨不得将这个锤子手机扔掉。可惜我现在还没有可以换的手机所以只能先用它了。
怎么设计外观刚刚说到的也只是一些概念在实际设计时如果是程序设计我们可以使用PhotoShop等工具来设计而对于网站设计用CSS层叠样式表Cascading Style Sheets来设计可以保证它的通用性。
外表设计的再漂亮也只是第一眼看上去很漂亮等新鲜感过去之后基本上也就没什么用了。于是接下来就要看实际的功能如何。这里我用某些设置的设计来作为例子Windows的系统要想设置某些东西都要找控制面板当然有些基础的功能在任务栏上也能用。但是Windows系统的设置通常藏得很深没有一点基础的人很难找出来当然也有可能是他语文学的不好理解不来。而Android系统的设置就不一样了它相比Windows系统就更加人性化了。不过想来也是以前电脑都是给懂的人用的虽然现在的电脑相比以前已经人性化很多了但还是有些地方让人应付不来。手机出来的晚生产出来时就已经有了为全世界人们使用的觉悟了所以用起来也比较简单。总结下来就是好的功能设计要为每一种人设计无论他有多专业还是说从来没有接触过这一切要让人第一眼看上去就明白它有什么基本功能而更高级一些的功能可以先隐藏起来等用户需要使用时再显现出来免得吓坏一些不会用电脑的人。烂的功能设计有两种1.想要找的功能没有可能根本没提供。2.想要找的功能找不到,可能藏得太深了。
你们以为UI都是有图像的吗错了有图像的UI叫做GUI图形用户界面Graphical User Interface但不是所有人用的电脑都是可以显示图像的只是大多数人都用的是图形界面图形界面看起来比较清晰使用起来也比较方便。但是图形界面的效率低无论是电脑的执行效率还是用户使用时的工作效率。不知有没有人听过DOS磁盘操作系统Disk Operating System你们如果没听说过可以回去问问你的父母。在以前图形化的操作系统还没出来时人们用的都是CLI命令行界面Command Line Interface。大家在看那些有着黑客入侵的电影时黑客们是不是都看起来都在胡乱拍键盘其实那真的是在胡乱拍键盘演示<http://geektyper.com/>而电脑屏幕上有一堆看不懂的类似于英文单词的东西从屏幕滚过虽然那是艺术的表现形式有点太夸张但是艺术源于生活现实中真的有人使用那种看起来似乎很酷炫的东西。但是他们不是为了耍帅而使用CLI的而是由于各种原因不得不使用他们。这样的例子有服务器操作系统以及IRC互联网中继聊天 Internet Relay Chat用这个聊天比QQ什么的聊天软件更快更省流量效率高。
我之前也说过电脑中很多设计由于经费等原因不得不让它从界面上看起来不太人性化。但是这并不是没有办法解决了。人之间的交流不止有图像更重要的是文字。电脑也一样电脑与人的交流在术语上叫做HCI人机交互 Human-Computer Interaction。来看一个实例如果我想设计一个网站但是我审美观不行这个网站怎么样才能让人感到亲切呢既然从整体没办法做到更好那就在细节上加倍努力吧一般的网站上都有登录系统吧那么我们可以这样设计对于初次访问的人我们可以在网站上显示欢迎来到我的网站。当然只显示一次之后不再显示。在登录之后刚登录完可以显示欢迎回来某某某。或者是根据时间显示下午好某某某。这样和“某某网站 用户某某某”这样的方式更容易让人接受吧。这样用户就能在潜意识里把这个网站看作一个人而不仅仅是网站。这样即使外表看起来不怎么样但是用户体验总还是不错的吧。没错这一块的设计就叫做UED用户体验设计User Experience Design为了提高用户满意度我们就通过这样的方式来让程序更易用。
除了以上所讲的部分,界面设计还有许多部分。由于篇幅原因,这里我将不再过多说明
以上是关于用户体验设计方面的,接下来让我说说程序设计吧!我之前也说过,编程语言只是工具,实际使用时还需要考虑程序的逻辑、架构、界面等等东西。在以前,程序设计中算法是非常重要的,但那也是以前,多亏很多计算机大神的帮助,现在的编程那是越来越简单了,一个几岁的小孩子就能写出来比以前的程序更漂亮、更复杂的程序。所以,现在算法在计算机编程的重要性越来越低了……但是并不是说算法就没有用了,如果没有人去研究算法,那么人们在遇到新的问题就没人能解决了。尽管以我们这个级别的人研究算法可能没法做出新的东西,但是我还是觉得,让更多的人了解程序背后的原理,可以帮助理解程序如何使用。所以接下来,让我说说关于算法与逻辑吧!
仍然是举个例子:大家都听过音乐吧,在播放音乐时有一个选项:随机播放,对吧?随机播放的实现方式有很多,让我们深层次的来研究一下它吧。首先,随机播放中,有个很重要东西,那就是随机。说到随机就不得不说随机数了,随机数也分为两种:真随机数与伪随机数,真随机数的生成在现实中很简单,在计算机中生成起来就很麻烦了,所以首先抛弃。伪随机数的算法很多,这里我们用最简单、最通用的伪随机数的算法:线性同余取随机数,看过离散数学的人可能有听说过这个。为什么我们选这种算法?因为其他算法我看不懂,比如什么梅森旋转算法啦,一听名字就能感觉它有多难了吧,反正我看了半天是没有理解。什么是线性同余?就是算一个一次函数的余数,相当简单,它的递推公式是:X0=seedXn+1≡(aXn+b)modM。seed表示随机数的种子通常取当前时间a,b,M都是常数通常会取质数。在seed与n都相同时这个随机数就能被反推出来所以很不安全。但是想来做随机播放也不担心别人会不会推出随机数所以我们就用这个就能得到一个随机数。具体原理我也不太清楚有兴趣的可以问问数学老师。接下来我们要创造一张表那张表上有着你要播放的播放列表但是这时候它还没有被打乱。首先我们要知道整张表上有多少首音乐假如我们用a来代表当前所有音乐的数量然后我们再为所有的音乐编上号看起来就是1、2、3……。这时候每一首音乐都有了一个属于自己的编号。再然后我们对用随机数公式得出的数字求余即Xmod(a+1)这样做就可以得到一个不超过所有音乐数量的随机数了。当然前提是随机数本身的最大值大于所有的音乐数量所以在随机数公式中的M要尽可能取大一些。得到最后需要的随机数后命令播放器播放编号等于随机数的那个对应的音乐。当需要播放下一首或切歌时为了避免又播到这一首歌我们可以将那张表上的那首音乐删除当然是在表里删不可能删这个文件。然后重复之前的操作。在最后一个音乐播放完成之后表里已经没有东西了。这时有两个选择如果用户打开了全部重复播放那么重新建表重新开始。如果没有则停止。看起来是不是很完美的方案错了用户总是喜欢做反设计师的操作万一用户点了上一首怎么样才能回到上一首那么我们就需要修改一下方案我们要建两张表把从表里删除的那个操作换成将它移动到第二张表里。这样如果用户需要听上一首歌就可以读上一张表的内容。难道说这样就完美了吗不完全但是这个BUG我现在不说出来大家自己思考思考吧。
除了逻辑设计还有算法设计。我们再举一个例子如果说我们在设计程序时需要用到质数比如需要列出1到1000之内的所有质数。那么我们用什么方法更好呢首先根据质数的定义质数是一个不会被除了1和它本身的数所整除的数字而且质数不包括1。那么接下来设计起来就很简单了只要让当前数字不停的除以除它和1之外的在1到这个数字之间的所有数字就可以了。这很好但是速度很慢。可能这样算1000以内的所有质数还不算太慢那如果是10万以内呢这得算多长时间啊……所以我们要对算法进行优化。我们知道合数有一个特点任何一个合数一定是由比它小的质数相乘得出的那么接下来我们可以这样筛选合数首先我们算出第一个质数在算第二个数时只要和之前算过的质数相除能除尽就是合数除不尽就是质数。这样是不是计算量一下就大大减少了呢但是这还不是最优化的方案如果说我们已经知道我们要算的最大数字是多少那么只需要除以比这个最大数字的算术平方根小的质数就够了。这样每次算的时候需要除的数字又少了一半算起来速度就会更快了。虽然这个算法不错但有时我们甚至不需要这个算法就可以更好的解决这个问题。因为我说的是列出1到1000之内的所有质数这个数字又不是很多那么我们可以提前算好这样就可以更快的解决问题了这样的操作我们叫它预计算Precomputed
程序设计是一个很严谨的事情每一个方面都需要做到最好。但是人无完人总有我们想不到的地方。尤其是计算机安全方面的事情总有你想不到的地方总有别人比你多想的地方正是因为这样才会出现黑客这样的人。这里我仍然用举例子的方式为大家展示程序设计的漏洞我最早发现的网站漏洞似乎是在一个主机商的网站上看见的。由于一个很偶然的原因我看到了那个主机商而那时我正好想建一个网站然后就在那个网站上注册了一个账号。那个主机商正好在搞活动好像是买主机可以给你便宜5块钱而账号初始上也有5块钱主机最便宜的每个月也要30块钱。然后我想了想要不然我干脆买上0.1个月的主机吧0.1个月应该是3块钱我应该能付的起。于是我在购买里输入了0.1当然结果是失败的它不能让你买小数或者是负数之类的月数。但是我返回来惊奇的发现我的账户里居然多出来了5块钱我想了想它应该是对我的账户上减去了0-5元钱毕竟是在搞活动然后算一下5-(-5)=10。这个好啊我感觉我可以免费得到那个主机商的主机了。于是我通过这个BUG买了1年的主机居然成功了。当然在大约10天后被发现了账户也被封禁了。通过这个例子我们应该明白不要相信任何用户输入的数据还好我仅仅是用这个漏洞买主机很明显这个漏洞甚至可以通过SQL注入之类的东西破坏他们的主机系统。不过这个例子似乎离日常生活有点远那么接下来我再说一个近一点的事情在几周前我们不是进行了禁毒考试吗我看了一下那个网站很明显是一个宁夏的网站公司包办的东西。一看就知道是一个做的很不认真的网站。我在答题前看了一下源代码发现它在批阅卷子时先在本机批一遍只有成绩大于60分时才会把答题数据传到服务器中再批一遍。这样确实可以有效的减小网站的负载但是这不就把答案也下载到本机上了么……于是我照着答案就在禁毒考试中得了A。这个例子又告诉了我们什么呢就是不要将不应该让用户看到的东西下载到客户端中。
总的来说做一个程序并不复杂但是做一个逻辑严谨界面美观而易用的好程序就没那么简单了。设计师在设计时需要考虑各种各样方面的东西来让用户用的舒服又要想尽各种办法防止整个程序出现奇奇怪怪的BUG。这也就是为什么说写程序很难了。但是我希望大家听完这个讲座后能改变对写程序的看法它看起来很复杂但是只要仔细思考就能解决一切问题。
以上就是我对编程以及设计的看法,也许语句中有不通顺之处,请大家谅解;如果有不对的地方,欢迎大家批评指正。
最后,谢谢大家前来听我的演讲,谢谢大家对我的支持与信任,本次演讲结束。