看动画轻松理解“递归”与“动态规划”
作者 | 程序员小吴
来源 | 五分钟学算法
在学习「数据结构和算法」的过程中,因为人习惯了平铺直叙的思维方式,所以「递归」与「动态规划」这种带循环概念(绕来绕去)的往往是相对比较难以理解的两个抽象知识点。
程序员小吴打算使用动画的形式来帮助理解「递归」,然后通过「递归」的概念延伸至理解「动态规划」算法思想。
什么是递归
先下定义:递归算法是一种直接或者间接调用自身函数或者方法的算法。
通俗来说,递归算法的实质是把问题分解成规模缩小的同类问题的子问题,然后递归调用方法来表示问题的解。它有如下特点:
一个问题的解可以分解为几个子问题的解
这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样
存在递归终止条件,即必须有一个明确的递归结束条件,称之为递归出口
递归动画
通过动画一个一个特点来进行分析。
1.一个问题的解可以分解为几个子问题的解
子问题就是相对与其前面的问题数据规模更小的问题。
在动图中①号问题(一块大区域)划分为②号问题,②号问题由两个子问题(两块中区域)组成。
2. 这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样
「①号划分为②号」与「②号划分为③号」的逻辑是一致的,求解思路是一样的。
3. 存在递归终止条件,即存在递归出口
把问题分解为子问题,把子问题再分解为子子问题,一层一层分解下去,不能存在无限循环,这就需要有终止条件。
①号划分为②号,②号划分为③号,③号划分为④号,划分到④号的时候每个区域只有一个不能划分的问题,这就表明存在递归终止条件。
从递归的经典示例开始
一、数组求和
数组求和
11Sum(arr[0...n-1]) = arr[0] + Sum(arr[1...n-1])
后面的 Sum 函数要解决的就是比前一个 Sum 更小的同一问题。
11Sum(arr[1...n-1]) = arr[1] + Sum(arr[2...n-1])
以此类推,直到对一个空数组求和,空数组和为 0 ,此时变成了最基本的问题。
11Sum(arr[n-1...n-1] ) = arr[n-1] + Sum([])
二、汉诺塔问题
汉诺塔(Hanoi Tower)问题也是一个经典的递归问题,该问题描述如下:
汉诺塔问题:古代有一个梵塔,塔内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上。有一个和尚想把这个盘子从A座移到B座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上。
两个盘子
三个盘子
① 如果只有 1 个盘子,则不需要利用 B 塔,直接将盘子从 A 移动到 C 。
② 如果有 2 个盘子,可以先将盘子 2 上的盘子 1 移动到 B ;将盘子 2 移动到 C ;将盘子 1 移动到 C 。这说明了:可以借助 B 将 2 个盘子从 A 移动到 C ,当然,也可以借助 C 将 2 个盘子从 A 移动到 B 。
③ 如果有 3 个盘子,那么根据 2 个盘子的结论,可以借助 C 将盘子 3 上的两个盘子从 A 移动到 B ;将盘子 3 从 A 移动到 C ,A 变成空座;借助 A 座,将 B 上的两个盘子移动到 C 。
④ 以此类推,上述的思路可以一直扩展到 n 个盘子的情况,将将较小的 n-1个盘子看做一个整体,也就是我们要求的子问题,以借助 B 塔为例,可以借助空塔 B 将盘子A上面的 n-1 个盘子从 A 移动到 B ;将A 最大的盘子移动到 C , A 变成空塔;借助空塔 A ,将 B 塔上的 n-2 个盘子移动到 A,将 C 最大的盘子移动到 C, B 变成空塔……
三、爬台阶问题
问题描述:
一个人爬楼梯,每次只能爬1个或2个台阶,假设有n个台阶,那么这个人有多少种不同的爬楼梯方法?
先从简单的开始,以 4 个台阶为例,可以通过每次爬 1 个台阶爬完楼梯:
每次爬 1 个台阶
可以通过先爬 2 个台阶,剩下的每次爬 1 个台阶爬完楼梯
先爬 2 个台阶
在这里,可以思考一下:可以根据第一步的走法把所有走法分为两类:
① 第一类是第一步走了 1 个台阶
② 第二类是第一步走了 2 个台阶
所以 n 个台阶的走法就等于先走 1 阶后,n-1 个台阶的走法 ,然后加上先走 2 阶后,n-2 个台阶的走法。
用公式表示就是:
f(n) = f(n-1)+f(n-2)
有了递推公式,递归代码基本上就完成了一半。那么接下来考虑递归终止条件。
当有一个台阶时,我们不需要再继续递归,就只有一种走法。
所以 f(1)=1
。
通过用 n = 2
,n = 3
这样比较小的数试验一下后发现这个递归终止条件还不足够。
n = 2
时,f(2) = f(1) + f(0)
。如果递归终止条件只有一个f(1) = 1
,那 f(2)
就无法求解,递归无法结束。
所以除了 f(1) = 1
这一个递归终止条件外,还要有f(0) = 1
,表示走 0 个台阶有一种走法,从思维上以及动图上来看,这显得的有点不符合逻辑。所以为了便于理解,把 f(2) = 2
作为一种终止条件,表示走 2 个台阶,有两种走法,一步走完或者分两步来走。
总结如下:
① 假设只有一个台阶,那么只有一种走法,那就是爬 1 个台阶
② 假设有两个个台阶,那么有两种走法,一步走完或者分两步来走
递归终止条件
通过递归条件:
11f(1) = 1;
22f(2) = 2;
33f(n) = f(n-1)+f(n-2)
很容易推导出递归代码:
11int f(int n) {
22 if (n == 1) return 1;
33 if (n == 2) return 2;
44 return f(n-1) + f(n-2);
55}
通过上述三个示例,总结一下如何写递归代码:
找到如何将大问题分解为小问题的规律
通过规律写出递推公式
通过递归公式的临界点推敲出终止条件、
将递推公式和终止条件翻译成代码
什么是动态规划
介绍动态规划之前先介绍一下分治策略(Divide and Conquer)。
分治策略
将原问题分解为若干个规模较小但类似于原问题的子问题(Divide),「递归」的求解这些子问题(Conquer),然后再合并这些子问题的解来建立原问题的解。
因为在求解大问题时,需要递归的求小问题,因此一般用「递归」的方法实现,即自顶向下。
动态规划(Dynamic Programming)
动态规划其实和分治策略是类似的,也是将一个原问题分解为若干个规模较小的子问题,递归的求解这些子问题,然后合并子问题的解得到原问题的解。
区别在于这些子问题会有重叠,一个子问题在求解后,可能会再次求解,于是我们想到将这些子问题的解存储起来,当下次再次求解这个子问题时,直接拿过来就是。
其实就是说,动态规划所解决的问题是分治策略所解决问题的一个子集,只是这个子集更适合用动态规划来解决从而得到更小的运行时间。
即用动态规划能解决的问题分治策略肯定能解决,只是运行时间长了。因此,分治策略一般用来解决子问题相互对立的问题,称为标准分治,而动态规划用来解决子问题重叠的问题。
与「分治策略」「动态规划」概念接近的还有「贪心算法」「回溯算法」,由于篇幅限制,程序员小吴就不在这进行展开,在后续的文章中将分别详细的介绍「贪心算法」、「回溯算法」、「分治算法」,敬请关注:)
将「动态规划」的概念关键点抽离出来描述就是这样的:
1.动态规划法试图只解决每个子问题一次
2.一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。
从递归到动态规划
还是以 爬台阶 为例,如果以递归的方式解决的话,那么这种方法的时间复杂度为O(2^n),具体的计算可以查看笔者之前的文章 《冰与火之歌:时间复杂度与空间复杂度》。
相同颜色代表着 爬台阶问题 在递归计算过程中重复计算的部分。
爬台阶的时间复杂度
通过图片可以发现一个现象,我们是 自顶向下 的进行递归运算,比如:f(n)
是f(n-1)与f(n-2)
相加,f(n-1)
是f(n-2)
与f(n-3)
相加。
思考一下:如果反过来,采取自底向上,用迭代的方式进行推导会怎么样了?
下面通过表格来解释 f(n)
自底向上的求解过程。
台阶数 1 2 3 4 5 6 7 8 9
走法数 1 2
表格的第一行代表了楼梯台阶的数目,第二行代表了若干台阶对应的走法数。
其中f(1) = 1
和 f(2) = 2
是前面明确的结果。
第一次迭代,如果台阶数为 3 ,那么走法数为 3 ,通过 f(3) = f(2) + f(1)
得来。
第二次迭代,如果台阶数为 4 ,那么走法数为 5 ,通过 f(4) = f(3) + f(2)
得来。
由此可见,每一次迭代过程中,只需要保留之前的两个状态,就可以推到出新的状态。
show me the code
11int f(int n) {
2 2 if (n == 1) return 1;
3 3 if (n == 2) return 2;
4 4 // a 保存倒数第二个子状态数据,b 保存倒数第一个子状态数据, temp 保存当前状态的数据
5 5 int a = 1, b = 2;
6 6 int temp = a + b;
7 7 for (int i = 3; i <= n; i++) {
8 8 temp = a + b;
9 9 a = b;
1010 b = temp;
1111 }
1212 return temp;
1313}
程序从 i = 3
开始迭代,一直到 i = n
结束。每一次迭代,都会计算出多一级台阶的走法数量。迭代过程中只需保留两个临时变量 a 和 b ,分别代表了上一次和上上次迭代的结果。为了便于理解,引入了temp 变量。temp 代表了当前迭代的结果值。
看一看出,事实上并没有增加太多的代码,只是简单的进行了优化,时间复杂度便就降为O(n),而空间复杂度也变为O(1),这,就是「动态规划」的强大!
详解动态规划
「动态规划」中包含三个重要的概念:
【最优子结构】
【边界】
【状态转移公式】
在「 爬台阶问题 」中
f(10) = f(9) + f(8)
是【最优子结构】f(1) 与 f(2)
是【边界】f(n) = f(n-1) + f(n-2)
【状态转移公式】
「 爬台阶问题 」 只是动态规划中相对简单的问题,因为它只有一个变化维度,如果涉及多个维度的话,那么问题就变得复杂多了。
难点就在于找出 「动态规划」中的这三个概念。
比如「 国王和金矿问题 」。
国王和金矿问题
有一个国家发现了 5 座金矿,每座金矿的黄金储量不同,需要参与挖掘的工人数也不同。参与挖矿工人的总数是 10 人。每座金矿要么全挖,要么不挖,不能派出一半人挖取一半金矿。要求用程序求解出,要想得到尽可能多的黄金,应该选择挖取哪几座金矿?
5 座金矿
找出 「动态规划」中的这三个概念
国王和金矿问题中的【最优子结构】
国王和金矿问题中的【最优子结构】
国王和金矿问题中的【最优子结构】有两个:
① 4 金矿 10 工人的最优选择
② 4 金矿 (10 - 5) 工人的最优选择
4 金矿的最优选择与 5 金矿的最优选择之间的关系是
MAX[(4 金矿 10 工人的挖金数量),(4 金矿 5 工人的挖金数量 + 第 5 座金矿的挖金数量)]
国王和金矿问题中的【边界】
国王和金矿问题中的【边界】 有两个:
① 当只有 1 座金矿时,只能挖这座唯一的金矿,得到的黄金数量为该金矿的数量
② 当给定的工人数量不够挖 1 座金矿时,获取的黄金数量为 0
国王和金矿问题中的【状态转移公式】
我们把金矿数量设为 N,工人数设为 W,金矿的黄金量设为数组G[],金矿的用工量设为数组P[],得到【状态转移公式】:
边界值:F(n,w) = 0 (n <= 1, w < p[0])
F(n,w) = g[0] (n==1, w >= p[0])
F(n,w) = F(n-1,w) (n > 1, w < p[n-1])
F(n,w) = max(F(n-1,w), F(n-1,w-p[n-1]) + g[n-1]) (n > 1, w >= p[n-1])
国王和金矿问题中的【实现】
先通过几幅动画来理解 「工人」 与 「金矿」 搭配的方式
1.只挖第一座金矿
只挖第一座金矿
在只挖第一座金矿前面两个工人挖矿收益为 零,当有三个工人时,才开始产生收益为 200,而后即使增加再多的工人收益不变,因为只有一座金矿可挖。
2.挖第一座与第二座金矿
挖第一座金矿与第二座金矿
在第一座与第二座金矿这种情况中,前面两个工人挖矿收益为 零,因为 W < 3,所以F(N,W) = F(N-1,W) = 0。
当有 三 个工人时,将其安排挖第 一 个金矿,开始产生收益为 200。
当有 四 个工人时,挖矿位置变化,将其安排挖第 二 个金矿,开始产生收益为 300。
当有 五、六 个工人时,由于多于 四 个工人的人数不足以去开挖第 一 座矿,因此收益还是为 300。
当有 七 个工人时,可以同时开采第 一 个和第 二 个金矿,开始产生收益为 500。
3.挖前三座金矿
这是「国王和金矿」 问题中最重要的一个动画之一,可以多看几遍
挖前三座金矿
4.挖前四座金矿
这是「国王和金矿」 问题中最重要的一个动画之一,可以多看几遍
挖前四座金矿
国王和金矿问题中的【规律】
仔细观察上面的几组动画可以发现:
对比「挖第一座与第二座金矿」和「挖前三座金矿」,在「挖前三座金矿」中,3 金矿 7 工人的挖矿收益,来自于 2 金矿 7 工人和 2 金矿 4 工人的结果,Max(500,300 + 350) = 650;
对比「挖前三座金矿」和「挖前四座金矿」,在「挖前四座金矿」中,4 金矿 10 工人的挖矿收益,来自于 3 金矿 10 工人和 3 金矿 5 工人的结果,Max(850,400 + 300) = 850;
国王和金矿问题中的【动态规划代码】
1 1代码来源:https://www.cnblogs.com/SDJL/archive/2008/08/22/1274312.html
2 2
3 3//maxGold[i][j] 保存了i个人挖前j个金矿能够得到的最大金子数,等于 -1 时表示未知
4 4int maxGold[max_people][max_n];
5 5
6 6int GetMaxGold(int people, int mineNum){
7 7 int retMaxGold; //声明返回的最大金矿数量
8 8 //如果这个问题曾经计算过
9 9 if(maxGold[people][mineNum] != -1){
1010 retMaxGold = maxGold[people][mineNum]; //获得保存起来的值
1111 }else if(mineNum == 0) { //如果仅有一个金矿时 [ 对应动态规划中的"边界"]
1212 if(people >= peopleNeed[mineNum]) //当给出的人数足够开采这座金矿
1313 retMaxGold = gold[mineNum]; //得到的最大值就是这座金矿的金子数
1414 else //否则这唯一的一座金矿也不能开采
1515 retMaxGold = 0; //得到的最大值为 0 个金子
1616 }else if(people >= peopleNeed[mineNum]) // 如果人够开采这座金矿[对应动态规划中的"最优子结构"]
1717 {
1818 //考虑开采与不开采两种情况,取最大值
1919 retMaxGold = max(
2020 GetMaxGold(people - peopleNeed[mineNum],mineNum - 1) + gold[mineNum],
2121 GetMaxGold(people,mineNum - 1)
2222 );
2323 }else//否则给出的人不够开采这座金矿 [ 对应动态规划中的"最优子结构"]
2424 {
2525 retMaxGold = GetMaxGold(people,mineNum - 1); //仅考虑不开采的情况
2626 maxGold[people][mineNum] = retMaxGold;
2727 }
2828 return retMaxGold;
2929}
动态规划代码
希望通过这篇文章,大家能对「递归」与「动态规划」有一定的理解。后续将以「动态规划」为基础研究多重背包算法、迪杰特斯拉算法等更高深的算法问题,同时「递归」的更多概念也会在「分治算法」章节再次延伸,敬请对程序员小吴保持关注。
(*本文仅代表作者观点,转载请联系原作者)
公开课预告
◆
推荐系统
◆
本次分享带你揭开个性化推荐的神秘面纱,从推荐算法到大型系统架构进行全面剖析。
添加小助手微信csdnai2,回复:推荐系统,加入课程交流群,课程回放以及PPT将在群内分享。
推荐阅读
AI女性界的“扛把子”,凭一己之力迫使NIPS改名
印度小哥“神剑”:PDF提取表格so easy!
精选180+Python开源项目,随你选!做项目何愁没代码
100多本Python书,免费下载
面向对象编程,再见!
程序员怒了!阿里 Antd 圣诞彩蛋害我被离职了!
00后也会「玩」区块链,你对「朝阳」行业焦虑啥 ?| 圣诞特辑(文末有福利)
云计算到底是怎么玩的?
相关文章:
毕业季:理想很丰满,现实也可以很丰满!
六月,原本不是一个适合离开的季节,不是烈日,就是暴雨,让人不得不走走停停,频频回望。然而,哪个季节又适合离开呢?六月,确实得离开了。大学几年的时光终将逝去,而之后各位…

php扩展模块安装-lamp
php扩展模块安装 PECL 的全称是 The PHP Extension Community Library ,是一个开放的并通过 PEAR(PHP Extension and Application Repository,PHP 扩展和应用仓库)打包格式来打包安装的 PHP扩展库仓库。通过 PEAR 的 Package Manager 的安装管理方式&…

一文搞懂K近邻算法(KNN),附带多个实现案例
简介:本文作者为 CSDN 博客作者董安勇,江苏泰州人,现就读于昆明理工大学电子与通信工程专业硕士,目前主要学习机器学习,深度学习以及大数据,主要使用python、Java编程语言。平时喜欢看书,打篮球…
致那些还在创业之路上孤独前行的青年大学生们!
彩虹,在大雨后出现 腊梅,在风雪中吐蕊 雄鹰,在险峰上空盘旋 人,在困境中弥坚 在这个创业的浪潮中 你是否也是其中之一 当所有事情都将有你一个人来完成 你是否有信心和能力把它做好 成功不是回首,不是寄望,…

MS DTC 无法正确处理 DC 升级/降级事件的解决
当Windows 2003安装AD后,经常出现以下警告信息的解决方法:MS DTC 无法正确处理 DC 升级/降级事件。MS DTC 将继续运行并将使用现有的安全设置。错误说明: %1, 打开管理工具的组件服务管理控制台,打开组件服务,计算机。右击我的电…

UML图的分类
作为一种建模语言,UML的定义包括UML语义和UML表示法两个部分。 (1) UML语义 描述基于UML的精确元模型定义。元模型为UML的所有元素在语法和语义上提供了简单、一致、通用的定义性说明,使开发者能在语义上取得一致,消除了因人而异的最佳表达方法所造成的影响。此外UML还支持对元…
告诫那些有创业梦的大学生,切记千万不要盲目创业!
如果你打算创业,那么最好具备两点: 一是有一定的经济实力或行业经验和人脉, 二是没有太多后顾之忧。 有一部分创业者是前期赚了一些钱,能确保基本生活的质量!所以可以全身心投入到创业中,提高成功的概率。然…

春运渡劫!Python给我抢回家的火车票
简介:本文首发于个人公众号「视学算法」,作者阿广,一个专注于大数据、人工智能和算法的学习平台,也是一个保送中科院软件研究所直博生的自留地。人生苦短,我愿做您最忠实的技术支持伙伴!一起用代码改变世界…

首次成功实施 XSS 攻击,盗取目标网站大量 VIP 帐号
前言 之前做网站时有做代码防御 XSS(Cross Site Script) 攻击,但是却只处于了解的阶段,并不知道其中具体的原理,更别说使用了。最近有朋友要求我帮助他 Hack 一个网站,达到一定的目的。思考来思考去,最后想了一套方案&…

oracle取得表中总记录数最快的方法
查询表中的记录总数的语法就是SELECT COUNT(*) FROM TABLE_NAME。这可能是最经常使用的一类SQL语句。 本文讨论怎样才能最快的得到这个记录数。本文纯粹主要是理论上的讨论,文章中很多内容(如常数索引)对实际的指导意义不大。 在具体描述之前…
你的创业前行之路,亲君愿与你一路相随
每一个创业者都是黑暗中的独行侠, 然后告诉别人光明就在前方, 其实, 他们自己心里也不知道光明还有多远。 无论当初是因为理想还是因为实现个人价值, 只要走上创业这条路, 我们就只能不断的告诉自己和他人:…

年度重磅:《AI聚变:2018年优秀AI应用案例TOP 20》正式发布
2018 年,AI 行业的关键词或许非“落地”二字莫属 ,人们强烈期待着更多 AI 技术应用和深入商业化。 一方面,科技巨头们在横向铺设 AI 技术平台,但也更强调 AI 与每一个垂直行业的深度融合。而另一面,AI 创业公司在频繁刷…

防止熊猫烧香的微软补丁
为了防止熊猫烧香病毒,要及时安装微软的安全更新,不要随意访问来源不明的网站。特别是微软的MS06-014漏洞,应立即打好该漏洞补丁。 不知道这个补丁是不是已经打上的朋友,一是在控制面板里可以看到.(勾上显示更新前面的方框),或者下载360安全卫士,扫描漏洞…

【Azure Services Platform Step by Step-第11篇】Windows Azure兰州拉面馆-日志与队列的使用...
在第9篇里,为了便于大家理解,我把Windows Azure的环境比喻成了"Azure兰州拉面馆"。本篇我们继续沿用这个比喻,讲讲Windows Azure中的队列(Queue Storage)与日志的使用。 Queue Storage在【Azure Services Platform Step by Step-第…
这才是世界排名前十位的奢侈品
真正的奢侈品,不是豪车大宅,不是名包贵表,而是这些…… 1. 一颗童心2. 生生不息的信念3. 背包走天下的健康体魄4. 愉悦和舒心的工作环境5. 安稳平和的睡眠6. 享受属于自己空间与时间的生活7. 牵手一个教会你爱与被爱的人8. 品味美好的心情…

配置springmvc在其他类中(spring容器外)获取注入bean
今天在写JedisUtils的时候要注入JedisPool,而这个属性被设置为static,Resource和Autowired都不可以注入,因为spring不能为静态变量依赖注入。因此需要额外的方法获取spring管理的bean。本文即SpringContextHolder: 1 package com.…

声智科技完成2亿元B轮融资,将持续拓展语音交互产品的规模化落地
整理 | 一一出品 | AI科技大本营寒冬之下,不少创业公司依然得到了资本青睐。AI科技大本营消息,12 月 29 日消息,声智科技(SoundAI)已于近期完成 2 亿人民币 B 轮融资,本轮投资由毅达资本领投,峰…

360度看IT行业--3月12日西安工程大学讲座
2009年3月12日,一个绿色的好日子。当天晚上7点30分,在西安工程大学的讲座开始了。西安工程大学的孩子们很热情,大一大二的居多,虽然是非计算机专业,但提前就满满的坐在会场等待了。而且很关注IT行业,提了很…

专访中国移动钱岭:大数据更像是一种“倍增器”
记者 | 杨丽出品 | AI科技大本营(rgznai100)为把握时代特征,2016 年中国移动确定并大力推动“大连接”战略,并制定了“十三五”时期做大连接规模、做优连接服务、做强连接应用的三个目标。如今,这家企业已经拥有 9.16 亿移动端用户…

创业者应该如何看待金钱
什么是真正的赢?一个高智商、高情商的商人,经营企业追求的终极目标就是一个赢字:金钱、地位、豪宅、名车、美女、权利、荣耀,为了赢得这些,很多人曾不择手段,曾不断地苦苦寻找“如何以最小的投入快速获得最…

Exchange与ADFS单点登录 PART 2:部署和配置ADFS
在第一篇文章完了之后,我们就可以在我们的服务器上部署ADFS了,安装的方法很简单,直接在服务器管理器中添加功能角色即可,选择当前服务器并在服务器角色中选择ADFS。 完成之后我们需要对ADFS进行详细的配置,在服务器管理…

路由器和交换机的综合实验
路由器和交换机的综合实验<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />主要目标:1. 跨交换机(二层交换机)的相同VLAN 之间的通讯2. 不同VLAN之间的通讯1) 通过路由器实现不同VL…

如何写出符合Python审美的代码风格?
作者 | Rocky0429来源 | Python空间本文为 AI科技大本营投稿文章(欢迎给我们投稿,投稿请联系微信1092722531)写在之前每个人都有自己的代码风格,随着写的行数增加,自己对于代码的审美也会变的不一样,这就像…

程序员都该懂点 HTTP
作者:developerHaozGithub 地址:developerHaoz说明:本文主要是对 HTTP 基础知识进行总结和归纳,毕竟做 IT 的,网络这一块还是很重要的 本文的主要内容HTTP 是什么URL 详解HTTP 之请求篇HTTP 之响应篇一、HTTP是什么1、…

谁的青春不迷茫,其实我们都一样
如果你为人生画一条浅浅吃苦底线,就别妄想跨越深邃的幸福极限。在熠熠生辉前,总要捱过一段孤独不安的日子。唯有担得起厚重的经历,才能禁得起岁月推敲。记住:一定要努力,但别着急。加油! 很庆幸你能以这样好…

关于Iframe在IE6下不显示的bug
IE都出到IE8了,用IE6的人渐渐少了..但还是存在的.例如QAMM们在用. 所以,IE6下存在的问题也必须解决.这两天,我就遇到一个了: html<table> <tr> <td id"tdTest" runat"server"> <iframe id"ifrTest" h…

腾讯优图吴永坚:迈向深度学习,我们面临模型训练与推荐的双重考验
整理 | 琥珀出品 | AI 科技大本营对腾讯优图的发展历程,吴永坚表示,优图是非常幸运的,幸运的同时也知道优图选对了方向,只要坚持,还是会有收获的。12 月 15 日,以"新趋势、新技术、新应用"为主题…

JS子窗口调用父窗口中的函数
很简单只需要一句话就可以了: window.opener.changeColor(); 这里的changeColor()就是父窗口中JS的一个函数 本文转自sucre03 51CTO博客,原文链接:http://blog.51cto.com/sucre/377011,如需转载请自行联系原作者

父亲节遇上端午节,你难道不回家吗?
创业者是孤独的 他们选择了更加艰险的人生。 同时,他们又是幸运的 因为他们背后有一位伟大的父亲。 决定创业时 他说:“大胆去闯吧,有爸爸在” 创业失败时 他说:“累了就回家,有爸爸在” 简单朴实的话语包含的是无私广…

蜘蛛爬虫网络高像素图片抓取工具[搜索引擎]
ZSpider—— 是一款Photo crawler工具。主要功能:免费抓取网络高像素图片,并下载到本地。使用说明:1. 软件环境:Windows XP, 20003, Vista, 2008, Windows 7.NET Framework 3.52. 双击Spider.exe,选择菜单,…