导读:编程的必要知识,也是日常的基本能力。
作者:Crossin先生
来源:Crossin的编程教室(ID:crossincode)
“英语不好能不能学编程?”
“编程是不是对数学要求很高?”
翻译一下就是:数学/英语是否是学编程先决条件?
我觉得这个问题有点像,身高不高能不能打篮球一样。虽然对于职业篮球运动员来说,身高是非常关键的因素,但对于普通篮球爱好者,甚至一个篮球相关从业人员来说,这并不是非要不可的条件。放到编程上,数学和英语都很重要,但:
  1. 在入门阶段,你完全不用在意这些,照着一本教程好好跟着模仿就行
  2. 对于大部分的日常开发来说,中学程度的数学和英语水平已经可以应付
  3. 和身高这种先天条件不同,英语和数学是可以通过学习提高的,哪里不足补哪里呗。网上流行一句话:“以大多数人的努力程度之低,根本轮不到拼天赋。”你能长期坚持背背单词,看看书,就足以提升自己。总是把XX不好挂在嘴上恐怕更多是在给自己找借口。
不过,有一项能力,确实是在学习编程初期就需要足够重视的。然而这一点,很多教程不会专门强调,相关书籍也往往假定你已经掌握,以至于很多学习者并没有意识到自己在此方面的薄弱,为之后的学习留下隐患。我要说的就是:
  • 逻辑
某种角度来说,逻辑可部分算作是数学,在高中数学课本中就有相关内容。这部分内容也恰好是我们学编程时最需要了解的基础。
01 布尔代数
真(1)、假(0)两种状态,以及与(and)、或(or)、非(not)三种基本运算组成。布尔代数看似简单,却与数字电路中开和关两种状态相对应,是计算机的逻辑基础。你可能听说过,电脑上的一切在内部都是由0和1所表示,那换句话说,计算机的所有行为,本质都是由布尔逻辑所实现的。
在编程语言中,布尔类型(bool)也是极为重要的存在。没有它,我们就做不了条件判断,也就无从控制程序的执行。Python 的 if、while 语句都必须依赖布尔类型作为判断条件。
因此,即使你不想深入学习逻辑,布尔代数的基本规则也是无论如何必须了解的。简单来说,就是下面这张“真值表”
p
q
not p
p and q
p or q
1
1
0
1
1
0
1
1
0
1
1
0
0
0
1
0
0
1
0
0
这些基本规则又会组合出更复杂的逻辑,比如: 
not (p or q) 等价于 (not p) and (not q)
(示例:“不是管理员或者会员”相当于“不是管理员且不是会员”)
实际开发中面临的逻辑判断复杂多样,但归根结底还是会转化到最基本的这几个规则上。
思考题1:如何用逻辑语言表示“通过活动注册的新用户或者充值超过100元的老用户,内部人员除外”
02 命题逻辑
真值唯一的陈述句叫做命题,不能分解成更简单的命题叫做原子命题。比如,“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点开放,普通用户每天可以领取一次,会员用户可以在每个时段分别领取一次。如何实现这段程序的逻辑结构?(我时常拿这个作为面试题,很多人都不能在短时间内给出正确的答案)
03 归纳
有时候,我们并不能通过逻辑推导出必然的结论,但仍然可以通过一系列的经验和已有结论,找出其中基本遵循的规律。
比如:
①X团队历来给所有成员都配备Dell笔记本作为工作电脑
②C老师最近刚加入X团队
通过这两点,我们可以推导出,C老师很可能也使用Dell笔记本。
但你要清楚归纳的结论并不必然为真,如果遇到逻辑推理出的必然反例,即使再不符合常理,归纳的结论也会被推翻。
比如除了上述两点,我们还知道:
③C老师签约了苹果公司代言
④苹果公司的代言人不得使用其他品牌的手机和笔记本
那么,上述“C老师使用Dell笔记本”的结论便不成立。
虽然归纳不是必然,但在解决问题时依然重要。尤其在开发中遇到错误需要 debug(调试)的时候,并不是所有错误都可以直接从报错信息看出问题(比如 Python 开发时经常出现的乱码问题),这时如果有丰富的经验和较强的归纳能力,效率会大大提升。这也是资深程序员和初级程序员之间差距的重要体现。
现在网上的编程教程铺天盖地,不过呢,大家都喜欢写写怎么编个爬虫抓图片、抓数据之类,却很少有文章愿意讲讲背后的思维过程。写了读者也不愿意看,因为看不出什么效果,哪有调几个函数就出结果来得爽快。
以至于你发现,照着例子也能写个一样的代码出来,但是一旦报错或者没有预期的结果,就完全抓瞎了,只能把参数东改改西改改,反复运行,期待某一次奇迹出现。以后换个新的问题,依然不知道从何下手。
这就是因为并未理解程序背后的逻辑。我常在答疑群里说:遇到程序出错了不要去猜!要去做假设,再通过输出验证假设,最终定位问题所在。
文本只是一个引子,不可能让你对逻辑融会贯通。但前面讲的那些逻辑基础,任何一本《离散数学》或者《逻辑学》的书上都有,而且仅仅是最开始的一小部分就很受用了。找一本来看一看。
真想好好学编程,不要只局限于读网上的教程,这些都是别人嚼烂喂到你嘴里的。如果你只能接受这样二次加工过的知识,而没有自己咀嚼的过程,那么你学习上的乳牙永远都掉不了。
了解逻辑学和思维具有逻辑性并不完全等价。有人没学过逻辑,说话做事一样很有逻辑性,而有的人虽然学过逻辑,也不过是当做数学公式在背,整天“逻辑思维”挂嘴边不代表做事就讲逻辑。
在网络上,你经常可以看到一些逻辑谬误,举几个常见的例子:
  • 以偏概全:你说用X产品遇到了Y问题。有人就反驳说,我也用X产品,我身边人也用X产品,都没有问题,所以你一定是故意黑。
  • 关联当因果:某地区的人喜欢喝生牛乳,同时该地区人平均寿命高于周边地区,所以喝生牛乳可以延年益寿。
  • 非黑即白:网上都在抨击某个产品窃听用户聊天,并且之前也有发垃圾广告的前科。你说窃听从技术上来说不现实,目前也缺少明确证据。然后就有人认为你不一起喷,你就是水军、洗地。
  • ……
类似的不讲逻辑充斥着网络。
我们的周围有很多偏见、歧视的观念,还有很多喜欢争论的“杠精”,归根结底,你会发现这些人都有一个共同的特征:逻辑混乱。比如,之所有有人会有性别歧视、地域歧视,就是因为以偏概全地由一些特例而对整体作出推论。而偷换概念、颠倒因果、动机揣测,更是杠精们喜欢滥用的逻辑谬误。
不仅仅是在编程上,如果我们更讲究逻辑,这个世界的矛盾就会少很多。即使没经过专门的学习和训练,只要保持谦逊,学会倾听,以包容的心态对待不同的声音,多去思考一下对方的观点,从不同的角度看问题,你的逻辑就会更完备。
感谢转发和点赞的各位~
延伸阅读👇
延伸阅读《因果论:模型、推理和推断》
干货直达👇
更多精彩👇
在公众号对话框输入以下关键词
查看更多优质内容!
读书 | 书单 | 干货|讲明白|神操作 | 手把手
大数据 | 云计算 | 数据库 | Python | 爬虫 | 可视化
AI | 人工智能 | 机器学习 | 深度学习 | NLP
5G|中台 | 用户画像数学 | 算法 数字孪生
据统计,99%的大咖都关注了这个公众号
👇
继续阅读
阅读原文