主题:今天随便说两句,关于日本 -- 绝对不是白领
我没有系统学习过怎么编程,都是摸索出来的,一点感触,方家勿笑。
我认为程序大致分两种,1、计算某个结果,或者说function;2、实现某种过程,或者说task。前一种更偏向数学,后一种更偏向语言。
实际上一个足够大的程序肯定是两种都有的,相互交汇不可分割,所以两种思维的融合也就不可避免了,但无论哪种,都是要讲究逻辑的,这么看来逻辑可能是更高层的思维吧。
数学从业者脑回路是很不一样的。
典型特征之一是官杀不管埋。比如,一个数学家可以证明一个问题的解是存在的。至于怎么找到这个解?好吧我证明这个解存在已经爽够了寻找这个解留给下一代吧。
离开数学很久以后我还保留了这个思路。
所以我和一个前辈有过这个对话。
前辈:这个问题有解没有?
我坚决地:有!
前辈:能不能找到这个解?
我坚决地:不能!
前辈:求助于最好的数学家最好的计算机呢?
我坚决地:别想因为理论上不可能!
解“i+++(++i)”这样的谜题其实和做数学练习是同样的道理,很多别扭的数学习题也没有啥实际意义,就是一种“机械性”的训练。
从你引用的部分和你的评论,我太不清楚原作者和你是想鄙视“二级C”还是想鄙视懂 C 编程的程序员。
数学,数学家,电脑,电脑程序,程序员,本来关系很清楚,非要搅和的话,也可以搅和一下数学,数学家,算盘,打算盘的账房先生,或者,音乐,小提琴家,制作小提琴的琴匠,也能搅和出同样的结论。
“99%的数学家都写不出像样的代码。”--- 99%的小提琴家都不会制作小提琴,所以琴匠才是真正的艺术家。99%的数学家都没账房先生算盘打得好,所以账房先生才是牛人。
计算机科学根本不是数学,它只不过借用了非常少,非常基础的数学,比高中数学还要容易。
所谓“高等数学”,并不是研究计算机科学必须的。你可以用计算机来做微积分计算,可是这时候你其实是在做数学工作,用计算机作为工具。你研究的并不是计算机科学。这就像你可以用计算机来设计建筑,但建筑学却不是计算机科学的基础。
计算机是比数学更加基础的工具,就像纸和笔一样。计算机可以用来解决数学的问题,也可以用来解决不是数学的问题,比如工程的问题,艺术的问题,经济的问题,社会的问题等等。
计算机科学是完全独立的学科。学习了数学和物理,并不能代替对计算机科学的学习。你必须针对计算机科学进行学习,才有可能成为好的程序员。
数学家所用的语言,比起常见的程序语言(比如C++,Java)来说,其实是非常落后而蹩脚的设计。所谓“数学的美感”,其实大部分是夜郎自大。
99% 的数学家都写不出像样的代码。
这样的理论,放哪个领域都很滑稽,例如,
制作小提琴根本不是音乐,它只不过借用了非常少,非常基础的音乐,比高中音乐还要容易。
所谓“高等音乐”,并不是研究小提琴科学必须的。你可以用小提琴来演奏音乐,可是这时候你其实是在做音乐工作,用小提琴作为工具。你研究的并不是小提琴科学。这就像你可以用小提琴来做室内装饰,但室内装饰却不是小提琴科学的基础。
小提琴是比音乐更加基础的工具,就像纸和笔一样。小提琴科学可以用来解决音乐的问题,也可以用来解决不是音乐的问题,比如拉动GDP,比如防止假冒伪劣产品等等,又比如,小提琴做得好,夜壶也肯定做得漂亮,这是音乐学望尘莫及的。
小提琴科学是完全独立的学科。学习了音乐和物理,并不能代替对小提琴科学的学习。你必须针对小提琴科学进行学习,才有可能成为好的琴匠。
音乐所用的语言,比起常见的小提琴语言来说比如“匠心琴韵,别具一格,价值连城”,其实是非常落后而蹩脚的设计,所谓“音乐的美感”,其实大部分是夜郎自大。
99%的小提琴家都做不出像样的小提琴。
又例如,
算盘科学根本不是数学,它只不过借用了非常少,非常基础的数学,比高中数学还要容易。
所谓“高等数学”,并不是研究算盘科学必须的。你可以用算盘来做微积分计算,可是这时候你其实是在做数学工作,用算盘作为工具。你研究的并不是算盘科学。这就像你可以用算盘来做假账,但假账学却不是算盘科学的基础。
算盘是比数学更加基础的工具,就像纸和笔一样。算盘可以用来解决数学的问题,也可以用来解决不是数学的问题,比如地主用算盘骗剥长工,打算盘还可以耍酷泡妞等等。
算盘科学是完全独立的学科。学习了数学和物理,并不能代替对算盘科学的学习。你必须针对算盘科学进行学习,才有可能成为好的账房先生。
数学家所用的语言,比起常见的算盘语言比如“三下五除二来”说,其实是非常落后而蹩脚的设计。所谓“数学的美感”,其实大部分是夜郎自大。
99%的数学家打算盘都不如账房先生。
回下面一位河友的话。这位河友贴还在待审,所以不能直接回,抱歉。
另外,我数学半路出家,荒废很久,有不妥之处各河友请纠正。
一个解存在但不可求的例子是不稳定系统。
数学上,不稳定系统指初始情况差一丝一毫引起系统演化相差无比巨大的系统。
比如,一个简单的不稳定系统是一支削尖的倒竖的铅笔。我们都知道这铅笔要倒。但是怎么倒,往左往右倒下时候转几圈,就没办法说了。
这个问题有解。我们把笔竖一次看它倒,倒下的轨迹就是一个解。
但是笔在倒以前,我们没有办法解方程得到一个关于笔倒下轨迹有意义的预测。
这是解存在但不可求的一个例子。
还有其他例子,不一一列举。
跟几根头发算秃,几根不算一样,很难定义
关于计算机和数学的关系,Paul Graham的看法是
创作者不同于科学家,明白这一点有很多好处。除了不用为静态类型烦恼以外,还可以免去另一个折磨科学家的难题,那就是“对数学家的妒忌”。科学界的每一个人,暗地里都相信数学家比自己聪明。我觉得,数学家自己也相信这一点。最后的结果就是科学家往往会把自己的工作尽可能弄得看上去像数学。对于物理学这样的领域,这可能不会有太大不良影响。但是,你越往自然科学的方向发展,它就越成为一个严重的问题。一页写满了数学公式的纸真是令人印象深刻啊。(小窍门:用希腊字母表示变量名会令人印象更深刻。)因此,你就受到巨大的诱惑,去解决那些能够用数学公式处理的问题,而不是去解决真正重要的问题。如果黑客认识到自己与其他创作者——比如作家和画家——是一类人,这种诱惑对他就不起作用。作家和画家没有“对数学家的妒忌”,他们认为自己在从事与数学完全不相关的事情。我认为,黑客也是如此。
把不同类型的工作捆绑在一起,可能是为了行政管理的方便,但是却容易引起混淆。这是我不喜欢“计算机科学”这个词的又一个原因。中间部分“计算机科学家”的工作,也许还可以被称为计算机的实验科学。但是,两端的数学家和黑客,并不是在做计算机的科学研究。
数学家看来并不在乎自己搞的是计算机还是数学。他们很高兴来到这个新地方,然后就开始埋头证明新的定理,与数学系的数学家干的事情完全一样。不一会儿,他们可能就忘了办公楼外的牌子上写的是“计算机科学系”。但是对于黑客,“计算机科学”这个标签是一个麻烦。如果黑客的工作被称为科学,这会让他们感到自己应该做得像搞科学一样。所以,大学和实验室里的黑客,就不去做那些真正想做的事情(设计优美的软件),而是觉得自己应该写一些研究性的论文。
要是黑客写论文,最好的情况下,写出来的也只是一些补充性的描述,不会具有太大的实际价值。黑客先开发了一个很酷的软件,然后就写一篇论文,介绍这个软件。论文变成了软件成果的展示。这种结合是错误的,常常会产生问题。为了配合论文研究性的主题,你很容易就把工作重点从开发优美的软件转移为开发一些丑陋的东西。
优美的软件并不总是论文的合适题材。首先,科学研究必须具有原创性。写过博士论文的人都知道,确保自己正在开垦新领地的方法,就是去找那些没有人要的土地。其次,科学研究必须是能够产生大量成果的,而那些不成熟的、障碍重重的领域最容易写出许多篇论文,因为你可以写那些为了完成工作、你不得不克服的障碍。没有什么比一个错误的前提更容易产生大量待解决的问题了。人工智能(AI)领域的大部分情况,都符合这条“如何凭空创造出问题”的规律。如果你假定,使用一系列的谓词逻辑(predicate logic)表达式,再加上代表抽象概念的参数,就能表达人类的知识,那么,你就可以写出许许多多的论文,解释如何完成这项工作。这就像电视剧《我爱露西》(I Love Lucy)的男主角Ricky Ricardo的话:“露西,这下够你好好解释的了。
文字来源于《黑客与画家》https://www.douban.com/note/453902232/
https://github.com/mkirchner/linked-list-good-taste
第一版
void remove_cs101(IntList *l, IntListItem *target)
{
IntListItem *cur = l->head, *prev = NULL;
while (cur != target) {
prev = cur;
cur = cur->next;
}
if (prev) {
prev->next = cur->next;
} else {
l->head = cur->next;
}
}
第二版
void remove_elegant(IntList *l, IntListItem *target)
{
IntListItem **p = &l->head;
while ((*p) != target) {
p = &(*p)->next;
}
*p = target->next;
}
第一版中,删除第一个元素是一个特例,需要用if单独处理,但是第二版中通过使用指针消除了这个特例,变得更加一般化了。这种好代码不是光学好数学就能想出来的,因为做数学题并不需要使用指针(︶︹︺)
按照c标准,“i+++(++i)”属于未定义行为(https://blog.csdn.net/qq_29169813/article/details/51416281),编译器得到什么结果都是有可能的。
谭浩强只是把他在borland c 2.0中得到的结果当成了「标准答案」去考(折腾)人。
有些孩子读高中的时候,就能用BASIC语言在Apple II型个人电脑上,写出漂亮的乒乓球游戏。等他们进了大学,都会去选修计算机科学101课程,那门课讲的就是数据结构。当他们接触到指针那些玩意以后,就一下子完全傻眼了,后面的事情你都可以想像,他们就去改学政治学,因为看上去法学院是一个更好的出路[1]。关于计算机系的淘汰率,我见过各式各样的数字,通常在40%到70%之间。校方一般会觉得,学生拿不到学位很可惜,我则视其为必要的筛选,淘汰那些没有兴趣编程或者没有能力编程的人。
对于许多计算机系的青年学生来说,另一门有难度的课程是有关函数式编程(functional programming)的课程,其中就包括递归程序设计(recursive programming)。MIT将这些课程的标准提得很高,还专门设立了一门必修课(课程代号6.001[2]),它的教材(Structure and Interpretation of Computer Programs,作者为Harold Abelson和Gerald Jay Sussman Abelson,MIT出版社1996年版)被几十所、甚至几百所著名高校的计算系机采用,充当事实上的计算机科学导论课程。(你能在网上找到这本教材的旧版本,应该读一下。)
https://www.ruanyifeng.com/blog/2008/12/the_perils_of_javaschools.html
我很久不写 C 程序了,发上一个帖子前还专门写了个微型的 C 程序编译来验证。但还是忘了给编译命令加上 -Wall,结果编译器没给警告。
C 语言因为历史久远,现在看来语法上有不少缺陷,比如我上面出的那个错误 😅。
现在考试还用谭教授那时的教材,那确实太陈旧了。
如果在学习 C 语言过程中,多做这样的练习题还是有用处的。但是作为考试内容,还不及时更新,确实不对了。
按他们的说法,由于搞数学的头脑清楚,逻辑清楚,写代码有很大优势。
因此,看来在学数学的人圈子里,他们有很多人都认为写代码对于他们是一个相对容易的转行。
回到那最后一句话,如果数学家的的定义使得那个圈子正好套中上述圈子,而象样的代码的定义又不是太苛刻,则99显然很难成立,所以我说要定义。
何况一般来说,精确到两位数接近三位数这样的断言,没有精确定义恐怕不那么容易斩钉截铁吧。
但是请教,像铅笔这个例子,为什么数学家认为不可求,或者只是在一定条件下不可求?
因为好比马斯克那个火箭回收,难道不正是一个典型的不稳定系统吗?
当然,从这个角度来说,虽然他那个技术是酷炫的,但也是风险巨大的吧。从工程上来说,难道不是一个在基本原理上就不合理的路线吗?
一个是未定义行为undefined,一个是未指定行为unspecified,
C标准我也不熟,但是像
printf("%d %d", i++, i++);肯定会有两种结果,c语言并没有指定函数取参数一定从左边取或者一定从右边取。当然这不会报警或者报错,只是得到的结果在不同的系统和编译器上可能不一样而已。
按照c99标准,副作用发生的顺序也是未指定的。英文还没看
未規定の動作の一覧
未規定の動作にはどのようなものがあるのでしょうか。C言語の標準規格であるJIS X 3010:2003(ISO/IEC 9899:1999)の「附属書J 可搬性」を参考に未規定の動作を列挙してみましょう。
部分式が評価される順序、及び副作用が発生する順序。ただし関数呼出しの()、&&, ||, ?:, カンマ演算子は除く。(6.5)
http://www.c-lang.org/detail/unspecified_behavior.html