设为首页收藏本站

Crossin的编程教室

 找回密码
 立即加入
查看: 6247|回复: 0
打印 上一主题 下一主题

浅谈逻辑:编程中最重要的基础

[复制链接]

169

主题

1

好友

733

积分

版主

Rank: 7Rank: 7Rank: 7

跳转到指定楼层
楼主
发表于 2020-7-24 16:41:14 |只看该作者 |倒序浏览

“英语不好能不能学编程?”

“编程是不是对数学要求很高?”

时不时会在公众号后台收到类似的疑问,即:数学/英语是否是学编程先决条件?

我觉得这个问题有点像,身高不高能不能打篮球一样。虽然对于职业篮球运动员来说,身高是非常关键的因素,但对于普通篮球爱好者,甚至一个篮球相关从业人员来说,这并不是非要不可的条件。放到编程上,数学和英语都很重要,但:
在入门阶段,你完全不用在意这些,照着一本教程好好跟着模仿就行对于大部分的日常开发来说,中学程度的数学和英语水平已经可以应付了和身高这种先天条件不同,英语和数学是可以通过学习提高的,哪里不足补哪里呗。“以大多数人的努力程度之低,根本轮不到拼天赋。”你能长期坚持背背单词,看看书,就足以提升自己。总是把XX不好挂在嘴上恐怕更多是在给自己找借口。
不过,有一项能力,确实是在学习编程初期就需要足够重视的。然而这一点,很多教程不会专门强调,相关书籍也往往假定你已经掌握,以至于很多学习者并没有意识到自己在此方面的薄弱,为之后的学习留下隐患。我要说的就是:

逻辑

某种角度来说,逻辑可部分算作是数学,在高中数学课本中就有相关内容。这部分内容也恰好是我们学编程时最需要了解的基础。

一、布尔代数

由真(1)、假(0)两种状态,以及与(and)、或(or)、非(not)三种基本运算组成。布尔代数看似简单,却与数字电路中开和关两种状态相对应,是计算机的逻辑基础。你可能听说过,电脑上的一切在内部都是由0和1所表示,那换句话说,计算机的所有行为,本质都是由布尔逻辑所实现的。

在编程语言中,布尔类型(bool)也是极为重要的存在。没有它,我们就做不了条件判断,也就无从控制程序的执行。Python 的 if、while 语句都必须依赖布尔类型作为判断条件。

因此,即使你不想深入学习逻辑,布尔代数的基本规则也是无论如何必须了解的。简单来说,就是下面这张“真值表”:

这些基本规则又会组合出更复杂的逻辑,比如:

not (p or q) 等价于 (not p) and (not q)

(示例:“不是管理员或者会员”相当于“不是管理员且不是会员”)

实际开发中面临的逻辑判断复杂多样,但归根结底还是会转化到最基本的这几个规则上。

思考题1:如何用逻辑语言表示“通过活动注册的新用户或者充值超过100元的老用户,内部人员除外”

二、命题逻辑

真值唯一的陈述句叫做命题,不能分解成更简单的命题叫做原子命题。比如,“1+1=2”是原子命题,“所有猫都是白的”是原子命题(假命题),“存在外星人”也是原子命题(虽不能判断真假,但结果必然唯一)。命题和逻辑运算相结合,又会产生更复杂的逻辑。

比如充分必要条件。

如果命题p必然推出命题q,那么p就是q的充分条件,q就是p的必要条件,记作 p→q。

比如汉乐府的诗句“山无棱,天地合,乃敢与君绝”,用逻辑语言表达是怎样?

(山无棱 and 天地合) → 与君绝?

想一想是不是不大对劲?根据语义来看,“山无棱”、“天地合”是“与君绝”的必要条件,如果“与君绝”为真,那必然存在“山无棱”和“天地合”,反过来却未必。所以正确的逻辑是:

与君绝 → (山无棱 and 天地合)

再比如三段论。

①不掌握基本的逻辑知识就无法学好编程

②Python是一种编程语言

所以,学好Python需要掌握基本的逻辑知识

一个大前提加上一个小前提,可以推导出一个结论。这是日常使用最多的论证形式,看似简单,但也总有人在这上面犯糊涂。举个错误的例子:

①有钱人都用 iPhone XS Max

②我用 iPhone XS Max

所以,我是有钱人

这些逻辑关系、推导过程与程序中的逻辑结构息息相关。如果你对此不能保持思路清晰,写出的代码很可能与预期有出入,或是在一些特殊情况下存在漏洞。

思考题2:一个每天签到领奖的小功能,在每天的11~13点和18~20点开放,普通用户每天可以领取一次,会员用户可以在每个时段分别领取一次。如何实现这段程序的逻辑结构?(我时常拿这个作为面试题,很多人都不能在短时间内给出正确的答案)

三、归纳

有时候,我们并不能通过逻辑推导出必然的结论,但仍然可以通过一系列的经验和已有结论,找出其中基本遵循的规律。

比如:

①X团队历来给所有成员都配备Dell笔记本作为工作电脑

②C老师最近刚加入X团队

通过这两点,我们可以推导出,C老师很可能也使用Dell笔记本。

但你要清楚归纳的结论并不必然为真,如果遇到逻辑推理出的必然反例,即使再不符合常理,归纳的结论也会被推翻。

比如除了上述两点,我们还知道:

③C老师签约了苹果公司代言

④苹果公司的代言人不得使用其他品牌的手机和笔记本

那么,上述“C老师使用Dell笔记本”的结论便不成立。

虽然归纳不是必然,但在解决问题时依然重要。尤其在开发中遇到错误需要 debug(调试)的时候,并不是所有错误都可以直接从报错信息看出问题(比如 Python 开发时经常出现的乱码问题),这时如果有丰富的经验和较强的归纳能力,效率会大大提升。这也是资深程序员和初级程序员之间差距的重要体现。

现在网上的编程教程铺天盖地,不过呢,大家都喜欢写写怎么编个爬虫抓图片、抓数据之类,却很少有文章愿意讲讲背后的思维过程。写了读者也不愿意看,因为看不出什么效果,哪有调几个函数就出结果来得爽快。以至于你发现,照着例子也能写个一样的代码出来,但是一旦报错或者没有预期的结果,就完全抓瞎了,只能把参数东改改西改改,反复运行,期待某一次奇迹出现。以后换个新的问题,依然不知道从何下手。

这就是因为并未理解程序背后的逻辑。我常在答疑群里说:遇到程序出错了不要去猜!要去做假设,再通过输出验证假设,最终定位问题所在。

文本只是一个引子,不可能让你对逻辑融会贯通。但前面讲的那些逻辑基础,任何一本《离散数学》或者《逻辑学》的书上都有,而且仅仅是最开始的一小部分就很受用了。找一本来看一看。真想好好学编程,不要只局限于读网上的教程,这些都是别人嚼烂喂到你嘴里的。如果你只能接受这样二次加工过的知识,而没有自己咀嚼的过程,那么你学习上的乳牙永远都掉不了。


了解逻辑学和思维具有逻辑性并不完全等价。有人没学过逻辑,说话做事一样很有逻辑性,而有的人虽然学过逻辑,也不过是当做数学公式在背,整天“逻辑思维”挂嘴边不代表做事就讲逻辑。

在网络上,你经常可以看到一些逻辑谬误,举几个常见的例子:
以偏概全:你说用X产品遇到了Y问题。有人就反驳说,我也用X产品,我身边人也用X产品,都没有问题,所以你一定是故意黑。关联当因果:某地区的人喜欢喝生牛乳,同时该地区人平均寿命高于周边地区,所以喝生牛乳可以延年益寿。非黑即白:网上都在抨击某个产品窃听用户聊天,并且之前也有发垃圾广告的前科。你说窃听从技术上来说不现实,目前也缺少明确证据。然后就有人认为你不一起喷,你就是水军、洗地、舔狗。……
类似的不讲逻辑充斥着网络。这两天,网上很多人说“不买华为就是不爱国”,对此任正非专门回应说:不要煽动民族情绪,不能把买华为与爱国简单等同起来。其实无需任总发话,这句话本身从逻辑上来说就是错误的。

不买华为→不爱国,这个命题在逻辑上应等价于它的逆否命题:爱国→买华为,也就是说爱国的人就一定会买华为。你这让拿着小米、OPPO、VIVO的爱国同胞们情何以堪。显然,爱不爱国并不由网友定义,只要存在一个爱国但未购买华为的人,这句话在逻辑上就不成立。

我们的周围有很多偏见、歧视的观念,还有很多喜欢争论的“杠精”,归根结底,你会发现这些人都有一个共同的特征:逻辑混乱。比如,之所有有人会有性别歧视、地域歧视,就是因为以偏概全地由一些特例而对整体作出推论。而反过来,有些人没有被公司录用,就归因是自己的性别或籍贯遭到了歧视,就又是另一种错误的逻辑。而偷换概念、颠倒因果、动机揣测,更是杠精们喜欢滥用的逻辑谬误。

为什么总有些人谈论观点时不讲逻辑?假定一个人要么懂逻辑,要么不懂逻辑。懂逻辑但不讲逻辑,说明他带有某种目的而刻意为之;而不懂逻辑,却还要跟人强词夺理,说明他欠缺认知能力且不自知。所以说,不讲逻辑还硬扛的人,不是__,就是__。(欢迎对号入座)

不仅仅是在编程上,如果我们更讲究逻辑,这个世界的矛盾就会少很多。即使没经过专门的学习和训练,只要保持谦逊,学会倾听,以包容的心态对待不同的声音,多去思考一下对方的观点,从不同的角度看问题,你的逻辑就会更完备。

否则,当你发现网络上全是不讲逻辑的言论时,就不想再发表任何观点了。

----

PS:留个作业:

这是『知乎』和『王者荣耀』的百度指数,王者荣耀高的时候,知乎就低,所以是不是说:如果人们不打王者荣耀,就会都来上知乎呢?[手动狗头]

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即加入

QQ|手机版|Archiver|Crossin的编程教室 ( 苏ICP备15063769号  

GMT+8, 2024-11-25 14:31 , Processed in 0.023817 second(s), 22 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部