渐faa522学 是谁的教练车!

&p&此套视频分六大阶段,每一阶段都逐渐加深,此套教程已经整理的非常完善,各位学习者基本上按照此套流程,一阶段,一阶段学习来,肯定会入门,逆袭成为大牛。&/p&&p&&b&第一阶段:&/b&&/p&&figure&&img src=&https://pic4.zhimg.com/50/v2-8a4bbdfa0_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&455& data-rawheight=&619& class=&origin_image zh-lightbox-thumb& width=&455& data-original=&https://pic4.zhimg.com/50/v2-8a4bbdfa0_r.jpg&&&/figure&&p&&br&&/p&&p&Java基础视频教程&/p&&p&1、毕向东老师的java入门教程&/p&&p&2、小白的福音java入门教程&/p&&p&3、java快速入门教程&/p&&p&此三个教程异曲同工,内容知识点相差不大,可以只学习其中一个哦!&/p&&p&&br&&/p&&p&&b&第二大阶段:&/b&&/p&&figure&&img src=&https://pic2.zhimg.com/50/v2-1bbc6f14d55c4a78ce1c4cf_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&556& data-rawheight=&516& class=&origin_image zh-lightbox-thumb& width=&556& data-original=&https://pic2.zhimg.com/50/v2-1bbc6f14d55c4a78ce1c4cf_r.jpg&&&/figure&&p&Java教程&/p&&p&(1)轻松掌握JavaWeb视频教程&/p&&p&(2)6天玩转mysql视频教程&/p&&p&(3)超全面的JavaWeb视频教程&/p&&p&(4)阶段案例--JavaWeb网上图书商城完整&/p&&p&&b&第三大阶段:&/b&&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/50/v2-14d1a66ec3f9b62cffb4_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&561& data-rawheight=&534& class=&origin_image zh-lightbox-thumb& width=&561& data-original=&https://pic1.zhimg.com/50/v2-14d1a66ec3f9b62cffb4_r.jpg&&&/figure&&p&Java教程&/p&&p&(1)Hibernate5框架&/p&&p&(2)Struts2框架&/p&&p&(3)Spring框架&/p&&p&
Spring2.5视频教程&/p&&p&&b&第四大阶段:&/b&&/p&&p&&b&知识点:&/b&&/p&&figure&&img src=&https://pic1.zhimg.com/50/v2-1aa1faf4bdecb_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&394& data-rawheight=&700& class=&content_image& width=&394&&&/figure&&p&&br&&/p&&p&Java教程&/p&&p&(1)ORACLE经典视频教程&/p&&p&(2)Maven精品教程&/p&&p&&b&第五大阶段:&/b&&/p&&figure&&img src=&https://pic2.zhimg.com/50/v2-cb915bd31f5712ecc220ec89dcf0f640_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&560& data-rawheight=&444& class=&origin_image zh-lightbox-thumb& width=&560& data-original=&https://pic2.zhimg.com/50/v2-cb915bd31f5712ecc220ec89dcf0f640_r.jpg&&&/figure&&p&Java教程推荐:&/p&&p&(1) Springmvc由浅入深全套视频教程&/p&&p&(2)Mybatis由浅入深全套视频教程&/p&&p&&br&&/p&&p&&b&第六大阶段:&/b&&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/50/v2-6bfe45c416ca1de7237221_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&517& data-rawheight=&379& class=&origin_image zh-lightbox-thumb& width=&517& data-original=&https://pic4.zhimg.com/50/v2-6bfe45c416ca1de7237221_r.jpg&&&/figure&&p&Java教程推荐:&/p&&p&(1)Java学科巴巴运动网视频教程106集&/p&&p&(2)巴巴运动网续集视频教程&/p&&p&以上就是Java学习路线图的内容,具体配套视频有需要的小伙伴可以私信我,码字不易,有用请点赞分享一下吧!&/p&
此套视频分六大阶段,每一阶段都逐渐加深,此套教程已经整理的非常完善,各位学习者基本上按照此套流程,一阶段,一阶段学习来,肯定会入门,逆袭成为大牛。第一阶段: Java基础视频教程1、毕向东老师的java入门教程2、小白的福音java入门教程3、java快速入…
&figure&&img src=&https://pic3.zhimg.com/v2-bdf214db27e9_b.jpg& data-rawwidth=&900& data-rawheight=&500& class=&origin_image zh-lightbox-thumb& width=&900& data-original=&https://pic3.zhimg.com/v2-bdf214db27e9_r.jpg&&&/figure&&p&在今年八月中旬,《指尖大冒险》SNS 游戏诞生,其具体的玩法是通过点击屏幕左右区域来控制机器人的前进方向进行跳跃,而阶梯是无穷尽的,若遇到障碍物或者是踩空、或者机器人脚下的阶砖陨落,那么游戏失败。&/p&&blockquote&笔者对游戏进行了简化改造,点击&a href=&https://link.zhihu.com/?target=http%3A//jdc.jd.com/demo/ting/H5Game/jumping/index.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&这里&/a&进行体验。&/blockquote&&figure&&img src=&https://pic1.zhimg.com/v2-899cf656fdd_b.jpg& data-size=&normal& data-rawwidth=&187& data-rawheight=&333& class=&content_image& width=&187&&&figcaption&《指尖大冒险》SNS 游戏&/figcaption&&/figure&&p&该游戏可以被划分为三个层次,分别为景物层、阶梯层、背景层,如下图所示。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-7fc7ab1e2ab9_b.jpg& data-size=&normal& data-rawwidth=&619& data-rawheight=&417& class=&origin_image zh-lightbox-thumb& width=&619& data-original=&https://pic4.zhimg.com/v2-7fc7ab1e2ab9_r.jpg&&&figcaption&《指尖大冒险》游戏的层次划分&/figcaption&&/figure&&p&整个游戏主要围绕着这三个层次进行开发:&/p&&ul&&li&景物层:负责两侧树叶装饰的渲染,实现其无限循环滑动的动画效果。&/li&&li&阶梯层:负责阶梯和机器人的渲染,实现阶梯的随机生成与自动掉落阶砖、机器人的操控。&/li&&li&背景层:负责背景底色的渲染,对用户点击事件监听与响应,把景物层和阶梯层联动起来。&/li&&/ul&&p&而本文主要来讲讲以下几点核心的技术内容:&/p&&ol&&li&无限循环滑动的实现&/li&&li&随机生成阶梯的实现&/li&&li&自动掉落阶砖的实现&/li&&/ol&&p&下面,本文逐一进行剖析其开发思路与难点。&/p&&h2&一、无限循环滑动的实现&/h2&&p&景物层负责两侧树叶装饰的渲染,树叶分为左右两部分,紧贴游戏容器的两侧。&/p&&p&在用户点击屏幕操控机器人时,两侧树叶会随着机器人前进的动作反向滑动,来营造出游戏运动的效果。并且,由于该游戏是无穷尽的,因此,需要对两侧树叶实现循环向下滑动的动画效果。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-3c8fc911df90e2104dbf280e70de11f4_b.jpg& data-size=&normal& data-rawwidth=&900& data-rawheight=&569& class=&origin_image zh-lightbox-thumb& width=&900& data-original=&https://pic1.zhimg.com/v2-3c8fc911df90e2104dbf280e70de11f4_r.jpg&&&figcaption&循环场景图设计要求&/figcaption&&/figure&&p&对于循环滑动的实现,首先要求设计提供可前后无缝衔接的场景图,并且建议其场景图高度或宽度大于游戏容器的高度或宽度,以减少重复绘制的次数。&/p&&p&然后按照以下步骤,我们就可以实现循环滑动:&/p&&ul&&li&重复绘制两次场景图,分别在定位游戏容器底部与在相对偏移量为贴图高度的上方位置。&/li&&li&在循环的过程中,两次贴图以相同的偏移量向下滑动。&/li&&li&当贴图遇到刚滑出游戏容器的循环节点时,则对贴图位置进行重置。&/li&&/ul&&figure&&img src=&https://pic3.zhimg.com/v2-832f53cdddcdca35f7b57c4d2ed763ce_b.jpg& data-size=&normal& data-rawwidth=&778& data-rawheight=&560& data-thumbnail=&https://pic3.zhimg.com/v2-832f53cdddcdca35f7b57c4d2ed763ce_b.jpg& class=&origin_image zh-lightbox-thumb& width=&778& data-original=&https://pic3.zhimg.com/v2-832f53cdddcdca35f7b57c4d2ed763ce_r.jpg&&&figcaption&无限循环滑动的实现&/figcaption&&/figure&&p&用伪代码描述如下:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// 设置循环节点&/span&
&span class=&nx&&transThreshold&/span& &span class=&o&&=&/span& &span class=&nx&&stageHeight&/span&&span class=&p&&;&/span&
&span class=&c1&&// 获取滑动后的新位置,transY是滑动偏移量&/span&
&span class=&nx&&lastPosY1&/span& &span class=&o&&=&/span& &span class=&nx&&leafCon1&/span&&span class=&p&&.&/span&&span class=&nx&&y&/span& &span class=&o&&+&/span& &span class=&nx&&transY&/span&&span class=&p&&;&/span&
&span class=&nx&&lastPosY2&/span& &span class=&o&&=&/span& &span class=&nx&&leafCon2&/span&&span class=&p&&.&/span&&span class=&nx&&y&/span& &span class=&o&&+&/span& &span class=&nx&&transY&/span&&span class=&p&&;&/span&
&span class=&c1&&// 分别进行滑动&/span&
&span class=&k&&if&/span& &span class=&nx&&leafCon1&/span&&span class=&p&&.&/span&&span class=&nx&&y&/span& &span class=&o&&&=&/span& &span class=&nx&&transThreshold&/span& &span class=&c1&&// 若遇到其循环节点,leafCon1重置位置&/span&
&span class=&nx&&then&/span& &span class=&nx&&leafCon1&/span&&span class=&p&&.&/span&&span class=&nx&&y&/span& &span class=&o&&=&/span& &span class=&nx&&lastPosY2&/span& &span class=&o&&-&/span& &span class=&nx&&leafHeight&/span&&span class=&p&&;&/span&
&span class=&k&&else&/span& &span class=&nx&&leafCon1&/span&&span class=&p&&.&/span&&span class=&nx&&y&/span& &span class=&o&&=&/span& &span class=&nx&&lastPosY1&/span&&span class=&p&&;&/span&
&span class=&k&&if&/span& &span class=&nx&&leafCon2&/span&&span class=&p&&.&/span&&span class=&nx&&y&/span& &span class=&o&&&=&/span& &span class=&nx&&transThreshold&/span& &span class=&c1&&// 若遇到其循环节点,leafCon2重置位置&/span&
&span class=&nx&&then&/span& &span class=&nx&&leafCon2&/span&&span class=&p&&.&/span&&span class=&nx&&y&/span& &span class=&o&&=&/span& &span class=&nx&&lastPosY1&/span& &span class=&o&&-&/span& &span class=&nx&&leafHeight&/span&&span class=&p&&;&/span&
&span class=&k&&else&/span& &span class=&nx&&leafCon2&/span&&span class=&p&&.&/span&&span class=&nx&&y&/span& &span class=&o&&=&/span& &span class=&nx&&lastPosY2&/span&&span class=&p&&;&/span&
&/code&&/pre&&/div&&p&在实际实现的过程中,再对位置变化过程加入动画进行润色,无限循环滑动的动画效果就出来了。&/p&&h2&二、随机生成阶梯的实现&/h2&&p&随机生成阶梯是游戏的最核心部分。根据游戏的需求,阶梯由「无障碍物的阶砖」和「有障碍物的阶砖」的组成,并且阶梯的生成是随机性。&/p&&h2&无障碍阶砖的规律&/h2&&p&其中,无障碍阶砖组成一条畅通无阻的路径,虽然整个路径的走向是随机性的,但是每个阶砖之间是相对规律的。&/p&&p&因为,在游戏设定里,用户只能通过点击屏幕的左侧或者右侧区域来操控机器人的走向,那么下一个无障碍阶砖必然在当前阶砖的左上方或者右上方。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-8d83ce35abbc9fa84d007_b.jpg& data-size=&normal& data-rawwidth=&879& data-rawheight=&514& class=&origin_image zh-lightbox-thumb& width=&879& data-original=&https://pic3.zhimg.com/v2-8d83ce35abbc9fa84d007_r.jpg&&&figcaption&无障碍路径的生成规律&/figcaption&&/figure&&p&用 0、1 分别代表左上方和右上方,那么我们就可以建立一个无障碍阶砖集合对应的数组(下面简称无障碍数组),用于记录无障碍阶砖的方向。&/p&&p&而这个数组就是包含 0、1 的随机数数组。例如,如果生成如下阶梯中的无障碍路径,那么对应的随机数数组为 [0, 0, 1, 1, 0, 0, 0, 1, 1, 1]。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-77a8842ffbae_b.jpg& data-size=&normal& data-rawwidth=&354& data-rawheight=&560& class=&content_image& width=&354&&&figcaption&无障碍路径对应的 0、1 随机数&/figcaption&&/figure&&h2&障碍阶砖的规律&/h2&&p&障碍物阶砖也是有规律而言的,如果存在障碍物阶砖,那么它只能出现在当前阶砖的下一个无障碍阶砖的反方向上。&/p&&p&根据游戏需求,障碍物阶砖不一定在邻近的位置上,其相对当前阶砖的距离是一个阶砖的随机倍数,距离范围为 1~3。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-f130f919bc721c9626efbe84ce5cd38c_b.jpg& data-size=&normal& data-rawwidth=&1454& data-rawheight=&528& class=&origin_image zh-lightbox-thumb& width=&1454& data-original=&https://pic4.zhimg.com/v2-f130f919bc721c9626efbe84ce5cd38c_r.jpg&&&figcaption&障碍阶砖的生成规律&/figcaption&&/figure&&p&同样地,我们可以用 0、1、2、3 代表其相对距离倍数,0 代表不存在障碍物阶砖,1 代表相对一个阶砖的距离,以此类推。&/p&&p&因此,障碍阶砖集合对应的数组就是包含 0、1、2、3 的随机数数组(下面简称障碍数组)。例如,如果生成如下图中的障碍阶砖,那么对应的随机数数组为 [0, 1, 1, 2, 0, 1, 3, 1, 0, 1]。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-86baf650fe4af46b7b2def778da916af_b.jpg& data-size=&normal& data-rawwidth=&462& data-rawheight=&471& class=&origin_image zh-lightbox-thumb& width=&462& data-original=&https://pic3.zhimg.com/v2-86baf650fe4af46b7b2def778da916af_r.jpg&&&figcaption&障碍阶砖对应的 0、1、2、3 随机数&/figcaption&&/figure&&p&除此之外,根据游戏需求,障碍物阶砖出现的概率是不均等的,不存在的概率为 50% ,其相对距离越远概率越小,分别为 20%、20%、10%。&/p&&h2&利用随机算法生成随机数组&/h2&&p&根据阶梯的生成规律,我们需要建立两个数组。&/p&&p&对于无障碍数组来说,随机数 0、1 的出现概率是均等的,那么我们只需要利用 &code&Math.random()&/code&来实现映射,用伪代码表示如下:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// 生成随机数i,min &= i & max&/span&
&span class=&kd&&function&/span& &span class=&nx&&getRandomInt&/span&&span class=&p&&(&/span&&span class=&nx&&min&/span&&span class=&p&&,&/span& &span class=&nx&&max&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&k&&return&/span& &span class=&nb&&Math&/span&&span class=&p&&.&/span&&span class=&nx&&floor&/span&&span class=&p&&(&/span&&span class=&nb&&Math&/span&&span class=&p&&.&/span&&span class=&nx&&random&/span&&span class=&p&&()&/span& &span class=&o&&*&/span& &span class=&p&&(&/span&&span class=&nx&&max&/span& &span class=&o&&-&/span& &span class=&nx&&min&/span&&span class=&p&&)&/span& &span class=&o&&+&/span& &span class=&nx&&min&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// 生成指定长度的0、1随机数数组&/span&
&span class=&nx&&arr&/span& &span class=&o&&=&/span& &span class=&p&&[];&/span&
&span class=&k&&for&/span& &span class=&nx&&i&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span& &span class=&nx&&to&/span& &span class=&nx&&len&/span&
&span class=&nx&&arr&/span&&span class=&p&&.&/span&&span class=&nx&&push&/span&&span class=&p&&(&/span&&span class=&nx&&getRandomInt&/span&&span class=&p&&(&/span&&span class=&mi&&0&/span&&span class=&p&&,&/span&&span class=&mi&&2&/span&&span class=&p&&));&/span&
&span class=&k&&return&/span& &span class=&nx&&arr&/span&&span class=&p&&;&/span&
&/code&&/pre&&/div&&p&而对于障碍数组来说,随机数 0、1、2、3 的出现概率分别为:P(0)=50%、P(1)=20%、P(2)=20%、P(3)=10%,是不均等概率的,那么生成无障碍数组的办法便是不适用的。&/p&&p&那如何实现生成这种满足指定非均等概率分布的随机数数组呢?&/p&&p&我们可以利用概率分布转化的理念,将非均等概率分布转化为均等概率分布来进行处理,做法如下:&/p&&ol&&li&建立一个长度为 L 的数组 A ,L 的大小从计算非均等概率的分母的最小公倍数得来。&/li&&li&根据非均等概率分布 P 的情况,对数组空间分配,分配空间长度为 L * Pi ,用来存储记号值 i 。&/li&&li&利用满足均等概率分布的随机办法随机生成随机数 s。&/li&&li&以随机数 s 作为数组 A 下标,可得到满足非均等概率分布 P 的随机数 A[s] ——记号值 i。&/li&&/ol&&p&我们只要反复执行步骤 4 ,就可得到满足上述非均等概率分布情况的随机数数组——障碍数组。&/p&&p&结合障碍数组生成的需求,其实现步骤如下图所示。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-7c9f016eaec663b97a6c97b0ca8db44c_b.jpg& data-size=&normal& data-rawwidth=&378& data-rawheight=&400& class=&content_image& width=&378&&&figcaption&障碍数组值随机生成过程&/figcaption&&/figure&&p&用伪代码表示如下:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// 非均等概率分布Pi&/span&
&span class=&nx&&P&/span& &span class=&o&&=&/span& &span class=&p&&[&/span&&span class=&mf&&0.5&/span&&span class=&p&&,&/span& &span class=&mf&&0.2&/span&&span class=&p&&,&/span& &span class=&mf&&0.2&/span&&span class=&p&&,&/span& &span class=&mf&&0.1&/span&&span class=&p&&];&/span&
&span class=&c1&&// 获取最小公倍数&/span&
&span class=&nx&&L&/span& &span class=&o&&=&/span& &span class=&nx&&getLCM&/span&&span class=&p&&(&/span&&span class=&nx&&P&/span&&span class=&p&&);&/span&
&span class=&c1&&// 建立概率转化数组&/span&
&span class=&nx&&A&/span& &span class=&o&&=&/span& &span class=&p&&[];&/span&
&span class=&nx&&l&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&k&&for&/span& &span class=&nx&&i&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span& &span class=&nx&&to&/span& &span class=&nx&&P&/span&&span class=&p&&.&/span&&span class=&nx&&length&/span&
&span class=&nx&&k&/span& &span class=&o&&=&/span& &span class=&nx&&L&/span& &span class=&o&&*&/span& &span class=&nx&&P&/span&&span class=&p&&[&/span&&span class=&nx&&i&/span&&span class=&p&&]&/span& &span class=&o&&+&/span& &span class=&nx&&l&/span&
&span class=&k&&while&/span& &span class=&nx&&l&/span& &span class=&o&&&&/span& &span class=&nx&&k&/span&
&span class=&nx&&A&/span&&span class=&p&&[&/span&&span class=&nx&&l&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&nx&&i&/span&&span class=&p&&;&/span&
&span class=&nx&&l&/span&&span class=&o&&++&/span&&span class=&p&&;&/span&
&span class=&c1&&// 获取均等概率分布的随机数&/span&
&span class=&nx&&s&/span& &span class=&o&&=&/span& &span class=&nb&&Math&/span&&span class=&p&&.&/span&&span class=&nx&&floor&/span&&span class=&p&&(&/span&&span class=&nb&&Math&/span&&span class=&p&&.&/span&&span class=&nx&&random&/span&&span class=&p&&()&/span& &span class=&o&&*&/span& &span class=&nx&&L&/span&&span class=&p&&);&/span&
&span class=&c1&&// 返回满足非均等概率分布的随机数&/span&
&span class=&k&&return&/span& &span class=&nx&&A&/span&&span class=&p&&[&/span&&span class=&nx&&s&/span&&span class=&p&&];&/span&
&/code&&/pre&&/div&&p&对这种做法进行性能分析,其生成随机数的时间复杂度为 O(1) ,但是在初始化数组 A 时可能会出现极端情况,因为其最小公倍数有可能为 100、1000 甚至是达到亿数量级,导致无论是时间上还是空间上占用都极大。&/p&&p&有没有办法可以进行优化这种极端的情况呢?&br&经过研究,笔者了解到 &a href=&https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Alias_method& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Alias Method&/a& 算法可以解决这种情况。&/p&&p&Alias Method 算法有一种最优的实现方式,称为 Vose’s Alias Method ,其做法简化描述如下:&/p&&ol&&li&根据概率分布,以概率作为高度构造出一个高度为 1(概率为1)的矩形。&/li&&li&根据构造结果,推导出两个数组 Prob 数组和 Alias 数组。&/li&&li&在 Prob 数组中随机取其中一值 Prob[i] ,与随机生成的随机小数 k,进行比较大小。&/li&&li&若 k &= Prob[i] ,那么输出符合期望概率分布的随机数为 i,否则输出的值是 Alias[i] 。&/li&&/ol&&figure&&img src=&https://pic2.zhimg.com/v2-eedd10552d6bca2ceaf0_b.jpg& data-size=&normal& data-rawwidth=&1866& data-rawheight=&608& class=&origin_image zh-lightbox-thumb& width=&1866& data-original=&https://pic2.zhimg.com/v2-eedd10552d6bca2ceaf0_r.jpg&&&figcaption&对障碍阶砖分布概率应用 Vose’s Alias Method 算法的数组推导过程&/figcaption&&/figure&&blockquote&如果有兴趣了解具体详细的算法过程与实现原理,可以阅读 Keith Schwarz 的文章&a href=&https://link.zhihu.com/?target=http%3A//www.keithschwarz.com/darts-dice-coins/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《Darts, Dice, and Coins》&/a&。&/blockquote&&p&根据 Keith Schwarz 对 Vose’s Alias Method 算法的性能分析,该算法在初始化数组时的时间复杂度始终是 O(n) ,而且随机生成的时间复杂度在 O(1) ,空间复杂度也始终是 O(n) 。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-3c95bf7ccc586d9290c9f_b.jpg& data-size=&normal& data-rawwidth=&783& data-rawheight=&205& class=&origin_image zh-lightbox-thumb& width=&783& data-original=&https://pic1.zhimg.com/v2-3c95bf7ccc586d9290c9f_r.jpg&&&figcaption&两种做法的性能比较(引用 Keith Schwarz 的分析结果)&/figcaption&&/figure&&p&两种做法对比,明显 Vose’s Alias Method 算法性能更加稳定,更适合非均等概率分布情况复杂,游戏性能要求高的场景。&/p&&blockquote&在 Github 上,@jdiscar 已经对 Vose’s Alias Method 算法进行了很好的实现,你可以到&a href=&https://link.zhihu.com/?target=https%3A//github.com/jdiscar/vose-alias-method.js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&这里&/a&学习。&/blockquote&&p&最后,笔者仍选择一开始的做法,而不是 Vose’s Alias Method 算法。因为考虑到在生成障碍数组的游戏需求场景下,其概率是可控的,它并不需要特别考虑概率分布极端的可能性,并且其代码实现难度低、代码量更少。&/p&&h2&根据相对定位确定阶砖位置&/h2&&p&利用随机算法生成无障碍数组和障碍数组后,我们需要在游戏容器上进行绘制阶梯,因此我们需要确定每一块阶砖的位置。&/p&&p&我们知道,每一块无障碍阶砖必然在上一块阶砖的左上方或者右上方,所以,我们对无障碍阶砖的位置计算时可以依据上一块阶砖的位置进行确定。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-a4f0fb4a2eaf48c106eb0be5f955b29e_b.jpg& data-size=&normal& data-rawwidth=&800& data-rawheight=&434& data-thumbnail=&https://pic2.zhimg.com/v2-a4f0fb4a2eaf48c106eb0be5f955b29e_b.jpg& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&https://pic2.zhimg.com/v2-a4f0fb4a2eaf48c106eb0be5f955b29e_r.jpg&&&figcaption&无障碍阶砖的位置计算推导&/figcaption&&/figure&&p&如上图推算,除去根据设计稿测量确定第一块阶砖的位置,第n块的无障碍阶砖的位置实际上只需要两个步骤确定:&/p&&ol&&li&第 n 块无障碍阶砖的 x 轴位置为上一块阶砖的 x 轴位置偏移半个阶砖的宽度,若是在左上方则向左偏移,反之向右偏移。&/li&&li&而其 y 位置则是上一块阶砖的 y 轴位置向上偏移一个阶砖高度减去 26 像素的高度。&/li&&/ol&&p&其用伪代码表示如下:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// stairSerialNum代表的是在无障碍数组存储的随机方向值&/span&
&span class=&nx&&direction&/span& &span class=&o&&=&/span& &span class=&nx&&stairSerialNum&/span& &span class=&o&&?&/span& &span class=&mi&&1&/span& &span class=&o&&:&/span& &span class=&o&&-&/span&&span class=&mi&&1&/span&&span class=&p&&;&/span&
&span class=&c1&&// lastPosX、lastPosY代表上一个无障碍阶砖的x、y轴位置&/span&
&span class=&nx&&tmpStair&/span&&span class=&p&&.&/span&&span class=&nx&&x&/span& &span class=&o&&=&/span& &span class=&nx&&lastPosX&/span& &span class=&o&&+&/span& &span class=&nx&&direction&/span& &span class=&o&&*&/span& &span class=&p&&(&/span&&span class=&nx&&stair&/span&&span class=&p&&.&/span&&span class=&nx&&width&/span& &span class=&o&&/&/span& &span class=&mi&&2&/span&&span class=&p&&);&/span&
&span class=&nx&&tmpStair&/span&&span class=&p&&.&/span&&span class=&nx&&y&/span& &span class=&o&&=&/span& &span class=&nx&&lastPosY&/span& &span class=&o&&-&/span& &span class=&p&&(&/span&&span class=&nx&&stair&/span&&span class=&p&&.&/span&&span class=&nx&&height&/span& &span class=&o&&-&/span& &span class=&mi&&26&/span&&span class=&p&&);&/span&
&/code&&/pre&&/div&&p&接着,我们继续根据障碍阶砖的生成规律,进行如下图所示推算。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-e568d3f939b109f34b4d14ac_b.jpg& data-size=&normal& data-rawwidth=&800& data-rawheight=&433& data-thumbnail=&https://pic4.zhimg.com/v2-e568d3f939b109f34b4d14ac_b.jpg& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&https://pic4.zhimg.com/v2-e568d3f939b109f34b4d14ac_r.jpg&&&figcaption&障碍阶砖的位置计算推导&/figcaption&&/figure&&p&可以知道,障碍阶砖必然在无障碍阶砖的反方向上,需要进行反方向偏移。同时,若障碍阶砖的位置相距当前阶砖为 n 个阶砖位置,那么 x 轴方向上和 y 轴方向上的偏移量也相应乘以 n 倍。&/p&&p&其用伪代码表示如下:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// 在无障碍阶砖的反方向&/span&
&span class=&nx&&oppoDirection&/span& &span class=&o&&=&/span& &span class=&nx&&stairSerialNum&/span& &span class=&o&&?&/span& &span class=&o&&-&/span&&span class=&mi&&1&/span& &span class=&o&&:&/span& &span class=&mi&&1&/span&&span class=&p&&;&/span&
&span class=&c1&&// barrSerialNum代表的是在障碍数组存储的随机相对距离&/span&
&span class=&nx&&n&/span& &span class=&o&&=&/span& &span class=&nx&&barrSerialNum&/span&&span class=&p&&;&/span&
&span class=&c1&&// x轴方向上和y轴方向上的偏移量相应为n倍&/span&
&span class=&k&&if&/span& &span class=&nx&&barrSerialNum&/span& &span class=&o&&!==&/span& &span class=&mi&&0&/span&
&span class=&c1&&// 0 代表没有&/span&
&span class=&nx&&tmpBarr&/span&&span class=&p&&.&/span&&span class=&nx&&x&/span& &span class=&o&&=&/span& &span class=&nx&&firstPosX&/span& &span class=&o&&+&/span& &span class=&nx&&oppoDirection&/span& &span class=&o&&*&/span& &span class=&p&&(&/span&&span class=&nx&&stair&/span&&span class=&p&&.&/span&&span class=&nx&&width&/span& &span class=&o&&/&/span& &span class=&mi&&2&/span&&span class=&p&&)&/span& &span class=&o&&*&/span& &span class=&nx&&n&/span&&span class=&p&&,&/span&
&span class=&nx&&tmpBarr&/span&&span class=&p&&.&/span&&span class=&nx&&y&/span& &span class=&o&&=&/span& &span class=&nx&&firstPosY&/span& &span class=&o&&-&/span& &span class=&p&&(&/span&&span class=&nx&&stair&/span&&span class=&p&&.&/span&&span class=&nx&&height&/span& &span class=&o&&-&/span& &span class=&mi&&26&/span&&span class=&p&&)&/span& &span class=&o&&*&/span& &span class=&nx&&n&/span&&span class=&p&&;&/span&
&/code&&/pre&&/div&&p&至此,阶梯层完成实现随机生成阶梯。&/p&&p&&br&&/p&&h2&三、自动掉落阶砖的实现&/h2&&p&当游戏开始时,需要启动一个自动掉落阶砖的定时器,定时执行掉落末端阶砖的处理,同时在任务中检查是否有存在屏幕以外的处理,若有则掉落这些阶砖。&/p&&p&所以,除了机器人碰障碍物、走错方向踩空导致游戏失败外,若机器人脚下的阶砖陨落也将导致游戏失败。&/p&&p&而其处理的难点在于:&/p&&ol&&li&如何判断障碍阶砖是相邻的或者是在同一 y 轴方向上呢?&/li&&li&如何判断阶砖在屏幕以外呢?&/li&&/ol&&h2&掉落相邻及同一y轴方向上的障碍阶砖&/h2&&p&对于第一个问题,我们理所当然地想到从底层逻辑上的无障碍数组和障碍数组入手:判断障碍阶砖是否相邻,可以通过同一个下标位置上的障碍数组值是否为1,若为1那么该障碍阶砖与当前末端路径的阶砖相邻。&/p&&p&但是,以此来判断远处的障碍阶砖是否是在同一 y 轴方向上则变得很麻烦,需要对数组进行多次遍历迭代来推算。&/p&&p&而经过对渲染后的阶梯层观察,我们可以直接通过 y 轴位置是否相等来解决,如下图所示。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-adee2dc6dc34ad1a07f76_b.jpg& data-size=&normal& data-rawwidth=&514& data-rawheight=&402& class=&origin_image zh-lightbox-thumb& width=&514& data-original=&https://pic1.zhimg.com/v2-adee2dc6dc34ad1a07f76_r.jpg&&&figcaption&掉落相邻及同一 y 轴方向上的障碍阶砖&/figcaption&&/figure&&p&因为不管是来自相邻的,还是同一 y 轴方向上的无障碍阶砖,它们的 y 轴位置值与末端的阶砖是必然相等的,因为在生成的时候使用的是同一个计算公式。&/p&&p&处理的实现用伪代码表示如下:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// 记录被掉落阶砖的y轴位置值&/span&
&span class=&nx&&thisStairY&/span& &span class=&o&&=&/span& &span class=&nx&&stair&/span&&span class=&p&&.&/span&&span class=&nx&&y&/span&&span class=&p&&;&/span&
&span class=&c1&&// 掉落该无障碍阶砖&/span&
&span class=&nx&&stairCon&/span&&span class=&p&&.&/span&&span class=&nx&&removeChild&/span&&span class=&p&&(&/span&&span class=&nx&&stair&/span&&span class=&p&&);&/span&
&span class=&c1&&// 掉落同一个y轴位置的障碍阶砖&/span&
&span class=&nx&&barrArr&/span& &span class=&o&&=&/span& &span class=&nx&&barrCon&/span&&span class=&p&&.&/span&&span class=&nx&&children&/span&&span class=&p&&;&/span&
&span class=&k&&for&/span& &span class=&nx&&i&/span& &span class=&k&&in&/span& &span class=&nx&&barrArr&/span&
&span class=&nx&&barr&/span& &span class=&o&&=&/span& &span class=&nx&&barrArr&/span&&span class=&p&&[&/span&&span class=&nx&&i&/span&&span class=&p&&],&/span&
&span class=&nx&&thisBarrY&/span& &span class=&o&&=&/span& &span class=&nx&&barr&/span&&span class=&p&&.&/span&&span class=&nx&&y&/span&&span class=&p&&;&/span&
&span class=&k&&if&/span& &span class=&nx&&barr&/span&&span class=&p&&.&/span&&span class=&nx&&y&/span& &span class=&o&&&=&/span& &span class=&nx&&thisStairY&/span& &span class=&c1&&// 在同一个y轴位置或者低于&/span&
&span class=&nx&&barrCon&/span&&span class=&p&&.&/span&&span class=&nx&&removeChild&/span&&span class=&p&&(&/span&&span class=&nx&&barr&/span&&span class=&p&&);&/span&
&/code&&/pre&&/div&&h2&掉落屏幕以外的阶砖&/h2&&p&那对于第二个问题——判断阶砖是否在屏幕以外,是不是也可以通过比较阶砖的 y 轴位置值与屏幕底部y轴位置值的大小来解决呢?&/p&&p&不是的,通过 y 轴位置来判断反而变得更加复杂。&/p&&p&因为在游戏中,阶梯会在机器人前进完成后会有回移的处理,以保证阶梯始终在屏幕中心呈现给用户。这会导致阶砖的 y 轴位置会发生动态变化,对判断造成影响。&/p&&p&但是我们根据设计稿得出,一屏幕内最多能容纳的无障碍阶砖是 9 个,那么只要把第 10 个以外的无障碍阶砖及其相邻的、同一 y 轴方向上的障碍阶砖一并移除就可以了&/p&&figure&&img src=&https://pic4.zhimg.com/v2-216a81ee4f4d3f95cd3f_b.jpg& data-size=&normal& data-rawwidth=&584& data-rawheight=&407& class=&origin_image zh-lightbox-thumb& width=&584& data-original=&https://pic4.zhimg.com/v2-216a81ee4f4d3f95cd3f_r.jpg&&&figcaption&掉落屏幕以外的阶砖&/figcaption&&/figure&&p&所以,我们把思路从视觉渲染层面再转回底层逻辑层面,通过检测无障碍数组的长度是否大于 9 进行处理即可,用伪代码表示如下:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// 掉落无障碍阶砖&/span&
&span class=&nx&&stair&/span& &span class=&o&&=&/span& &span class=&nx&&stairArr&/span&&span class=&p&&.&/span&&span class=&nx&&shift&/span&&span class=&p&&();&/span&
&span class=&nx&&stair&/span& &span class=&o&&&&&/span& &span class=&nx&&_dropStair&/span&&span class=&p&&(&/span&&span class=&nx&&stair&/span&&span class=&p&&);&/span&
&span class=&c1&&// 阶梯存在数量超过9个以上的部分进行批量掉落&/span&
&span class=&k&&if&/span& &span class=&nx&&stairArr&/span&&span class=&p&&.&/span&&span class=&nx&&length&/span& &span class=&o&&&=&/span& &span class=&mi&&9&/span&
&span class=&nx&&num&/span& &span class=&o&&=&/span& &span class=&nx&&stairArr&/span&&span class=&p&&.&/span&&span class=&nx&&length&/span& &span class=&o&&-&/span& &span class=&mi&&9&/span&&span class=&p&&,&/span&
&span class=&nx&&arr&/span& &span class=&o&&=&/span& &span class=&nx&&stairArr&/span&&span class=&p&&.&/span&&span class=&nx&&splice&/span&&span class=&p&&(&/span&&span class=&mi&&0&/span&&span class=&p&&,&/span& &span class=&nx&&num&/span&&span class=&p&&);&/span&
&span class=&k&&for&/span& &span class=&nx&&i&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span& &span class=&nx&&to&/span& &span class=&nx&&arr&/span&&span class=&p&&.&/span&&span class=&nx&&length&/span&
&span class=&nx&&_dropStair&/span&&span class=&p&&(&/span&&span class=&nx&&arr&/span&&span class=&p&&[&/span&&span class=&nx&&i&/span&&span class=&p&&]);&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&至此,两个难点都得以解决。&/p&&h2&后言&/h2&&p&为什么笔者要选择这几点核心内容来剖析呢?&br&因为这是我们经常在游戏开发中经常会遇到的问题:&/p&&ul&&li&怎样处理游戏背景循环?&/li&&li&有 N 类物件,设第 i 类物件的出现概率为 P(X=i) ,如何实现产生满足这样概率分布的随机变量 X ?&/li&&/ul&&p&而且,对于阶梯自动掉落的技术点开发解决,也能够让我们认识到,游戏开发问题的解决可以从视觉层面以及逻辑底层两方面考虑,学会转一个角度思考,从而将问题解决简单化。&/p&&p&这是本文希望能够给大家在游戏开发方面带来一些启发与思考的所在。最后,还是老话,行文仓促,若错漏之处还望指正,若有更好的想法,欢迎留言交流讨论&/p&&h2&参考资料&/h2&&ul&&li&&a href=&https://link.zhihu.com/?target=http%3A//www.keithschwarz.com/darts-dice-coins/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《Darts, Dice, and Coins&/a&》&/li&&/ul&
在今年八月中旬,《指尖大冒险》SNS 游戏诞生,其具体的玩法是通过点击屏幕左右区域来控制机器人的前进方向进行跳跃,而阶梯是无穷尽的,若遇到障碍物或者是踩空、或者机器人脚下的阶砖陨落,那么游戏失败。笔者对游戏进行了简化改造,点击进行体验。该…
&p&谢学弟邀:) &b&既然已经身在工业界,那么就来谈谈工业界未来需要什么样的机器学习人才。&/b&&/p&&p&&b&撇开学术界需求因为大部分人最终不会从事算法研究,而会奋斗在一线应用领域&/b&。相较而言,工业界对人才的需求更加保守。这受限于很多客观因素,如硬件运算能力、数据安全、算法稳定性、人力成本开支等。&/p&&p&&b&这个答案可能更适合两类人: 1. 在读学生 2. 工作不久想要转行机器学习的朋友&/b&。特别厉害的技术大牛建议探索适合自己的路线,而我只能泛泛谈谈适合大部分人的路线。但在回答前,我还是忍不住吐槽一下那种简单回答“深度学习”,“大数据”,“NLP”,“机器视觉”的人。这每一个领域的小方向都多如牛毛,以自然语言处理(NLP)为例,细分有自然语言生成、自然语言理解,还有不同语言的语言模型。任何一个方向花几十年研究也不为过,只给出几个字的答案和买彩票有什么区别...&b&因此大部分机器学习实践者还是该脚踏实地。盲目追逐热点很容易跌进陷阱,而巩固基础、寻找自己擅长的领域和机器学习交叉点可以帮助你在未来的就业市场变得炙手可热,成为工业界最紧缺的人才。&/b&&/p&&h2&&b&0. 背景&/b&&/h2&&p&&b&工业界未来需要什么样的机器学习人才?老生常谈,能将模型应用于专业领域的人,也就是跨领域让机器学习落地的人&/b&。有人会问现在我们不就需要这样的人吗?答案是肯定的,我们需要并将长期需要这样的人才,现阶段的机器学习落地还存在各种各样的困难。&b&这样的需求不会是昙花一现,这就跟web开发是一个道理,从火热到降温也经过了十年的周期。一个领域的发展有特定的周期,机器学习的门槛比web开发高而且正属于朝阳期,所以大家致力于成为“专精特定领域”的机器学习专家并不过时。&/b&&/p&&p&什么是特定领域的机器学习专家?举个例子,我以前曾回答“人工智能是否会替代财务工作者”时提到我曾在某个公司研究如何用机器学习自动化一部分审计工作,但遇到的最大困难是我自己对审计的了解有限,而其他审计师对我的工作不是非常支持导致进展缓慢。&b&所以如果你有足够的机器学习知识,并对特定领域有良好的理解,在职场供求中你肯定可以站在优势的那一边&/b&。以我的另一个回答为例「&a href=&https://www.zhihu.com/question//answer/& class=&internal&&反欺诈(Fraud Detection)中所用到的机器学习模型有哪些?」&/a&,特定领域的知识帮助我们更好的解释机器学习模型的结果,得到老板和客户的认可,这才是算法落了地。&b&能写代码、构建模型的人千千万,但理解自己在做什么,并从中结合自己的领域知识提供商业价值的人少之又少。&/b&所以调侃一句,哪个方向的机器学习人才最紧缺?答:每个领域都需要专精的机器学习人才,你对特定领域的理解就是你的武器。&/p&&p&当然,给喂鸡汤不给勺很不厚道,所以我也会给出一些具体建议。&b&再次申明,我的建议仅给以就业为目的的朋友,走研究路线我有不同的建议,本文不再赘述。&/b&&/p&&h2&&b&1. 基本功&/b&&/h2&&p&说到底机器学习还是需要一定的专业知识,这可以通过学校学习或者自学完成。&b&但有没有必要通晓数学,擅长优化呢?我的看法是不需要的,大前提是需要了解基本的数学统计知识即可&/b&,更多的讨论可以看我这个答案「&a href=&https://www.zhihu.com/question//answer/& class=&internal&&阿萨姆:如何看待「机器学习不需要数学,很多算法封装好了,调个包就行」这种说法?」&/a&。最低程度下我建议掌握五个小方向,对于现在和未来几年内的工业界够用了。&b&再一次重申,我对于算法的看法是大部分人不要造轮子,不要造轮子,不要造轮子!只要理解自己在做什么,知道选择什么模型,直接调用API和现成的工具包就好了。&/b&&/p&&ul&&li&&b&回归模型(Regression)&/b&。学校的课程中其实讲得更多的都是分类,但事实上回归才是工业届最常见的模型。比如产品定价或者预测产品的销量都需要回归模型。现阶段比较流行的回归方法是以数为模型的xgboost,预测效果很好还可以对变量重要性进行自动排序。而传统的线性回归(一元和多元)也还会继续流行下去,因为其良好的可解释性和低运算成本。如何掌握回归模型?建议阅读Introduction to Statistical Learning的2-7章,并看一下R里面的xgboost的package介绍。&/li&&li&&b&分类模型(Classification)&/b&。这个属于老生常谈了,但应该对现在流行并将继续流行下去的模型有深刻的了解。举例,随机森林(Random Forests)和支持向量机(SVM)都还属于现在常用于工业界的算法。可能很多人想不到的是,逻辑回归(Logistic Regression)这个常见于大街小巷每一本教科书的经典老算法依然占据了工业界大半壁江山。这个部分推荐看李航《统计学习方法》,挑着看相对应的那几章即可。&/li&&li&&b&神经网络(Neural Networks)&/b&。我没有把神经网络归结到分类算法还是因为现在太火了,有必要学习了解一下。随着硬件能力的持续增长和数据集愈发丰富,神经网络的在中小企业的发挥之处肯定会有。三五年内,这个可能会发生。但有人会问了,神经网络包含内容那么丰富,比如结构,比如正则化,比如权重初始化技巧和激活函数选择,我们该学到什么程度呢?我的建议还是抓住经典,掌握基本的三套网络: a. 普通的ANN b. 处理图像的CNN c. 处理文字和语音的RNN(LSTM)。对于每个基本的网络只要了解经典的处理方式即可,具体可以参考《深度学习》的6-10章和吴恩达的Deep Learning网课(已经在网易云课堂上线)。&/li&&li&&b&数据压缩/可视化(Data Compression & Visualization)&/b&。在工业界常见的就是先对数据进行可视化,比如这两年很火的流形学习(manifold learning)就和可视化有很大的关系。工业界认为做可视化是磨刀不误砍柴工,把高维数据压缩到2维或者3维可以很快看到一些有意思的事情,可能能节省大量的时间。学习可视化可以使用现成的工具,如Qlik Sense和Tableau,也可以使用Python的Sklearn和Matplotlib。&/li&&li&&b&无监督学习和半监督学习(Unsupervised & Semi-supervised Learning)&/b&。工业界的另一个特点就是大量的数据缺失,大部分情况都没有标签。以最常见的反诈骗为例,有标签的数据非常少。所以我们一般都需要使用大量的无监督,或者半监督学习来利用有限的标签进行学习。多说一句,强化学习在大部分企业的使用基本等于0,估计在未来的很长一阵子可能都不会有特别广泛的应用。&/li&&/ul&&p&&b&基本功的意义是当你面对具体问题的时候,你很清楚可以用什么武器来处理&/b&。而且上面介绍的很多工具都有几十年的历史,依然历久弥新。所以以3-5年的跨度来看,这些工具依然会非常有用,甚至像CNN和LSTM之类的深度学习算法还在继续发展迭代当中。无论你现在还在学校还是已经开始工作,掌握这些基本的技术都可以通过自学在几个月到一两年内完成。&/p&&h2&&b&2. 秘密武器&/b&&/h2&&p&有了基本功只能说明你可以输出了,怎么才能使得你的基本功不是屠龙之术?必须要结合领域知识,这也是为什么我一直劝很多朋友不要盲目转机器学习从零做起。&b&而学生朋友们可以更多的关注自己感兴趣的领域,思考如何可以把机器学习运用于这个领域&/b&。比如我自己对历史和哲学很感兴趣,常常在思考机器学习和其他文科领域之间的联系,也写过一些开脑洞的文章「 &a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&带你了解机器学习(一): 机器学习中的“哲学”&/a&&a href=&https://www.zhihu.com/question//answer/& class=&internal&&」&/a&。&/p&&p&&b&而已经有了工作/研究经验的朋友,要试着将自己的工作经历利用起来。举例,不要做机器学习里面最擅长投资的人,而要做金融领域中最擅长机器学习的专家,这才是你的价值主张(value proposition)。最重要的是,机器学习的基本功没有大家想的那么高不可攀,没有必要放弃自己的本专业全职转行,沉没成本太高。通过跨领域完全可以做到曲线救国,化劣势为优势,你们可能比只懂机器学习的人有更大的行业价值。&/b&&/p&&p&举几个我身边的例子,我的一个朋友是做传统软件工程研究的,前年他和我商量如何使用机器学习以GitHub上的commit历史来识别bug,这就是一个很好的结合领域的知识。如果你本身是做金融出身,在你补足上面基本功的同时,就可以把机器学习交叉运用于你自己擅长的领域,做策略研究,我已经听说了无数个“宣称”使用机器学习实现了交易策略案例。虽不可尽信,但&b&对特定领域的深刻理解往往就是捅破窗户的那最后一层纸,只理解模型但不了解数据和数据背后的意义,导致很多机器学习模型只停留在好看而不实用的阶段&/b&。&/p&&p&换个角度思考,不同领域的人都有了对机器学习的理解能更好的促进这个技术落地,打破泡沫的传言。&b&而对于大家而言,不用再担心自己会失业,还能找到自己的角度在这个全民深度学习的时代找到“金饭碗”。所以我建议各行各业的从业者不必盲目的转计算机或者机器学习,而应该加深对本专业的了解并自学补充上面提到的基本功,自己成为这个领域的机器学习专家。&/b&&/p&&h2&&b&3. 弹药补给 &/b&&/h2&&p&没有什么不会改变,这个时代的科技迭代速度很快。从深度学习开始发力到现在也不过短短十年,所以没有人知道下一个会火的是什么?以深度学习为例,这两年非常火的对抗生成网络(GAN),多目标学习(multi-lable learning),迁移学习(transfer learning)都还在飞速的发展。有关于深度学习为什么有良好泛化能力的理论猜想文章在最新的NIPS听说也录了好几篇。这&b&都说明了没有什么行业可以靠吃老本一直潇洒下去,我们还需要追新的热点。&/b&但机器学习的范围和领域真的很广,上面所说的都还是有监督的深度学习,无监督的神经网络和深度强化学习也是现在火热的研究领域。&b&所以我的建议是尽量关注、学习了解已经成熟和已经有实例的新热点,不要凡热点必追。&/b&&/p&&p&&b&如果你有这些基本功和良好的领域结合能力,三年五年绝不是职业的瓶颈期,甚至十年都还太早。科技时代虽然给了我们很大的变革压力,但也带给了我们无限的可能。技术总会过时,热点总会过去,但不会过去的是我们不断追求新科技的热情和对自己的挑战。&/b&&/p&&p&欢迎来到机器学习的世界 ?o?o? &/p&
谢学弟邀:) 既然已经身在工业界,那么就来谈谈工业界未来需要什么样的机器学习人才。撇开学术界需求因为大部分人最终不会从事算法研究,而会奋斗在一线应用领域。相较而言,工业界对人才的需求更加保守。这受限于很多客观因素,如硬件运算能力、数据安全、…
&p&哇!1000赞了!给汪诘老师做个广告吧,喜马拉雅音频上的&b&汪诘&/b&老师(注意是诘问的诘),做了几个系列的节目,对量子物理感兴趣的,可以听一听,其中也有跟本期视频的相关解释。&/p&&p&下面是原答案:&/p&&p&关于量子物理的,本人绝对轻易不会把这个视频放出来(高潮部分在3分20多秒后)!&b&粗&/b&思就恐,据说好几个物理学家看完以后削发为僧出家为尼,还有几个量子物理学家看完以后生活不能自理!&/p&&a class=&video-box& href=&//link.zhihu.com/?target=https%3A//www.zhihu.com/video/412800& target=&_blank& data-video-id=&& data-video-playable=&true& data-name=&& data-poster=&https://pic1.zhimg.com/80/v2-3d96e34d9e1d9bb2bcd82f8f993bfa50_b.jpg& data-lens-id=&412800&&
&img class=&thumbnail& src=&https://pic1.zhimg.com/80/v2-3d96e34d9e1d9bb2bcd82f8f993bfa50_b.jpg&&&span class=&content&&
&span class=&title&&&span class=&z-ico-extern-gray&&&/span&&span class=&z-ico-extern-blue&&&/span&&/span&
&span class=&url&&&span class=&z-ico-video&&&/span&https://www.zhihu.com/video/412800&/span&
&/a&&p&说说我的观后感吧,第一次看这个视频,感觉这个世界是不可以理解的,后来又不少科普作家在自己的节目里解释了这个视频,观测本身《光子》影响了电子,测不准原理在作乱,费曼也对此解释过,但是我还是觉得量子物理挺不可思议的。&/p&&p&至于削发为尼、生活不能自理那些是我胡编的。&/p&&p&应很多知友的请求,我再上传一个烧脑的续集:关于“延迟实验”的视频,讲真,更吓人:&/p&&a class=&video-box& href=&//link.zhihu.com/?target=https%3A//www.zhihu.com/video/831360& target=&_blank& data-video-id=&& data-video-playable=&true& data-name=&& data-poster=&https://pic4.zhimg.com/80/v2-8d574dd52da1d8bb5f0c9afdc3f6bba3_b.jpg& data-lens-id=&831360&&
&img class=&thumbnail& src=&https://pic4.zhimg.com/80/v2-8d574dd52da1d8bb5f0c9afdc3f6bba3_b.jpg&&&span class=&content&&
&span class=&title&&&span class=&z-ico-extern-gray&&&/span&&span class=&z-ico-extern-blue&&&/span&&/span&
&span class=&url&&&span class=&z-ico-video&&&/span&https://www.zhihu.com/video/831360&/span&
&/a&&p&为了将原来16分钟的视频上传到知乎,我用录屏软件加快放并压缩至9分钟,速度有点快,画面不够清晰,想看源文件的,去网上搜索“选择延迟实验“吧,应该有很多。&/p&
哇!1000赞了!给汪诘老师做个广告吧,喜马拉雅音频上的汪诘老师(注意是诘问的诘),做了几个系列的节目,对量子物理感兴趣的,可以听一听,其中也有跟本期视频的相关解释。下面是原答案:关于量子物理的,本人绝对轻易不会把这个视频放出来(高潮部分在3…
&figure&&img src=&https://pic2.zhimg.com/v2-6c8b4efa461b01aed752a739f1086768_b.jpg& data-rawwidth=&550& data-rawheight=&386& class=&origin_image zh-lightbox-thumb& width=&550& data-original=&https://pic2.zhimg.com/v2-6c8b4efa461b01aed752a739f1086768_r.jpg&&&/figure&&p&从大一入学被调剂到计算机专业,到喜欢上这个专业,再到毕业拿到10多个offer,最终进入理想的大厂工作。回想起来这些年确确实实踩了很多坑。&b&我刚开始学习编程的时候也想一口吃成一个胖子,想速成,但是有时候却是不尽人意。&/b&&/p&&p&回忆了下这几年学习编程的过程,整理了一些我自己认为很需要注意的几个方面,分享给大家。希望能让初学编程的你,少走一些弯路,&b&可能文章比较长,但我真心希望初学编程的你能够认真看完,至少,我认为如果我刚学编程的时候看到这篇文章,对我或多或少是有一些帮助的。&/b&&/p&&p&我个人是一名计算机专业的学生,很多人可能会认为我是在课堂上学到的编程,其实不是这样。&/p&&p&我认为科班出身和非科班出身的学生最大的区别在于&b&科班出身的学生知道去学什么&/b&,知道每一门课程是干什么的;还有一些必须完成的作业、小项目,促使他们去做一些实际的编码练习,除此之外,真的全靠自学。&/p&&p&对于自学编程,我认为首先应该谈的是如何去避免一些坑,这样就可能节约大把的时间。下面我就以问题的形式来分享一些我认为重要的方面。&/p&&p&&br&&/p&&p&&b&&i&1. 我应该选择什么编程语言&/i&&/b&&/p&&p&可能困扰编程新手最多的一个问题是【我应该学什么编程语言】或者【我需要学习哪些课程才能做出一个web、一个app】,很多人一直纠结这个问题,陷入了东学一点、西看一点的死循环,到头来啥也没学好,这会很浪费时间。&/p&&p&刚上大一的时候,我也很想知道应该选择什么编程语言。我问了很多人,网上各种查资料,但所能得到的答案都很片面,多数对这个问题答非所问,总是回答说“某某编程语言难”,“某某编程语言性能好”。&b&其实作为初学者,我们对计算机体系都不了解,就不要过多地去纠结性能,或者难易等因素&/b&,原因我等下再说。&/p&&p&如果你有明确的方向,那么很好选择。&b&如果你想做算法、机器学习方向,那么python是最好的选择。如果你想做web开发,java、php等都可以。如果想做一些更底层的工作,那么就可以选c。&/b&当然这是建立在你有明确方向的基础上。可是,很多人都没怎么接触过计算机行业,特别是和我一样刚入学就被调剂到计算机专业的人。对这些同学来说,各个编程语言就只是个名字,除了叫法不一样,你根本不知道它们有什么差别。所以索性不要纠结了,我替你选一个吧。&/p&&p&&b&如果你是在校大学生,那么你有大把连续的时间,就先学习c,然后再学c++。&/b&我个人是学c入门的,也许很多人不理解我为什么推荐学c,因为c和c++都很难、很复杂,看起来并不适合入门。然而正是它们的难和复杂才能让你更好地理解计算机系统【&b&计算机系统不是指操作系统】&/b&。&b&学习编程不是学习编程语言,而是学习一个计算机生态,即一个庞大的知识体系。&/b&只会编程语言而不理解整个计算机的体系,就像只会写字而写不出好文章。了解c/c++和了解计算机系统是极为贴合的,&b&&i&向下&/i&&/b&可以帮助你更容易地理解操作系统、编译原理、计算机网络、计算机组成原理,为什么呢?因为较为底层的东西很多都是用c实现的,和系统的贴合度极高,很多教材源码甚至教程,在讲述这些知识的时候都是用c或c++作为媒介。而&b&&i&向上&/i&&/b&,c++面向对象的机制,也可以做出一些应用,譬如五子棋游戏等,也不会显得那么枯燥。花个小半年时间了解c和c++,之后你就会觉得看书、看资料可以轻松很多。&/p&&p&&b&如果你是一个上班族,&/b&但是刚刚学习编程,可能学c和c++对你来说有些复杂和困难,因为学习它们确实是很需要时间。你们不像在校生那样有大把的连续时间,而零碎的时间去学习一个比较复杂的东西效果不见得有那么好,所以可以先学一些【更容易见效】的编程语言,&b&从python入手吧&/b&,至少能快速做出一些小应用,不至于丢失了兴趣,但是真的要入门编程又还得看看与计算机系统相关的书籍,这样才能更深层次地去编程,譬如【深入理解计算机系统】这一本书可以读很多遍,这本书把整个计算机系统给串起来了。&/p&&p&&br&&/p&&p&&b&&i&2.学习编程,我需要学习哪些课程?&/i&&/b&&/p&&p&&b&我要学哪些课程?我为什么要学习如高数、离散数学、线性代数、概率论等课程?&/b& &/p&&p&这个问题也是之前困扰了我很久的问题。不过我现在想通了,对于【高数、离散、线性代数、概率论】等课程,很好解释,做算法的同学肯定知道为啥要学习这些课程。&b&机器学习&/b&中会大量用到上述提到的课程,所以会比较好理解。对在校生而言,学校开设的很多课程我们不知道为什么要学,我们很疑惑,不知道学它有什么用,这个时候我们就会很纠结,还会产生抵触情绪。这很正常,因为我们学习得不够深入,自然不能理解它们的用处。&/p&&p&在我看来,&b&大学本科课程更多的是面向“面”的教学&/b&,即什么课程都教给你一些,但是又讲得不那么深入;而&b&工作或者读研,更多的则是面向“点”的学习&/b&,用到的知识更专。本科时,学校也不知道你以后是去搞算法、还是搞架构、还是搞服务器开发,甚至去搞硬件,所以学校需要你学很多课程,至少有个了解。对学生来说,一方面可以从中选择自己感兴趣的点;一方面也可以对未来的就业方向有些启发。所以即使像数电、模电等课程,虽然之后可能用不着,但是你也要学,并且会花费大量的时间。虽然你最后不一定去搞硬件,但是这些课程也会让你更容易去理解一些知识,比如cpu中的逻辑器件。&/p&&p&如果你在大一的时候就有一个明确的定位,知道自己今后想从事哪方面的工作,课程与课程之间是可以调一下&b&优先级&/b&的。不过像大学物理,这种课程确实是对编程没有帮助,但是像我前面所说的,大学教育更注重广度,大物等课程可能就是为了给你普及生活常识吧。&/p&&p&其实,大学教育的问题是普遍存在的,我认为我们学习一项技能的时候,应该采取的是&b&项目驱动式学习&/b&,即需要用到什么东西时不会了再去学,而不是先填鸭式的都填进脑子,并且在学习的过程中我们还不知道它这是干嘛用的,等之后用到了,甚至不记得自己学过,反而查资料才会想起:哦,原来我之前学的xx科目是这个用处啊,可是我当时并没有好好学。很多时候学生时间的浪费可能还是要怪老师、怪学校,他们一开始没给我们做好充分的课程介绍。所以,在经过比较多的编程和项目实践后,我认为一个比较好的学习方式是,&b&改良版的项目驱动学习法&/b&。即:&/p&&p&&i&&b&学习一段时间,做个小项目,将做项目遇到的问题记下来,针对性地学习相关知识,然后再实践,再学一段时间理论,让知识成网状发射状地变大。当然,项目驱动式学习有一个弊端,就是每次学习的知识都是项目所需要的,很零碎、不成体系,所以需要改良,即在采取项目驱动学习法的时候每天抽一段时间去完整地读一本书,或者一个相关问题的完整介绍,这样就很容易把一些知识成体系地串起来。这样一段时间下来,慢慢的,你就知道我们为什么要学那么多科目,学这些科目能干什么。&/b&&/i&&/p&&p&为了表达地更加形象,我就举一个小例子,是我最近遇到的。我本身的工作是做Linux C++的,但不仅限于此。我个人对python、数据分析,以及机器学习等内容比较感兴趣,大家可以看到我最近也在我的专栏发布了很多文章。就从&b&数据获取&/b&开始,我讲讲我这两个月做了什么东西。&/p&&p&谈到数据获取,可能最容易想到的是&b&爬虫&/b&,爬虫是一个在知乎上被说烂了的话题,所以我不想多说它是什么。很多时候有人觉得爬虫简单,为什么呢,因为有&b&现成的框架&/b&,所以获取少量的数据就比较容易。但是当你需要爬取的数据很大的时候(比如我之前抓取了知乎500万用户的数据,在下班的时间、用自己家里普通的pc,计算机性能并不是那么好,比不上服务器,又要在不被封IP的情况下抓到这么大量的数据,然后对数据进行清洗,最后还要可视化展示),使用现成的爬虫框架就并不是那么容易实现了。况且,我需要抓很多数据源,并不是一锤子买卖。所以我选择去&b&开发一个系统&/b&,即在现有的框架下进行二次开发,搭建一个属于自己的爬虫系统,并植入一些算法。我在系统中添加了很多中间件,直到现在,它还可以在10分钟内就部署一个能抓取大量数据的爬虫应用。当然,这个过程也遇到了不少麻烦,我就简单讲讲,怎么去攻克一个个问题。&/p&&p&下面先给出一个&b&树形图&/b&,从上往下每一个圈都代表了学习过程中遇到的难点,如果你现在看不懂,没关系,我想告诉你的是一种梳理知识的方法:&/p&&figure&&img src=&https://pic2.zhimg.com/v2-becccee03724_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&891& data-rawheight=&1465& class=&origin_image zh-lightbox-thumb& width=&891& data-original=&https://pic2.zhimg.com/v2-becccee03724_r.jpg&&&/figure&&p&如上图所示,就是一个项目驱动式学习的例子,我们的目的是为了获取数据,所以选择了爬虫:&/p&&ol&&li&爬虫可以理解为一个简单的过程:发送request,获取response,然后提取数据。这个过程会涉及到网络,是发送http还是https请求;目标网站是否需要登录,是post请求还是get请求,从这条线,衍生出了一条对网络进行学习的路径。&/li&&li&获取到网页之后,如果不是结构化的数据,可能返回的是一个html源代码,那么可能就需要了解dom,或者html页面解析的知识,甚至需要了解一下前端开发。&/li&&li&在抓取的过程中,经常会遇到数据中途不能被爬取的情况,一般是IP被封禁了,那么可能又要用上代理,代理是什么呢?http,https代理能不能混用呢?如何构建一个代理池呢?这里又有很多要学习的东西。还有可能遇到的情况是,抓下来的数据是加密的,需要通过js解密,这时候就要了解一下js,如何用爬虫模拟浏览器进行抓取。除此之外,如果抓取的频率不对,很多数据源会给你假数据,这就是一些经验问题了,本文不是技术文,所以就不多讨论。&/li&&li&当解决了上述问题后,我们好像可以拿到一些数据了,但是当数据大起来,问题又复杂了,你可能需要使用分布式抓取了,这时候你可能需要了解一下redis,当request产生的速度大于其消费的速度之后,你的任务队列可能爆炸,所以这里又涉及到算法和数据结构的应用了。&/li&&li&数据量上去之后,把数据写在文件里面是不靠谱的,这时候又涉及到存储了,到底是使用关系型数据库还是非关系型数据库呢,有什么区别呢?存进去的数据怎么去重呢?为什么insert操作越来越卡了呢?电脑怎么越来越热了呢?索引是什么,什么时候该建立索引呢?这里又牵扯到数据库原理相关的知识。&/li&&li&遇到一些比较难处理的网站,比如有验证码识别该怎么办呢?其实对于很多纯数字和字母的验证码都很好解决,自己用深度学习训练即可。在TensorFlow的Demo中就要生成验证码自己训练的教程,然后制定个中间件放在爬虫系统中,这个问题就解决了。可是什么是深度学习呢?这里又引出一条对深度学习进行探索的例子,而我自己也是之前在学校的时候自学了小半年机器学习,有了一定的基础后,才能比较容易地上手TensorFlow框架。再往下就比较深了。&/li&&/ol&&p&上述六点简单讲了讲项目驱动式学习的介绍,其实,你看到的每一个小圆圈,深挖下去都大有文章。我们现在看到的只是冰山一角,任何一条学习路径学习下去都深无止境,我们不可能完全学会,可是&b&项目驱动式学习最大的好处是让你知道你应该去学习什么,而不是先学一大堆知识,再去做一个项目&/b&。严格来说,项目驱动式学习的可视化路径是一张网,而不是一棵树,这里画成树状只是为了便于大家理解。&/p&&p&除了获得数据,还有清洗数据、分析数据,甚至挖掘数据,最后可视化数据并且展示数据,这里我就不一一介绍了。可以参见下面这张图,&b&如果大家想看我做的一些成品,可以看看我的其他文章&/b&。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-4e82f497fda1c55dc7dec_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&682& data-rawheight=&938& class=&origin_image zh-lightbox-thumb& width=&682& data-original=&https://pic3.zhimg.com/v2-4e82f497fda1c55dc7dec_r.jpg&&&/figure&&p&&b&&i&3.学习编程是否需要制定计划?&/i&&/b&&/p&&p&&b&学习编程是否需要制定计划,该制定什么样的计划呢?&/b& &/p&&p&我认为不只是编程需要制定计划,其他任何的学习和工作都需要制定计划。我从13年上大学就开始定期给自己制定计划,这个习惯也一直坚持到了现在,受益匪浅。当然也不只是制定学习计划,还可以列一些自己需要做的其他的事情。我最近在整理笔记的时候也发现了一些之前记录的计划和清单,可以给大家看看。&b&比如下图就是我14年写的笔记,笔记上都留下了最后一次打开的时间&/b&。列举了一些自己需要看的文章,因为当时不太懂得规划,所以比较乱。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-4f616fcac9fdcfb0ab1551b_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1292& data-rawheight=&1028& class=&origin_image zh-lightbox-thumb& width=&1292& data-original=&https://pic2.zhimg.com/v2-4f616fcac9fdcfb0ab1551b_r.jpg&&&/figure&&p&到了16年的时候,我做计划做得更加有条理了。下图是16年10月30日的计划,那时候我已经大四了,并且已经找到了工作、签了满意的offer,并且没有什么课,按理说可以放松放松了,不过我还是制定了一些学习计划,并且选择在11月去百度实习。&b&从内容上看,主要是学习英语和计算机专业课,因为大一大二的时候我确实不明白为什么要学习专业课,到了大三下想清楚原因以后,我也就一直在重新学习,因为计算机专业课真的很重要!学好了这些课,能让你在日后的学习工作中轻松不少:&/b&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-c2db9c4345cc6caab4f96_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1706& data-rawheight=&1406& class=&origin_image zh-lightbox-thumb& width=&1706& data-original=&https://pic4.zhimg.com/v2-c2db9c4345cc6caab4f96_r.jpg&&&/figure&&p&&b&除了大四制定的计划外,大二的时候我也制定过较为详细的学习计划(如下图),把需要学习的内容进行了编号,存入表格,这样才能让你过得有条不紊。当然,很难完全按照计划去执行,不过制定相应的计划能让你清楚地知道自己应该干什么。&/b&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-1ba136d2ccd82b153fedfaa_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1672& data-rawheight=&1266& class=&origin_image zh-lightbox-thumb& width=&1672& data-original=&https://pic2.zhimg.com/v2-1ba136d2ccd82b153fedfaa_r.jpg&&&/figure&&p&所以,如果你是在校生,那么好好制定一个计划吧,因为你有大把的时间。当然,如果你已经毕业了,没关系,我现在也在上班,同样也列举了自己最近要学习的内容,如下图(2月27日更新过),包括了短期和长期需要学习的内容:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-abe41fc9daee9db3ad44_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1542& data-rawheight=&1258& class=&origin_image zh-lightbox-thumb& width=&1542& data-original=&https://pic4.zhimg.com/v2-abe41fc9daee9db3ad44_r.jpg&&&/figure&&p&&b&&i&4.编程是否需要做笔记和写博客?&/i&&/b&&/p&&p&我觉得,写不写博客无所谓,因为博客是要写出来给大家看的,可能要保证格式美观、语法也要尽量准确,最好比较有文采,我觉得太麻烦也就一直没写。&b&而笔记是必须要做的,并且记笔记是一个长期的过程。在学习的过程中,我们一直都在追求一种最高效的学习方法,比如,同一个班的同学,他用他的学习方法考上了清华,而你用同样的方法就不行,为什么?因为他的方法对他自己而言是定制化的,可能且大概率不适合你,比如他的笔记你不一定能看懂,因为他可能设计了一套属于自己的符号。而就编程而言,很多同学说善用搜索引擎,是对的,可是搜索引擎搜出来的是别人的答案。你照搬过来,也许可以用,但是你没有记住,这些知识并不属于你,之后你可能还会遇到同样的问题,又要再搜索一遍,可能很难找到之前的那个答案了。但是记笔记就不一样,记笔记是定制化的,对你自己定制,你可以用自己最爽的表达方式来描述一个问题,是自己写给自己看的东西,看了几遍之后就能非常迅速和容易地理解。之后遇到相同的问题可以快速地通过找笔记解决。&/b&&/p&&p&举个例子,下图是我记录的一些关于gdb【linux下调试c++的工具】的使用的一些笔记。我只记录了我自己最常用的一些内容,也许你看着很乱,但是我就能很容易看懂,这就是我的定制化。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-6b9bdba6bb42c72f4d8cc9_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&2268& data-rawheight=&1546& class=&origin_image zh-lightbox-thumb& width=&2268& data-original=&https://pic3.zhimg.com/v2-6b9bdba6bb42c72f4d8cc9_r.jpg&&&/figure&&p&记笔记的习惯一定要坚持,等过个一年或者两年,这就是你巨大的财富,因为那是只有你才能看懂的东西。我已经记录了4年多、1G多的内容,现在的笔记基本已经形成了体系,可以给大家展示其中的一部分。&/p&&p&专业知识相关笔记:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-1a92b35caf6c7daa7fce92d8b37ba5b4_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&559& data-rawheight=&817& class=&origin_image zh-lightbox-thumb& width=&559& data-original=&https://pic3.zhimg.com/v2-1a92b35caf6c7daa7fce92d8b37ba5b4_r.jpg&&&/figure&&p&开发相关的笔记:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-e47df51a4ad6c7f7cb239a1_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&559& data-rawheight=&924& class=&origin_image zh-lightbox-thumb& width=&559& data-original=&https://pic3.zhimg.com/v2-e47df51a4ad6c7f7cb239a1_r.jpg&&&/figure&&p&一些类目:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-ac61d7e115b0f3bdbae27c390d923141_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&239& data-rawheight=&991& class=&content_image& width=&239&&&/figure&&p&&i&&b&5.有什么比较好的编程方法?&/b&&/i&&/p&&p&除了上述分享的一些方法,我认为在同一时间段不要学习太多类别的课程,比如你可以同时学习python和html/css,但是你不要同时学python、操作系统、编译原理、计算机组成、数据结构、网络,我曾经试过,一门课没学一会儿就学下一门,其实上一门根本学不到什么实际的知识。因为记忆知识是符合&b&艾宾浩斯记忆曲线&/b&的。对于一门课,特别是很难的专业课,譬如操作系统,你每天看半小时,效果是比较差的,可能你热身就得半小时。所以宁可每天学两门,然后每一门学长一点的时间,比如两小时。【毕竟学校上课,一次课也得两小时】,要避免贪多,一口吃不成个胖子。 &/p&&p&&br&&/p&&p&&i&&b&6.我需要刷oj么?&/b&&/i&&/p&&p&我认为刚开始编程的时候还是应该刷的,但是一定要注意,不要被你周围的“X神”给误导了。因为我上大学的时候,身边总是有很多搞计算机竞赛的人,他们之间都互相称对方为“X神”,某某神又使用一个牛逼的算法,将程序时间从1秒降低到了0.999秒。我要劝大家的是,刷题不是为了达到这个目的,不是说非要在竞赛中拿奖,除非你是特别喜欢,否则,没必要去&b&背代码&/b&。我们刷题的目的是适应写代码的感觉,在这个过程中你会遇到编译错误,你会慢慢去记住一些语法、关键字,并理解一些概念,还可以自己去使用它,比如实现数据结构。慢慢的你就会变得有经验,知道一些错误产生的原因。我也是慢慢这样过来的,我现在在工作和下班以后写代码时,基本都不用IDE了,比如写c++,要么vim,要么就是sublime,而调试用的是我前面提到的工具gdb。即,有一个文本编辑器就能写代码,脱离了IDE的束缚。在写oj之后一段时间,在比较熟练了之后,就可以不去刷题了,可以去譬如github这样的网站上找点项目来看,然后自己跟着写一下,编程能力慢慢就提升了。就计算机专业来说,很多同学在大一上完编程课之后,就很少写代码了,这样是很不好的。刷题除了可以锻炼编程能力,对于找工作前突击也很有作用。比如,我之前投递过华为公司的研发岗位,校招的时候有笔试题。我就在16年国庆的时候刷了一下华为的oj,我记得笔试是600分的总分,过100就给面试机会,而我很轻松的就拿了500分,而当时也就刷了20多道华为的题。 &/p&&figure&&img src=&https://pic3.zhimg.com/v2-3d5b9bcf85aeb841a9537_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1080& data-rawheight=&674& class=&origin_image zh-lightbox-thumb& width=&1080& data-original=&https://pic3.zhimg.com/v2-3d5b9bcf85aeb841a9537_r.jpg&&&/figure&&p&&i&&b&7.看书还是看视频?&/b&&/i&&/p&&p&网上有不少人鄙视看视频学习的同学,我不知道为什么,因为我认为看视频是一个很好的学习方式。不过我们得明白看书和看视频分别有什么优缺点。&/p&&p&其实我是很建议看视频入门的,因为目前网上的应用型【非学术型:比如清华大学的操作系统,非常难】的视频都是很简单的,很多是面向初学者的,视频能用较短的时间告诉你你现在所学的技术可以干什么,可能需要先修哪些知识,可以帮助我们搭建一个项目驱动式学习的网络。可是视频也有个缺点:就是知识非常的杂,很不系统。虽然现在很多教学网站都提供了学习路径,但是这些路径中的视频很多时候都不是同一个老师录制的,只是按照知识的依赖关系排的顺序,所以,如果想通过视频去系统地学习一门知识,是比较困难的。【当然,一些学术型的视频还是很推荐的,比如斯坦福的机器学习,清华的操作系统、数据结构等课程,能坚持看完,绝对受益匪浅】。而应用型的,比如web开发等知识,还是得看书。书籍等特点就是系统化,由浅入深,你可以定制化地看自己薄弱的章节。所以一个比较好的学习方式是:&/p&&p&&i&&b&看视频入门,看书进阶。&/b&&/i&&/p&&p&&br&&/p&&p&&i&&b&8.多久能学会编程?&/b&&/i&&/p&&p&其实这个问题是没有答案的,如果只是想做出一个小应用,2个月足矣,而就我个人而言,我认为学习编程不是学习一种编程语言,而是学习一个生态,一个计算机系统,所以无止境。&/p&&p&&br&&/p&&p&&i&&b&9.我应该选择什么资料,看什么书?&/b&&/i&&/p&&p&其实这个问题也是很多编程新手容易困惑的问题。网络上拥有我们一辈子都看不完的教程和资料,所以现在应该不会存在找不着视频教程、找不着书看的问题。而问题就是我们不知道看什么视频、看什么书。从开始学编程到现在,我也买了上百本书,而真正适合自己的好书并不多。而视频教程的问题就更严重了,东看一点、西看一点,知识很难组织成网络。所以&b&学习编程的过程中,我们遇到的最大的问题是:当我们遇到问题的时候,在大量资料面前,我们不知道选择什么资料去学习。&/b&即使我们使用项目驱动式学习的方法找到了我们的方向,但是同一个路径下,也有很多资料。前文列举的项目驱动式学习的图中,我们是自上而下的去发现问题,然后再解决问题。如果能有人帮我们组织好学习路径,然后自下而上地去学习,那么效率可能会提高很多。&/p&&p&&i&&b&不过不用担心,我已经尽我所能,将我看过或者我认为好的课程和书本资料给串了串,整理好上传了,所有学习资料均免费,无任何收费课程。&/b&&/i&&/p&&p&&i&&b&如果需要,请关注微信公众号【大数据前沿】回复:【编程路径】获取。&/b&&/i& &/p&&p&&b&如果觉得有帮助,请直接赞赏!!!&/b&&/p&&p&顺便插播个广告:&/p&&p&【大数据前沿】:用键盘舞动青春,用数据描绘世界。传播IT技术,发现编程之美。了解科技前沿,挖掘数据价值。人生苦短,我用python,编程路上,有我陪你。如果你想和我一起学习编程,就用微信搜索:【大数据前沿】关注吧,&b&对于部分技术性文章,我会录制视频教程分享实现过程,有时候也会留下数据和代码让读者练习&/b&。让我们一起进步吧!&/p&&p&近期热文:&/p&&a href=&https://zhuanlan.zhihu.com/p/& data-draft-node=&block& data-draft-type=&link-card& data-image=&https://pic2.zhimg.com/v2-ebcfa76c746dd224f7af543bdx120.jpg& data-image-width=&400& data-image-height=&240& class=&internal&&二胖:大数据解密之你的同事都跳槽到了哪些公司&/a&&a href=&https://zhuanlan.zhihu.com/p/& data-draft-node=&block& data-draft-type=&link-card& data-image=&https://pic3.zhimg.com/v2-9d62b11bdce05fc0d35a_180x120.jpg& data-image-width=&400& data-image-height=&245& class=&internal&&二胖:30岁,大学毕业的你,月薪多少?&/a&&a href=&https://zhuanlan.zhihu.com/p/& data-draft-node=&block& data-draft-type=&link-card& data-image=&https://pic4.zhimg.com/v2-369ec090d7aed9cc4a017_180x120.jpg& data-image-width=&500& data-image-height=&350& class=&internal&&二胖:大数据告诉你旅行青蛙饲养员的秘密&/a&&a href=&https://zhuanlan.zhihu.com/p/& data-draft-node=&block& data-draft-type=&link-card& data-image=&https://pic3.zhimg.com/v2-959b7bda8be9dc83abd2_180x120.jpg& data-image-width=&1126& data-image-height=&630& class=&internal&&二胖:用 python 挖一挖成都房价&/a&&a href=&https://zhuanlan.zhihu.com/p/& data-draft-node=&block& data-draft-type=&link-card& data-image=&https://pic2.zhimg.com/v2-fad3b31d94bbef0f48c29_180x120.jpg& data-image-width=&971& data-image-height=&703& class=&internal&&二胖:不会爬虫怎么获取数据?&/a&&p&End&/p&&figure&&img src=&https://pic4.zhimg.com/v2-0e5bb3350f3fdd1afd8c_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&720& data-rawheight=&466& class=&origin_image zh-lightbox-thumb& width=&720& data-original=&https://pic4.zhimg.com/v2-0e5bb3350f3fdd1afd8c_r.jpg&&&/figure&&p&&/p&
从大一入学被调剂到计算机专业,到喜欢上这个专业,再到毕业拿到10多个offer,最终进入理想的大厂工作。回想起来这些年确确实实踩了很多坑。我刚开始学习编程的时候也想一口吃成一个胖子,想速成,但是有时候却是不尽人意。回忆了下这几年学习编程的过程,…
算法,第四版。&br&我是计算机应用技术专业,现在也在学数据结构,不过学的很渣,我是“坏学生”。&br&一次去豆瓣看我们的教材的时候看了下面的评论推荐这书。&br&百度云链接(不完全版本):链接: &a href=&//link.zhihu.com/?target=http%3A//pan.baidu.com/s/1jGE7h6A& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&百度云 请输入提取密码&/a& 密码: lljo
算法,第四版。 我是计算机应用技术专业,现在也在学数据结构,不过学的很渣,我是“坏学生”。 一次去豆瓣看我们的教材的时候看了下面的评论推荐这书。 百度云链接(不完全版本):链接:
密码: lljo
1. Nicholas Zakas 写的 &a href=&//link.zhihu.com/?target=http%3A//www.slideshare.net/nzakas/scalable-javascript-application-architecture& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&slideshare.net/nzakas/s&/span&&span class=&invisible&&calable-javascript-application-architecture&/span&&span class=&ellipsis&&&/span&&/a&&br&2.《基于MVC的JavaScript Web 富应用开发》 &a href=&//link.zhihu.com/?target=http%3A//book.douban.com/subject/6397064/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&book.douban.com/subject&/span&&span class=&invisible&&/6397064/&/span&&span class=&ellipsis&&&/span&&/a&&br&3. 张克军:前端基础架构的实践和思考 &a href=&//link.zhihu.com/?target=http%3A//www.slideshare.net/taobaoued/ss-9440002& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&slideshare.net/taobaoue&/span&&span class=&invisible&&d/ss-9440002&/span&&span class=&ellipsis&&&/span&&/a&&br&4. DexterYy 新版阿尔法城背后的前端MVC实践
&a href=&//link.zhihu.com/?target=http%3A//www.slideshare.net/taobaoued/mvcmvc-behindalphatown& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&slideshare.net/taobaoue&/span&&span class=&invisible&&d/mvcmvc-behindalphatown&/span&&span class=&ellipsis&&&/span&&/a&
1. Nicholas Zakas 写的
2.《基于MVC的JavaScript Web 富应用开发》
3. 张克军:前端基础架构的实践和思考
4. DexterYy 新版阿尔法城背后的前端MVC实践
后文于新增内容,以下是原文。&br&- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -&br&&br&&b&架构是一个演变的过程。&/b&&br&它指的不是随着历史的演变,而是随着项目演变。&br&通常说架构,指的是架构模式,自创的架构很少。&br&了解架构模式,才能心有余力的应对项目的发展。&br&&br&前端项目大概会经历以下这些阶段:&br&1. 整体渲染&br&2. 结构行为表现分离&br&3. 隔离逻辑单元&br&4. 插件&br&5. 模块&br&6. 前端MVC/MVVM&br&7. 组件&br&- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -&br&&br&下面分别介绍一下:&br&&b&1. 整体渲染&/b&&br&&figure&&img src=&https://pic3.zhimg.com/50/be1f781a0cd38c9098cde1_b.jpg& data-rawwidth=&247& data-rawheight=&267& class=&content_image& width=&247&&&/figure&所有页面代码放到了一个html文档中,适合个人实验室项目。&br&新建一个文件,快速的验证某个功能或者开发某个组件,再移植到开发环境中。&br&&br&优点:开发速度快,执行过程清晰&br&不足:不容易分工合作&br&&br&&b&2. 结构行为表现分离&/b&&br&&figure&&img src=&https://pic3.zhimg.com/50/3ed69d7f453d8a8568a0f_b.jpg& data-rawwidth=&196& data-rawheight=&221& class=&content_image& width=&196&&&/figure&当页面中有了好几个Script和Style片段,这时候就想着是不是该把它们放到一个文件中了。&br&不然总在一个页面拖上拖下}

我要回帖

更多关于 faa225 下载 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信