前面的课时,我们学习了“代数与统计”“算法与数据结构”,至今这门课程的主体知识已告一段落,下面我们进入彩蛋环节,我会向你介绍两个应用到数学的场景,第一个是求职面试,第二个是做人生规划。

这一讲,我们先聊一聊求职面试时常见的数学题。

毕业后,相信你一定参加过不少的面试吧。在求职面试的时候,即使目标工作岗位很少需要直接使用数学知识,也依然有不少面试官非常注重候选人的数学水平,而这并不是没有依据的。因为绝大多数的岗位,都需要候选人具有逻辑推理能力和解决问题的能力。而这些能力在数学上都能有所体现。

下面,我们通过三个例题,带大家体验一下面试中的数学。

例题1 抛硬币问题

假设你和大漂亮在玩抛硬币游戏。硬币的正面朝上可得 1 分,背面朝上则分数不变。如果大漂亮可以抛 51 次硬币,而你只能抛 50 次硬币,那么大漂亮分数比你高的概率是多少?

这个问题如果用计算机进行仿真求解,就会非常容易,我们给出下面的代码。

import random
dapiaoliang = 0
you = 0
win = 0
for _ in range(1000):for _ in range(51):if random.randint(0,1) == 1:dapiaoliang += 1for _ in range(50):if random.randint(0,1) == 1:you += 1if dapiaoliang > you:win += 1dapiaoliang = 0you = 0
print win

我们对代码进行走读:

  • 第 3、4 行,分别定义两个变量来保存大漂亮和你的得分;

  • 第 5 行,用 win 变量来记录大漂亮获胜的次数;

  • 第 6 行开始,执行一个重复 1000 次的循环;

  • 在每次的循环内部,先在第 7~9 行,通过 51 次的循环,模拟出大漂亮的得分;

  • 再在第 10~12 行,通过 50 次的循环,模拟出你的得分;

  • 在 13、14 行判断,如果大漂亮分数比你高,则大漂亮获胜一局。

最终,打印出大漂亮获胜的局数。我们运行代码的结果如下图。

可见,在 1000 次的游戏中,大漂亮获胜了 502 次。这样,我们可以估算出,大漂亮获胜的概率为 0.502。

【数学角度解答】

我们再从数学的角度重新计算一下这道题。在这里,我们需要通过加乘法则去拆解一下事件。假设 A 事件代表大漂亮抛 51 次硬币的得分,B 事件代表你抛 50 次硬币的得分,要计算的目标是 A 大于 B 的概率 P(A>B)。

每次抛硬币是独立的事件,独立事件共同发生的概率满足乘法法则。因此,可以把大漂亮的得分,拆解为前 50 次抛硬币的得分(M 事件)和最后一次抛硬币的得分( N 事件)。

而其中,最后一次抛硬币,只有正面得 1 分或者背面得 0 分两种情况。

对于一个事件的两个可能的结果分支,可以通过加法法则来求概率,因此有下面的公式。

P(A>B)=P(M+N>B)=
P(N=0)·P(M+0>B)+P(N=1)·P(M+1>B)=
0.5·P(M+0>B) + 0.5·P(M+1>B)

对于最后一项 P(M+1>B) 等价于 P(M≥B)。这是因为,如果 M 大于或等于 B,则 M+1 必然是大于 B 的;反过来,M 和 B 是抛硬币正面朝上的次数,所以必然是整数。如果 M+1 比 B 大,那么 M 必然会大于或等于 B。因此,有二者概率相等,即 P(M+1>B) = P(M≥B)。

我们把这个关系带入到 P(A>B) 中,则有 P(A>B)=0.5·P(M>B)+0.5·P(M>=B)

再根据加法法则,则有 P(A>B)=0.5·P(M>B)+0.5·P(M>B)+0.5·P(M=B)

别忘了,M 事件代表“大漂亮前 50 次抛硬币的得分”,而 B 事件是“你抛 50 次硬币的得分”。区别只剩下了抛硬币的人不一样。不管是谁抛硬币,正面朝上的概率始终都是1/2。所以从结果来看,这两个事件是完全等价的,

则有 P(M>B) = P(M<B)。

因此 P(A>B)
= 0.5·P(M>B)+0.5·P(M<B)+0.5·P(M=B) = 0.5·[P(M>B)+P(M<B)+P(M=B)]

注意:M 和 B 的关系只有大于、小于或者等于,所以 P(M>B)+P(M<B)+P(M=B) 之和为 1。因此,可以得到结果为 P(A>B) = 0.5·[P(M>B)+P(M<B)+P(M=B)] = 0.5

这与我们用代码仿真计算的结果是一致的。

例题2 数据上溢问题

对于一个 Sigmoid 函数,y=1/(1+e-x)。假设输入的自变量 x 很小,为 -1000000。因为要先计算 e-x 的值,即 e1000000,如下图所示,直接计算就会先得到一个非常大的数字而抛出异常。那么在线上代码中,该如何规避这种情况,计算出输出值呢?

其实,这里可以用到一个非常简单的技巧,对公式做个变形就能让程序适应这种情况了。我们知道,Sigmoid 函数的结果是一个在 0~1 之间的连续值。而之所以产生数据溢出是因为要先计算e-x 的值。处理这种情况,我们可以从数学的角度,对分子和分母都乘以 ex 这一项,则有

y = 1/(1+e-x) = ex/(ex+1)。

此时,输入 x=-1000000,则需要计算 ex,得到结果为 0.0。再带入到 Sigmoid 函数中,就可以得到结果啦。

可能你还会问,对公式做了变形之后,如果 x 为很大的正数,如 1000000,岂不是又数据溢出抛异常了吗?如果 x 为很大的正数,我们直接用 Sigmoid 函数的原始形态 y=1/(1+e-x) 就可以了。

综合上面两种情况,我们可将x分正数及非正数分别计算,来避免数据的溢出。即

  • 如果 x>0,则 y = 1/(1+e-x)

  • 如果 x<0,则 y = ex/(1+ex)

实现的代码如下:

import math
def sigmoid(x):if x < 0:y = math.pow(math.e,x) / (1 + math.pow(math.e,x))else:y = 1 / (1 + math.pow(math.e,-x))return y
a = -1000000
b = 1000000
print sigmoid(a)
print sigmoid(b)

我们对代码进行走读:

  • 在 Sigmoid 函数的代码中,第 4 行,判断 x 和 0 的大小关系;

  • 如果 x 为负数,则通过第 5 行的公式计算 y;

  • 如果 x 不是负数,则通过第 7 行的公式来计算 y。

我们在主函数中,分别输入了非常小和非常大的两个数字,并顺利得到结果分别为 0.0 和 1.0,如下图所示。

例题3 投点距离期望问题

假设在墙上有一个半径为 10 厘米的圆形区域,现在大迷糊用飞镖向这个圆形区域进行均匀随机的投射。假设大迷糊不会“脱靶”,求大迷糊扎到的点到圆形区域圆心距离的期望。

这个题用代码仿真会非常容易,我们给出下面的代码。

import random
import math
inCircle = 0
distance = 0.0
for _ in range(1000):x = 1.0 * random.randint(0,1000) / 100y = 1.0 * random.randint(0,1000) / 100if x * x + y * y > 100:continueelse:inCircle += 1distance += math.sqrt(x * x + y * y)
print distance / inCircle

我们对代码进行走读:

  • 第 4 行,保存合法的投射次数变量;

  • 第 5 行,是累计的距离之和变量;

  • 第 6 行,通过 for 循环执行多次的投射动作;

  • 每次投射,第 7 行和第 8 行,随机地生成投射点的坐标变量 x 和 y(在这里,我们精确到小数点后两位);

  • 第 9 行,如果坐标点的平方和超过 100,也就是投射点在 10 厘米的圆形之外;

  • 那么第 10 行,执行 continue,继续下一轮循环;

  • 否则,说明投射点在圆内,执行第 11 行的代码;

  • 第 12 行,合法投射次数加 1;

  • 第 13 行,通过本次投射点到圆心的距离,更新累计的距离之和;

  • 最后第 14 行,打印累计距离和合法投射次数的比值,得到了平均距离。

这也是投射点到圆心距离的期望,我们运行代码的结果为 6.66 厘米,如下图所示。

接下来,我们再从数学的角度来计算一下这个题目。

【数学角度解答】

题目中,要求解的是一个点到圆心距离这个随机变量的期望。很显然,点到圆心的距离是个连续值。要求某个连续型随机变量的期望,可以用期望的定义式来计算,即

所以,当你在工作中遇到“某连续型变量的期望”时,它一定可以写成上面的积分形式,这是定义式,也是公理。

在我们这个问题中,随机变量 x 是点到圆心的距离。由于投射点不可以在圆形以外,所以这个距离的取值范围是 0~10。因此,我们可以把上面的公式改写为

那么问题来了,这里的概率密度函数 f(x) 的表达式是什么呢?别忘了,概率论告诉我们,概率密度函数是概率分布函数的导数。

我们不妨试着求一下投射问题的概率分布函数。假设在圆内有一个小圆,半径是 x0。那么投射点恰好也在小圆内的概率为 P(x<x0) = π·x02/π·102 = x02/102

因此,概率分布函数为 F(x) = x2/102;又因为,概率密度函数是概率分布函数的导数,所以概率密度函数为 f(x) = 2x/102

我们把这些条件都带入到期望的公式中,则有

这与我们用代码求解的 6.66 厘米是一致的。

小结

我们对这一讲进行总结。这一课时的内容是面试中的数学,面试官会通过一个简单的数学题,考察候选人解决问题的思考路径。

数学题的魅力就在于活学活用,你很难遇到同一道题,所以靠死记硬背是不行的。只有深入理解数学原理,才能做到在面试的数学考察中游刃有余。在备考的时候,应该注意在基本功方面多花时间去做到深入理解。对于每个知识点的适用范围,来龙去脉做到掌握。

如果你遇到了一个让你束手无策的题目,不妨试着从下面两个角度寻找突破口。

  • 第一个角度,从问题出发去寻找突破口。

例如,本课时的投点距离期望问题。这个题目要计算的是连续型随机变量的期望,那么它一定可以用连续型随机变量期望的定义式表示。接下来,问题就变成了对这个定义式的未知量进行计算求解。

  • 第二个角度,从已知条件出发去寻找突破口。

例如,在抛硬币问题中,已知条件是大漂亮抛了 51 次,你抛了 50 次。抛 51 次,可以拆分为抛 50 次和抛 1 次。这样,我们就得到了大漂亮抛 50 次和你抛 50 次,这样等价的两个事件。基于这两个事件,就能推导出大漂亮得分比你高的概率。

这些寻找突破口的方法,是候选人解决问题能力的集中体现;也是数学题、算法题千变万化后,唯一不变的规律。

下一讲,我将向你讲解《23 | 站在生活的十字路口,如何用数学抉择?》让你用数学为自己补充智慧锦囊。


精选评论

程序员的数学课22 面试中那些坑了无数人的算法题相关推荐

  1. mopso算法代码程序_JAVA程序员的必杀技,面试中常考的8个经典算法题,过程精妙,代码精炼...

    总有一些题,超越了岁月,即便是经过了新框架的层层迭代,它依然散发着令人回味无穷的味道.下面的几个笔试题目,是JAVA面试中经常遇见的,大家一定要牢记于心,可别复习到了到时候又说不出来.我就吃过这种亏, ...

  2. 在这个天上掉块馅饼都能砸死10个程序员的年代,程序员该如何在面试中脱颖而出...

    本文为原创资源,欢迎分享,转载. JAVA开发大本营 前言:在这个遍地培训班,程序员已经过剩的年代,又恰好遇到互联网寒冬,天上掉个馅饼,都能砸死10个程序员.大量的公司进行裁员,但是也有一部分公司在进 ...

  3. 程序员如何面对 HR 面试的 40 个问题

    转载自 程序员如何面对 HR 面试的 40 个问题! 讲一个身边朋友亲身经历的故事吧. 一个技术非常牛的朋友去阿里面试,成功通过了几轮技术车轮战,最后躺在了 HR 面上...所以,尽管你技术再牛逼,你 ...

  4. Web前端程序员该如何准备面试?这些面试知识应该掌握

    面试其实是实力和运气并存的事情,所以一方面我们要做好知识的准备,另一方面也要抓住时机,该出手就出手,那么Web前端程序员该如何准备面试呢?下面和一起来看看吧! 一:Web前端面试什么? 针对Web前端 ...

  5. Java程序员跳槽涨薪面试心得

    面试候选人的时候,有个比较常见的问题:对于一份工作,你最关注哪些因素?回答往往是薪资待遇,公司氛围,公司发展前景,工作强度等.个人比较欣赏的答案是:个人能力的成长.想收获一个薪资好,公司发展前景好的工 ...

  6. 只有程序员看的懂面试圣经

    技术圈 只有程序员看的懂面试圣经|如何拿下编程面试 http://www.epubit.com.cn/article/197 当我最初开始参加编程面试的时候,我所有最心仪的公司都忽视了我.现在回头看那 ...

  7. 【程序员必修数学课】->基础思想篇->递归(下)->分而治之从归并排序到MapReduce

    递归(下) 前言 归并排序中的分治思想 分布式系统中的分治思想 1.数据分割和映射 2.归约 3.合并 总结 前言 在上一篇中,我介绍了如何使用递归,来处理迭代法中比较复杂的数值计算.但是我们知道,有 ...

  8. Java程序员裸辞,跳槽面试屡屡被拒,终拿美团offer面经分享如下

    Java程序员裸辞,跳槽面试屡屡被拒,终拿美团offer面经分享如下 我是一名本科毕业但是非计算机专业的程序员,上个月面完了阿里,结果是没通过,然后上周又面了美团,上周五才面完了HR面,我自己感觉希望 ...

  9. 程序员糗事--爆笑中====

    程序员糗事--爆笑中==== 似乎任何职业都会给从业人员带来这样那样的习惯.国外某网站上有位朋友(应该也是程序员)想了解其他程序员在投身堆码事业后有什么样的坏习惯.结果一呼百应,很多程序员纷纷自爆自己 ...

最新文章

  1. 自制pyBoard的I2C实验,应用MicroPython
  2. Gartner称2016会是Windows 10的“企业之年”
  3. html 书架样式css,CSS3 响应式书架布局
  4. android 自定义图片上传,android自定义ImageView仿图片上传(示例代码)
  5. base64下载excel (使用blob)
  6. 前端学习(2661):生命周期
  7. java中static关键字简介
  8. IllegalStateException: Error reading delta file hdfs://xxx/spark/xx/state/0/11/1.delta
  9. isinstance / issubclass / type, 方法和函数, 反射
  10. 匹配中文字符的正则表达式
  11. 评价指标MSE和AUC的参考文献
  12. 【Atomikos】分布式事务简单示例
  13. Java SE 12 新增特性
  14. 【读书笔记】之蔡康永的说话之道
  15. Unity il2cpp new 内存分配过程
  16. DSSD : Deconvolutional Single Shot Detector论文阅读笔记
  17. Debian6.0安装后系统基本配置
  18. eclipse不能启动
  19. 后一个数 减 前一个数 形成新列表
  20. .cc注册规则有哪些 CC域名前景怎么样

热门文章

  1. 推特“大V”僵尸粉太多?马斯克质疑“推特正没落”
  2. 如何轻松归档文件?2种方法轻松创建归档文件!
  3. 16s之稀释曲线绘制
  4. 异常----素质三连(try-catch-finally)
  5. 思科网络安全 第三章测验答案
  6. mac版PHPstudy集成环境
  7. 几种优化算法的读书笔记——梯度下降、牛顿法、拟牛顿法、随机梯度下降、AdaGrad、RMSProp、Adam及选择优化算法的建议
  8. MacBook键盘无法正常工作?故障排除指南
  9. autodesk inventor2014 64位32位 免序列号版
  10. 整理了一份github上比较热门的ChatGPT项目,值得收藏