learn-tech/专栏/程序员的数学课/00开篇词数学,编程能力的营养根基.md
2024-10-16 09:22:22 +08:00

93 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

因收到Google相关通知网站将会择期关闭。相关通知内容
00 开篇词 数学,编程能力的营养根基
你好,我是公瑾,欢迎来到《程序员的数学课》。一些同学可能知道,之前我在拉勾教育就开设了一个[《数据结构与算法》]课程,目的是帮助大家提升编码能力,打牢代码基础,在结课时也受到许多同学的好评,表示所讲的内容在面试和工作中都很有实用性。
编程一类的基础能力固然重要,但这些依旧不是程序员全部的“立足之本”。个人角度而言,从我在中科院的博士研究生经历,再到后来从事机器学习、数据挖掘等算法研发工作,都是数学作为我的基础思维能力支撑我一路走来。
程序员为什么要注重数学?
在[《数据结构与算法》]课程中,许多留言问题高频集中在:复杂度如何计算、某个代码优化是否降低了时间复杂度,或者是动态规划的状态转移方程问题,等等。这的确是在学习数据结构中遇到的困难,但剥离了外壳之后,你会发现本质上都是数学问题。
举个例子,对于一个有序数组中查找目标值的问题,应该采用二分查找算法。而且随着数组元素越来越多,二分查找相对全局遍历而言,性能上的优势会越来越明显。从数学视角来看,这是因为当 x 很大时lnx <。比如 x=100ln100=4.6 << 100
y=lnx y=x 的函数图
可能许多同学知道二分查找效率更高但二分查找的代码是需要采用递归进行实现的很多同学为了实现方便就会考虑采用暴力搜索的查找方式也就是一个 for 循环搞定但如果你知道了它背后的数学原理并且深刻体会到 ln100=4.6 << 100你就再也不会用 for 循环去实现有序数组的查找问题了
此外数学还可以帮助你降低代码的复杂度
我们看一个编程问题一个数组中只有数字 obj 出现了一次其他数字都出现了两次请查找出 obj约束为 O(n) 的时间复杂度O(1) 的空间复杂度
例如在数组 a = [2,1,4,3,4,2,3] 则输出 1因为 234 都出现了两次唯独 1 只出现一次
这是个在无序数组中涉及与其他元素匹配的查找问题常规解法的复杂度应该是O(n²) 时间复杂度O(1) 空间复杂度或者 O(n) 时间复杂度O(n) 空间复杂度显然这并不符合题目的约束
要想解决这个问题需要借助数学的异或运算异或有这样两个性质第一任何数异或自己为零第二任何数异或零是它自己借助异或运算你只需要把数组 a 中所有元素计算一下异或就可以得到 obj 实现起来就是如下所示的 O(n) 时间复杂度的 for 循环且不需要额外开辟复杂变量
a = [2,1,4,3,4,2,3]
result = a[0]
for i in range(1,len(a)):
result = result ^ a[i]
print result
从上面的例子中你便能认识到数学的重要性越是优雅的程序越是能用简单的代码实现同样的需求
工作场景之外在求职面试中大量的算法题也是对程序员数学能力的考察与其直接海量刷题不如先打好知识基础和建好思维逻辑再有方法论地刷题才能未雨绸缪有备无患
程序员学数学有哪些痛
下定决心开始学习数学之后绝大多数的程序员都会面临下面几个问题
第一数学的海洋过于广阔不知道学什么
从数学的知识体系看它至少包括了微积分线性代数几何概率论数理统计等内容而对于程序员只需要精通那些对代码开发有指导性帮助的数学知识就足够了那么哪些数学是必要的呢又如何区分必备的数学知识的边界呢这对于许多程序员来说是模糊的
第二各种数学理论如何联系到工作实践中
结合前面降低代码复杂度的例子你会发现自己很难想到利用异或去查找前面数组中的 obj先从编程思想来看时间复杂度是 O(n)这就意味着可以使用一个 for 循环空间复杂度是 O(1)这就意味着处理过程只能做一些基本运算
接着围绕题目来看除了 obj 以外的元素都出现两次突发奇想一下如果可以有一个类似于连连看的计算能把相同元素清掉最终不就只保留了 obj 相同元素清掉这就是异或运算口诀中的同零异一这就与异或的数学运算构建了联系因此学习数学时死读书是没用的必须落地到实践做到知行合一
第三数学本身很难工作又很忙不知道怎么学
不得不说数学并不简单学好数学必要的时间脑力投入肯定少不了然而程序员节奏紧张工作压力大这就要求程序员在学习数学的时候必须掌握学习方法提高学习效率这也是我们本课程要解决的问题
我将怎么带你学数学
如果你是数学专业者需要追求大而全但如果是程序员用得上的数学大而全便会失去意义工作若干年后的你会发现很多数学知识学得慢忘得快而且工作中还用不到所以你应该放弃学生时代学习数学的思路这里我很建议你遵循以下学习理念
首先聚焦自己的工作领域明确哪些是你必备的例如位运算数学归纳法最优化算法等对这些知识的精通可以奠定你知识体系的基础此外所有的学习都要落地在实践你需要不断复习巩固知识加深对知识点的理解深度达到灵活运用的状态在实际工作中利用数学思想去解决问题
因此这门专栏会非常聚焦程序员场景我会根据我多年的从业经历提炼出程序员必须具备的数学知识专栏主要分为以下四个模块
模块一无处不在的数学思维 带你在数制中体验编程用逻辑工具提升沟通能力并通过数学思维进行业务决策再从数学角度出发重新审视万物背后的数学原理让你对数学思维有全新认知
模块二编程基础代数与统计 数学作为编程基础我从线性代数概率论与统计等基础内容中精挑细选出程序员必备的数学知识并结合大量案例讲解以全新视角带你认识理论数学在实际工作中的应用而这些内容也是之后实战应用部分的理论基础便于你之后的学习
模块三数学实战算法与数据结构 算法和数据结构中存在大量的数学问题脱离数学去孤立地看它们一定是事倍功半的在这个模块我会与你一起复习基础算法并从数学的角度向你诠释基础算法背后的规律同时对每个知识点我还会给出实战场景加强你的理解深度
模块四数学应用AI 与机器学习 AI 是近年来很火的技术方向其实 AI 和机器学习技术的外壳剥开它就是一个最优化的问题也就是个数学问题在这个模块我会围绕 AI 的几个常用技术点从数学的角度抽象出它的技术核心即使你对 AI 还不是很熟悉也可以从数学的角度把握住 AI 建模的主要脉络
最后彩蛋部分我将与你分享工作与生活中的数学智慧带你在数学方法论的指导下击破算法题告别盲刷并在决策的十字路口教你用数学为自己补充智慧锦囊
以上这几个模块虽然仅是数学的冰山一角但已经足够程序员的工作所需希望学会这些知识后你能在意识方面建立起必备的数学敏感度并具备对业务问题分析拆解的数学逻辑以及掌握实际开发中利用数学原理优化代码结构的能力
讲师寄语
最后我想告诉你的是数学如同阅读一样我们无法说清我们现在的思维能力见识是由哪本书带来的就像我们不知道是曾经的哪口食物把我们从婴孩变成了健康活力的大人
所以说数学虽然无法立竿见影但却能潜移默化地影响我们的思维行动工作为我们提供思维的营养根基魏征的谏太宗十思疏有云求木之长者必固其根本欲流之远者必浚其泉源同样我们在成长路上不仅需要学完即用的技能更需要静下心来修炼基本功最后希望数学能够伴随你在成长路上越走越远