程序员用什么电脑合适

calendar += ShengXiao[(year - 4) % 60 % 12].ToString() + "年 ";

,根据你前两条,你选择四核心的I7处理器(4核8线程,QM结尾的,如I7 3610QM),16G内存(我8G内存,运行两个win7虚拟机就有点吃紧了)。内存不是硬性指标,你储以买回来自己升级到16G,可以省不少。

github 慢 github慢的原因github 慢 github慢的原因


github 慢 github慢的原因


第二,对于你的3,现在主流的就是N卡GT640M,A卡是HD7730M,不过配置A卡的机型比较少,还是以N卡为主吧。

第三,你的4 和5的要求,目前是冲突的,要散热好,体积和重量一定小不了。特别是对于你要求得高负载下,机面不热,我看过不少评测,能达到这个要求的就外星人的M17X R4,地球人的准系统这样的游戏笔记本,以及移动工作站。这些都是15英寸及以上的机型,重量都不轻,当然价格亦不菲。

第四,有升级空间,那么我第三条里提到的游戏本和移动工作站都有很强的升级空间(显卡都可以升级的哦)。能不能用4~5年关键还是要看你的需要和平时的维护。

说这么多了,一个

DELL 灵越 14R TURBO(Ins14TD-3728)

屏幕尺寸:14英寸 1600x900

CPU型号:In 酷睿i7 3632QM

CPU主频:2.2GHz

内存容量:8GB DDR3 1600MHz

硬盘容量:1TB 5400转

显卡芯片:NVIDIA GeForce GT 640M+HD4000

问题二:程序员都用什么笔记本 首先,这种配置还要散热好的续航时间都长不了,而且也不会太轻。其次NBA 2K对配置的要求并没有这么高,可以考虑配置稍低但续航较长的电脑,标压i5+860M/960M就可以满足需求,剩下的钱可以加加SSD,内存什么的。

其实,还是看你是哪种类型。也就是你的需求。

1. 痴迷技术型

我认识一位朋友,大一开始给别人写程序,研究电脑研究技术。大三就自己挣钱买到了台thinkpad,大概1w多吧。这种人从硬件开始玩儿,自己组装电脑,慢慢玩儿到软件,对各种技术都玩儿过。如果你是这种的,那么买个性能好配置高的就行,因为你必须得折腾,不断折腾,反正,早坏早换。

2. 只是用来写程序

如果只是写写程序,做做开发 - 偏软件的这种。建议直接Macbook Pro。作为一个用过很多年windows刚转到mac 1年的码农来讲,只能说:太爽了!

1、适合的系统:Windows系的用Windows,Linux系的用Linux或者Mac。总之要和自己的需求一致,别给自己找到麻烦。

2、舒服的交互硬件。4k屏用不用的到不好说但是一个27寸以上的显示器人人都喜欢。双显很有用,三显不好说。因为我们总要开各种资料/网页,IDE,命令行编辑器什么的,小显示器你就慢慢恶心吧。机械键盘或者hhkb请上一个。

4、通畅的网络环境。咦怎么Google打不开?怎么GitHub这么慢?

5、其他配置根据不同的需求而定。比如跑GPU的,图形开发的显卡要给力一些。经常出的还要配个轻便续航强的笔记本。

不考虑钱的情况下,笔记本可以有:

p15寸低配版

dell xps15 2015核显定制版

thinkpad t540p核显定制高配版

它们的共同特点:

CPU(4代以上的四核标压i7)

硬盘速度快(256G第五,专门回答你的“PPS”,i5是不如i7的,我也不拿具体的型号比较了,你的要求就i7合适。B+固态硬盘)

大内存(16GB)

没有独显(CPU集成,低功耗,性能凑合)

超长续航(不插电正常使用10小时+)

屏幕大且分辨率高(15寸屏,1080p+)

轻薄(重2千克左右,厚20毫米左右)

1W+

这样的笔记本可以让你:

开IDE、跑程序嗖嗖的,特别快,不卡

码字、作图视野开阔,不担心眼瞎

不带电源出去用一天没问题,不用到处找插电

带着到处跑不觉得太累

合上盖子就可以带走,打开盖子就能用,不用关机

杜绝玩游戏(但是阻止不了玩LOL)

看题主像是个前端妹子,p比较合适,而且可能也是我列举的那三个里面比较便宜的了。

问题三:想了解程序员用什么电脑 首先,这种配置还要散热好的续航时间都长不了,而且也不会太轻。其次NBA 2K对配置的要求并没有这么高,可以考虑配置稍低但续航较长的电脑,标压i5+860M/960M就可以满足需求,剩下的钱可以加加SSD,内存什么的。其实,还是看你是哪种类型。也就是你的需求。1. 痴迷技术型 我认识一位朋友,大一开始给别人写程序,研究电脑研究技术。大三就自己挣钱买到了台thinkpad,大概1w多吧。这种人从硬件开始玩儿,自己组装电脑,慢慢玩儿到软件,对各种技术都玩儿过。如果你是这种的,那么买个性能好配置高的就行,因为你必须得折腾,不断折腾,反正,早坏早换。2. 只是用来写程序 如果只是写写程序,做做开发 - 偏软件的这种。建议直接Macbook Pro。作为一个用过很多年windows刚转到mac 1年的码农来讲,只能说:太爽了!1、适合的系统:Windows系的用Windows,Linux系的用Linux或者Mac。总之要和自己的需求一致,别给自己找到麻烦。2、舒服的交互硬件。4k屏用不用的到不好说但是一个27寸以上的显示器人人都喜欢。双显很有用,三显不好说。因为我们总要开各种资料/网页,IDE,命令行编辑器什么的,小显示器你就慢慢恶心吧。机械键盘或者hhkb请上一个。3、内存要大,CPU要快,硬盘要SSD。开一堆网页,开IDE都是很占资源的。编译的速度影响工作效率与心情。4、通畅的网络环境。咦怎么Google打不开?怎么GitHub这么慢?5、其他配置根据不同的需求而定。比如跑GPU的,图形开发的显卡要给力一些。经常出的还要配个轻便续航强的笔记本。不考虑钱的情况下,笔记本可以有:p15寸低配版dell xps15 2015核显定制版thinkpad t540p核显定制高配版它们的共同特点:CPU(4代以上的四核标压i7)硬盘速度快(256GB+固态硬盘)大内存(16GB)没有独显(CPU集成,低功耗,性能凑合)超长续航(不插电正常使用10小时+)屏幕大且分辨率高(15寸屏,1080p+)轻薄(重2千克左右,厚20毫米左右)1W+这样的笔记本可以让你:开IDE、跑程序嗖嗖的,特别快,不卡开浏览器、开IDE,再多也不担心内存不足码字、作图视野开阔,不担心眼瞎不带电源出去用一天没问题,不用到处找插电带着到处跑不觉得太累合上盖子就可以带走,打开盖子就能用,不用关机杜绝玩游戏(但是阻止不了玩LOL)看题主像是个前端妹子,p比较合适,而且可能也是我列举的那三个里面比较便宜的了。

问题四:程序员用什么样的笔记本电脑比较合适 1.如果预算足够,建议用DELL的品牌机,用380MT、780MT、980MT,都是三年的,质量和稳定性都不错。

美工的就用HP或者DELL的工作站级别的。CPU一般是至强的,Quadro的显卡。AMD的行业软件(adobe,autodesk等)支持一般,就别考虑了。

2.如果要性价比,组装机可以考虑i3和i5级别的,内存4GB是起码的,DDR3现在2GB才1300一条,直接用三星金条吧,稳定性和兼容性不错,主板用技嘉的UD3系列的。最关键的是插排用贝尔金的守护者系列,防电涌是关键!!!想不到吧?其实电脑坏90%是因为电涌和静电(一般都是主板坏掉,当然你用杂牌配件我什么都不说了)。程序员的配置如果有钱就上DELL U2311双显示器,如果预算不够就先上一台,显卡用i3的集显就足够了;美工的区别就是显示器一定要用广色域的,DELL-U2410这种级别的,有钱的话上DELL-U3011或者+苹果液晶,显卡用丽台的Quadro FX系列就好了,专业显卡搭配专业显示器很顺畅的,要注意安装厂商的专用驱动和行业软件商的加速驱动;装好了都是自动识别自动配置色彩模式。预算不够就先用CRT显示器凑合吧。

其实最关键还是整体架构的设计要符合你们的具体情况,做到按需配置。比如搞一台塔式的,内存12GB以上的做虚拟机,在虚拟机上装2008R2,大家远程登录做开发调试更方便。客户端用win7+xp mode做开发和测试。我以前给软件公司做过一个虚拟机,他们装了很多XP和win7客户机系统,写了测试脚本专门跑IE和其他浏览器的兼容性和做其他软件测试。美工就是单一台用来做3D渲染和动画制作(windows机器做动画渲染非常考验耐心的)。还有一台美工高配机器也是2008R2系统,开远程桌面,普通工作在普通美工电脑完成,复杂和工作量大的可以交给苹果和高配机器跑。瘦客户端结合虚拟化技术和VDI能够充分利用高配机器的性能,还给公司省了不少钱。毕竟要求高配置的工作比例不是很高的。

祝购物愉快,生活开心!

问题五:程序员的电脑需要什么样的配置? 不需要很高,一般的配置就可以

问题六:程序员一般用什么配置的电脑好?? CPU: I5 4590散片 1100 内存:芝奇4G 1600宽条 140 不够就再加一条 280 硬盘:ST 1T 64M 7200 300 散热:随意cpu自带的也行 主板:微星B85M-P33 V3 330 显卡:映众GTX750 1G 战神 620 电源:台达VX300 180 机箱:动力火车绝尘侠X1 120

问题七:程序员应该买什么样的笔记本电脑 程序员吗?买什么样的电脑?这确实是个问题,不过你也要看你自己需要什么,你觉得你需要什么呢,你需要什么样的电脑呢,我想想奥,我觉得你应该买台HP的,不,我还是觉得你应该买台IBM的,我左想右想呢,我觉得你还是应该买台式好,够用,不,哦,你是程序员哦,那不就是高级职业IT人士嘛,哦,你应该买IBM呢,你看多客气,是不,不,太贵的,你还是买台式好了,不,台式太了,陪你高级职业IT人士不好,我看你呢还是买笔记本好,不,笔记本质量不好,我看你还是不太合适,文哥啊。我右想左想,你还是不要买了,呵呵。。。想玩下就来我这里哦。。。。

问题八:程序员开发用什么电脑比较好 苹果。

问题九:程序员用什么笔记本比较合适? Acer V5-5G-53QR

CPU系列:英特尔 酷睿i5 6代系列

CPU型号:In 酷睿i5 6300HQ

CPU主频:2.3GHz

睿频:3200MHz

总线规格:DMI 8 GT/s

缓存:6MB

核心架构:Skylake

核心/线程数:四核心/四线程

制程工艺:14nm

指令集:AVX2,64bit

功耗:45W

内存容量:4GB(4GB×1)

硬盘容量:500GB

光驱类型:无内置光驱

屏幕尺寸:15.6英寸

显示比例:16:9

屏幕分辨率:1920x1080

显卡芯片:NVIDIA GeForce GTX950M

显存容量:2GBCtrl+1 快速修复(最经典的快捷键,就不用多说了) Ctrl+D: 删除当前行 Ctrl+Alt+ 当前行到下一行(增加) Ctrl+Alt+ 当前行到上一行(增加) Alt+ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了) Alt+

显存类型:DDR3

显存位宽:128bit

流处理器数量:640

DirectX:12

问题十:适合程序员的电脑配置? 一、配置:

CPU I5 4130散 620

主板 华擎B85大板 450

散热 超频3红海mini 30

显卡 技嘉 GV-N660OC-2GD 1200

内存 威刚4G 220

硬盘 希捷7200转64M 1TB 350

机箱 自选 70

电源 安钛克BP430

二、电脑硬件点评:

CPU I5 4130,可以支持程序员的各种程序编写软件,所有配件全部上的一线牌子,质量保证!

预留800自配显示器

这个配置的话,降低了CPU,提升了显卡,力求在程序编辑的时候,可以更好地查看编辑后的小效果,这款配置适应在编程工作做的任何一种软件,以及在设计中的中端要求,如photo,AutoCAD,coredraw等软件的设计处理。

现实中程序员是怎样飞快敲代码的?

现实中程序员大多是结合快捷键敲代码的,因为长时间的锻炼,程序员敲代码的速度越来越快。从慢到快,每个程序员都付出了很多。

首先介绍的就是我觉得应该熟悉 Mac 内置的一些软件及配置。

trackpad 配置

2. 开启单词选词查询:选中某个中英文单词后,三指 tab 会弹出词典释义。这个在石头哥之前的文章中也有介绍。

3. Scroll 方向: 这个自己用习惯了就好。由于我刚开始从 Win 转向 Mac 的时候习惯用 Win 的那种方式,于是就没有开启 Scroll direction: natural,然后也一直沿用至今。

4. 其他手势:有必要熟悉一下,比如知道在 Win 环境下用 win+d

资深码农一枚,身边的经验告诉我,只要不停的ctrl+c 然后 ctrl+v就能打得很快。(滑稽狗头)

言归正传,粘贴确实是很多代码量的来源,但是也确实很多程序员能够很快速的自己敲完代码,那是怎么做到的呢?

让老白来分享下我平时是如何飞快的敲键盘的吧

一直以来,我个人倾向于写代码只是体力活的观点,但是写代码前的思考和设计确实程序员价值的体现。一般来说,我在开始写代码前会搞清楚需求是什么,细抠到每个关键点。比方说要做一个促销打折的功能,那么就要考虑清楚是哪种促销,是一个产品的单独促销还是多个产品的绑定促销,是不是所有产品都可以促销,降价的方式是直接降多少钱还是降百分比,用户打算如何使用这个功能等等。一旦将这些信息搞清楚了之后,就可以开始设计功能了。这里的设计不是闭着眼睛空想或者直接照抄别人的,而是要根据自己产品的产品模型,已有的框架来进行思考,寻找出一条灵活的而且相对改动不会特别大的方案。在这个过程中就会涉及到我们课本中学到的类图流程图等等。一旦有了这些信息,我们就可以很清晰的知道我们需要在哪些地方做哪些改动,大致的工作量是多少。然后,我们就可以开始干体力活了,也就是敲代码。一般来说对于自己常用的语言以及代码库都是有一定的熟练程度,而且也知道了自己所需要的改动,因此具体写起来的时候,基本只需要照着之前设计好的设计图写就行了。如果功能不是很复杂,很困难整个设计思路都已经在脑中,大家就能看到电视剧或者电影中那种飞快的敲击画面了。

当然了,老白也是从小白成长过来的,最开始的时候也是一路copy/paste,但是即使是copy/paste也希望大家可以知道为什么人家是这样写的,这样能够帮助自己更好的成长。

资深码农一枚,身边的经验告诉我,只要不停的ctrl+c 然后 ctrl+v就能打得很快。(滑稽狗头)言归正传,粘贴确实是很多代码量的来源,但是也确实很多程序员能够很快速的自己敲完代码,那是怎么做到的呢?让老白来分享下我平时是如何飞快的敲键盘的吧一直以来,我个人倾向于写代码只是体力活的观点,但是写代码前的思考和设计确实程序员价值的体现。一般来说,我在开始写代码前会搞清楚需求是什么,细抠到每个关键点。比方说要做一个促销打折的功能,那么就要考虑清楚是哪种促销,是一个产品的单独促销还是多个产品的绑定促销,是不是所有产品都可以促销,降价的方式是直接降多少钱还是降百分比,用户打算如何使用这个功能等等。一旦将这些信息搞清楚了之后,就可以开始设计功能了。这里的设计不是闭着眼睛空想或者直接照抄别人的,而是要根据自己产品的产品模型,已有的框架来进行思考,寻找出一条灵活的而且相对改动不会特别大的方案。在这个过程中就会涉及到我们课本中学到的类图流程图等等。一旦有了这些信息,我们就可以很清晰的知道我们需要在哪些地方做哪些改动,大致的工作量是多少。然后,我们就可以开始干体力活了,也就是敲代码。一般来说对于自己常用的语言以及代码库都是有一定的熟练程度,而且也知道了自己所需要的改动,因此具体写起来的时候,基本只需要照着之前设计好的设计图写就行了。如果功能不是很复杂,很困难整个设计思路都已经在脑中,大家就能看到电视剧或者电影中那种飞快的敲击画面了。当然了,老白也是从小白成长过来的,最开始的时候也是一路copy/paste,但是即使是copy/paste也希望大家可以知道为什么人家是这样写的,这样能够帮助自己更好的成长。

速度对写代码的那个程序员很重要。

在公司工作,有项目和开发检查每个程序员的进度。生产力太低会给产生不良印象。

我承认这个“生产力”只是印象而已,和项目的实际进度关系不大。但事实就是大多数人就吃这套,在按时完成工作的前提下表演一些输入代码的魔术,会获得的另眼相看。

例如上级要求和我一起在周末加班完成一个小功能或修掉一个bug。提前一点点时间完成工作,让也可以比预期早一点回家,就会对我有好感。或者至少通过秀键盘作,表现得很高效工作的样子。无非就是在正确的时间和地点建立个人正面形像而已。

现在让我正面回答这个问题,高级程序员充分利用了编辑器和IDE中的先进功能,也可以自由组合运用第三方的命令行工具。必要的话可以自己写一些工具。

这个过程也是动态的,编辑器/IDE/命令行工具都在不断的进步中。例如VSCode在2017年使用rust写的ripgrep作为自己的查找替换工具的后端引擎,可以把速度提高40到60倍。

高级程序员可以使用编辑器和IDE的自动完成功能,避免手动输入代码的错误。除了inlisense之外,还有很多其他自动完成功能可以同时启用。比如自动完成行,自动完成文件路径,搜索所有4:个人提高漏洞挖掘能力的方法打开的文件自动完成词等等。某些程序员不用这些功能并不等于它们不存在或者不重要。

自动完成某个特定的子功能如自动完成行,也有很多文章可做。比如可以搜索整个项目的代码来自动完成行。可以完成单行也可以完成多行。搜索匹配行如果可能的话用速度更快的git grep或者ripgrep来做。 匹配关键字的提取也需要智能的算法。可以参考我写的Emacs 插件 redguardtoo/eacl

如果你在一个项目中的代码的commit实现了一个不错的特性,同事在另一个项目中也希望使用。或者你的commit可能有bug,希望在另一个沙盒环境里重现。那么可以用命令行程序patch来把commit重新apply到新环境。注意有的项目不用git(我碰到过公司使用perforce的),或者沙盒环境根本没有版本控制(例如某个bug只在production才能重现,老板了供你调试,但禁止在其上安装新软件)。所以只有patch可用,否则只有手动对比输入代码。

现代的编程环境都集成了可拓展的编译器或者语法解析器供你使用。VSCode的typescript ( . 比如在jascript项目中给某个模块中的所有函数加上打印函数名和函数参数的代码,可以写babel plugin来实现(10行代码而已)。

以上这些技巧都是举例说明。只是沧海一而已。如何提高编程速度 获得更多这方面的知识

题外}int nTheDate;else话:

很多人可能对好莱坞电影描写的黑客程序员有所误解。肯定有一些艺术夸张,但是好莱坞的导演未必不了解程序员是怎么工作的。只不过他们接触更多的是Unix 程序员。

我以前在柯达娱乐影像部门工作,就是为好莱坞开发视频非线性处理软件。由于历史原因,这些软件跑在Unix工作站上(后来慢慢迁移到Linux)。软件的用户需要自己写脚本来处理视频。导演就是拿视频处理的电脑拍了几个镜头而已。

“没有调查就没有发言权”,你不知道好莱坞导演最早接触的都是Linux/Unix用户,所以你以为他们描写的那种程序员根本就不存在。

好像没几个人回答问题,都说的是不用飞快的敲代码。我可以分享一下我的经验。

隔出时间可以集中注意力,比如一个小时完全不被打扰的那种

换一个好一点的键盘,上一代mbp键距太短我敲的手疼,新的mbp一出来我就换了。外置键盘我都是微软的ergo键盘

选个vim或者emacs,减少手指移动的距离,这样单位时间里面能做的改动会增加。我vscode里面也会用vim

还嫌慢的话可以弄个没字的键盘,然后改键改成colemak或者其它的你顺手的,我自己没试过但是有同事改了。好处是密度在第二行非常高,手指移动距离变短了。坏处是同事来帮你debug的时候会拿刀砍你。

敲15000行的代码,都是一行敲出来的,必须每天写代码,不能小看书中的例子,书中的例子必须一个一个敲出来的敲多有感觉了,做项目都是有小项目搭积木搭乘的,是每天写点代码

现实中,程序员如果需要用手敲代码,一定是用十根手指协调动作敲击键盘来输入代码的。

因为经过专业训练,而且每天都敲键盘,所以程序员的手速是非常快的,敲代码的速度是非常快的,令人眼花缭乱。

但是,程序员编写的成语代码可不一定是他一下一下敲键盘敲进去,而是另有高招……

比如,某些功能的代码是现成的,程序员可以直接粘贴,就不用手工敲代码了。

比如,某些编程软件功能强大,可以自动生成代码,这时候程序员同样无需手工敲代码,只要按照需求进行相关设置,就可以获得需要的结果了。

现在的编程环境对于程序员来说,已经极大改善。那种每一个代码都需要人工敲击的时代早已经一去不复返……所以现在程序员编程时,从作角度来说,已经轻松多了……

aqui te amo。

敲代码很快有几个条件:

1.对项目代码和结构非常熟悉,知道整个数据流的在代码中的流动过程和变化过程。知道当前新增的代码在整个项目处于哪个位置,对于数据会有产生什么新的变化。这些要心理有数。也就是从架构层面去思考代码的编写。

2.对于需求理解的很透。这样业务逻辑转成代码逻辑就不会有任何不清楚的地方。

3.已经解决了技术难点,也就是说前期测试性代码已经写过了弄清楚了,避免了突然出现的技术性难点

。4.新增的代码和新增的数据结构已经仔细思考过了,并设计好。也清楚引入这些新的代码和数据结构对现有代码的整体影响。

5.异常点的位置的处理方案已经安排好了。写代码一部分是正常业务流程,算法过程,但是另外一大块就是处理各种异常。当异常出现之后,是代码重试,报错后忽略,还是报错之后停止代码,还是报错后清理代码并重新恢复上一个状态,等等。这些都是要心理有数。

6.对于如何新增源代码文件,命名函数,命名文件名,命名类名,命名变量名有一整套方案。有时候想个函数名或者变量名都要卡好几分钟,就不算飞快了。别笑,想个变量名,百度十来分钟的时候多了去了。

7.外部环境已经准备好了。IDE稳定,数据库结构稳定,数据稳定,网络稳定,访问网页顺畅,准备好免打扰的牌子。准备好刷卡提需求的二维码,准备好板砖和大刀,预防产品提需求和改需求。

我是怎么踩过在 OSX 上录屏的坑的

问题一:求适合程序员用的笔记本电脑 你问的很有条理性,而且要求很细,所以我先用一二三来回答你,让你有个大概的印象选什么样的笔记本。

昨天开始在研究 OSX 上的屏幕录制并且实时获取视频流或图像帧的实现。遇到了非常大的阻力,各种问题,昨晚纠结了一整晚,终于在小萌的启发下慢慢找到了解决办法,把谷歌和 stackoverflow 都翻了个底朝天,的解决有点意外,中间还是有一些细节需要求证,然而除了 Apple Doc 已经没有任何参考文献了,而有些机制 Apple Doc 中都不会涉及。所以此刻迫不及待的想要写一篇博客,来纪念万里长征的步。

3、内存要大,CPU要快,硬盘要SSD。开一堆网页,开IDE都是很占资源的。编译的速度影响工作效率与心情。

要实现录屏,有两种途径,一种是通过 Core Graphic , 一种是通过AVFoundation 。 Core Graphic 的话,你可以找到苹果的一份 SampleCode,如果使用了

CGImageRef screenShot = CGWindowListCreateImage(CGRectMake(0.0f, 0.0f, [self screenRect].size.width, [self screenRect].size.height), kCGWindowListOptionOnScreenOnly, kCGNullWindowID, kCGWindowImageDefault |kCGWindowImageNominalResolution);

它的优点在于你可以根据 WindowID 来获取 指定窗口 的图像,并且可以通过ListOption 来设定各种包括桌面图标,去除桌面图标,去除桌面,这些七七八八的设置,所以微信 Mac 端的截屏功能应该就是使用了上面这行代码。 所以我们也可以设置一个 NSTimer, 来按照六十分之一秒一帧的速度来获取截图,并且形成一个流。 实践表明性能还不错,对于录屏这种事情烧一烧 CPU 是常有的事情,毕竟你需要按帧来计算像素,而且对于 Mac 而言,CPU 并不是什么特别大的问题 =。= 因此这种办法是可行的 ,然而我觉得不够优雅。

同样,Core Graphic 中还有一种实现办法: CGDisplayCreateImage :

CGImageRef Ref = CGDisplayCreateImage(display);

//NSData data = (NSData )CFBridgingRelease(CGDataProviderCopyData(CGImageGetDataProvider(Ref)));

screenImg = [[NSImage alloc] initWithCGImage:Ref size:CGDisplayScreenSize(display)];

//screenImg = [image mutableCopy];

CGImageRelease(Ref);

CGDisplayRelease (display);

这种实现的机制和上述的是一致的,实现出来的效果和性能也都不错,但是同样的还是觉得不够优雅。

所以此刻就要转向 AVFoundation 了。在 AVFoundation 中,有一个 input 类叫做 AVCaptureScreenInput 这个 input 直接可以获得到当前屏幕的视频输入。这时候我想起两年前我做过视频人脸的 sdk,简单地说就是通过 AVDevCapture来获取相机的 input 然后打开一个 AVSession , 然后再将 input 里面的 buffer 读出来,对每一帧进行人脸检测的运算。然后我按照苹果的一个录屏的例子和一个 Github 上存在不多的这方面的仓库实现了简单的录屏,使用了AVCaptureMovieFileOutput 作为 output。到这里的时候,一切都很顺利,输出到 mov 文件的录屏都是正常的。然后我开始了从缓冲区读取 buffer 的工作,简单来说,从缓冲区读帧是根据 AVCaptureFileOutputDelegate 里面的一个回调

- (void)captureOutput:(AVCaptureFileOutput )captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection )connection;

来实现的。这里的 CMSampleBuffers 是一个 Core Foundation 的对象,它包含了零个或多个压缩或未压缩过的特定媒体类型的抽样,通常被用来传递媒体数据。一个 CMSampleBuffers 可以包含:

CMBlockBuffer , 可能包含一个或多个的 sample (话说 sample 可以翻译为帧么?还是取样的意思……)

CVImageBuffer 包含了 buffer 层级的附件和 sample 层级的附件,还包括了包含的所有 sample 的格式,大小和时间信息

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

uint8_t baseAddress = (uint8_t )CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0); // Get rmation of the image

size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);

size_t width = CVPixelBufferGetWidth(imageBuffer);

size_t height = CVPixelBufferGetHeight(imageBuffer);

CGColorSpaceRef colorSpace = CGColorSpaceCreateDevRGB();

CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);

CGImageRef newImage = CGBitmapContextCreateImage(newContext);

CGContextRelease(newContext);

CGColorSpaceRelease(colorSpace);

CVPixelBufferUnlockBaseAddress(imageBuffer,0);

然而这个时候出了个小岔子,这里获取的 CMSampleBuffers 里面包的是CMBlo其实 Core Media 那层有很多知识点,但是苦于文档太少,研究的人也太少,因此实在是举步维艰,感兴趣的朋友可以参考一下 苹果的 Reference 看下这块的内容。ckBuffer !于是我开始查各种 stackoverflow, 无解, 一开始以为是视频格式的问题,需要按照 H264 的编码来解析,但是怎么可能呢…… 百思不得其解,即使我将 CMBlockBuffer 里面的 Data 读取了出来,也无法转换成 NSImage , 说明这个 Data 不是正常的 data。 那么有没有可能一帧被拆成多个 samples 来传输了呢…… 有可能,然而我尝试了仍然无果。

这时候我回头看看,发现我这里并没有将视频导出到文件的需求,有没有其他 output 来替代。偏巧我在 stackoverflow 上看到了 这个问题 ,于是就用AVCaptureVideoDataOutput 来尝试。尝试之前我已经有强烈预感了 - - 毕竟上一个 output 是直接输出到文件,而这个 output 明显是直接输出成 data。于是你只要这样给一个 output 就可以恢复正常了:

self.output = [[AVCaptureVideoDataOutput alloc] init];

[((AVCaptureVideoDataOutput )self.output) setVideoSettings:[NSDictionary dictionaryWithObjectsAndKeys:@(kCVPixelFormatType_32BGRA),kCVPixelBufferPixelFormatTypeKey, nil]];

dispatch_queue_t queue = dispatch_queue_create("com.sergio.chan", 0);

[(AVCaptureVideoDataOutput )self.output setSampleBufferDelegate:self queue:queue];

这时候的 sampleBuffer 已经可以正常按帧解析出来了,这里有两个问题,一个是在上面那段代码获取到一个 CGImageRef 的 newImage 对象后需要每一次都对 newImage 进行一次release,否则内存溢出就要爆炸了,一个是线程安全问题,在上面的代码里可以看出这个新的AVCaptureVideoDataOutputSampleBufferDelegate 其实是在一个的线程上接收回调的,因此如果你要在这个 delegate 中进行 UI 作的话,记得回到主线程作 =。=

@try {

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

uint8_t baseAddress = (uint8_t )CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0); // Get rmation of the image

size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);

size_t width = CVPixelBufferGetWidth(imageBuffer);

size_t height = CVPixelBufferGetHeight(imageBuffer);

CGColorSpaceRef colorSpace = CGColorSpaceCreateDevRGB();

CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);

CGImageRef newImage = CGBitmapContextCreateImage(newContext);

CGContextRelease(newContext);

CGColorSpaceRelease(colorSpace);

CVPixelBufferUnlockBaseAddress(imageBuffer,0);

NSImage image = [[NSImage alloc] initWithCGImage:newImage size:[self screenRect].size];

CGImageRelease(newImage);

dispatch_async(dispatch_get_main_queue(), ^{

self.imageView.image = image;

}});

}@catch (NSException exception) {

NSLog(@"Error at %@",exception.debugDescription);

}@finally {

return;

}PS. Cocoa 中获取 ScreenRect 的方法如下:

- (NSRect)screenRect

{NSRect screenRect;

NSArray screenArray = [NSScreen screens];

NSScreen screen = [screenArray objectAtIndex: 0];

screenRect = [screen frame];//[screen visibleFrame];

return screenRect;

}这里后来又遇到一个小坑。如果使用的是 visibleFrame, 那么如果你的窗口处于全屏模式,获取 visibleFrame 的时候其实会把上面状态栏的那部分区域给省略了,因为计算 visibleFrame 的时候估计不考虑状态栏是否隐藏吧,所以这里用 frame 更好。

这里从 delegate 中获取到每一帧的数据之后就可以对每一帧进行压缩,并且以 Data 的形式进行传输了。点忘记介绍一下 AVCaptureScreenInput 的一些特性了:

self.input.capturesMouseClicks = YES;

self.input.minFrameDuration = CMTimeMake(1, 60);

self.input.scaleFactor = 0.5f;

self.input.cropRect = [self screenRect];

首先 AVCaptureScreenInput 可以记录下鼠标移动的轨迹,还可以记录鼠标的点击(自行体验),第二个属性设置的是帧率,也就是60帧一秒。第三个和第四个属性顾名思义分别是缩放的比例和输出的裁剪区域,设置这两个属性可以减少每一帧的大小,也就是说在输入的时候就已经限制过大小了,然后你再可以进行一些压缩什么的。其实 AVCaptureScreenInput 还有一个关键的属性,但是现在已经被废弃了,因为苹果已经把这个属性内置成系统默认了:joy: 重复帧会被自动取消,这在以前的版本是可以通过一个属性设置的,现在已经被默认采用了。

多余的说几点:

其实可能有些人知道在 AVFoundation 下面, Core Media 之上还有一层叫做Video ToolBox ,这在2012年那会儿都是只有的设备才能调用到的 Private API,但是2014年的 WWDC 苹果将这一层开放出来了,因此你可以在AVFoundation 更深入的层次去做视频编码解码和流处理,这块的知识我这次只看了个大概,留下了一些资料出处: Github WWDC

,最重要的是!代码已经整理成开源库放在 Github 上了!

漏洞可以随便挖吗

总价格3150,预留800的显示器价格

今天测试时发现一个任意用户登录漏洞,简单记录一下(em...写得真的很简单的那种!)

登录成功后的一个请求,里面包含了当前登录用户的用户名和user_id:

后面紧接着一个包含if(self.imageView) {敏感信息的数据包,如下:

可以看到返回信息中包含了当前用户的密码MD5,且可以正常解密。更换为其他的user_id:

可以看到,返回了其他user_id的密码,但是,正常情况下,只有在成功登录一个用户后才能获取用户的user_id,所以要想登录他人账户,必须要知道user_id值对应的用户名.....,既然系统会有一个返回密码的数据包,那就可能有其他的敏感信息返回数据包,于是打开burp的hsitory,底部搜索user_id,终于在茫茫数据包中发现了一个接口:

一个请求,通过登录用户名,返回信息包含了该用户名对应的user_id:

通过id获取密码:

不断遍历用户名可以获得更多的user_id,也就可以通过上面的请求获取更多的用户密码MD5,通过解密后的用户名密码即可登录任意用户:

漏洞挖掘类型总结

如果你刚刚好是一个刚刚学完基础的小白,如果你刚刚好没有参加各种培训,完全自学。

那么你的漏洞清单可能是这样的。

js文件可能存在的未授权访问

3: 漏洞类型详解

正式开始前插一条,我之前对漏洞的定义有一点点误解,以为只有上面列表上的才是漏洞,其实不然,只要可以给厂商带来损失的全都是漏洞。逻辑漏洞也是基于这条。回顾一下自己的挖掘过程,其实漏掉了很多。

逻辑漏洞

逻辑漏洞也是一个经久不衰的话题,不过逻辑漏洞并不像前面几种漏洞,可以用扫描器去扫,逻辑漏洞目前,据我所知是没有一个扫描器可以敢说自己能扫到逻辑漏洞的。或许有的厂家敢说自己没有一个sql注入,但是没人敢说自己没有逻辑漏洞(我想也没有厂家敢说自己没有sql注入吧,哈哈哈)。而且,由于现在waf,和防火墙的逐渐完善,sql注入,上传等漏洞,也越来越难以查找和利用,而逻辑漏洞则不存在这种问题。

信息泄露

信息泄露漏洞顾名思义就是信息泄露,信息泄露也分好多种,如。

组合漏洞

组合漏洞是一个可以吧低危漏洞变成高危漏洞的一个神奇的东西。比如你找到一个xss漏洞和一个csrf漏洞,如果两个漏洞单独提交,或许是两个低危,或许是两个忽略。但是如果你把你的xss和csrf组合起来就有可能变成一个高危漏洞,打组合拳,key师傅组合拳打的很厉害,向师傅看齐,key师傅给我说,挖到低危不要着急提交,存起来,万一某一天碰见一另一个漏洞,组合一下,就可以一发入魂了。

这一节讲一下挖掘漏洞应该如何提高和应该有哪些好的习惯。

细心放在位,是因为细心真的是非常非常非常重要,我有幸请教过很多大佬成功的秘籍,他们告诉我的个词语就是细心,正所谓心细则挖天下。很多漏洞都是需要细心才可以发现,不放过数据包中的任何一个参数,不放过网站的任意一个点,我曾问过团队的小石师傅,如何挖掘那些很多人都挖过的src,这么多人都挖过,一些功能点我还要在测一遍吗。小石师傅并没有给我直接回答,而是讲了他一个漏洞的挖掘经历,那是挖美团的时候,小石师傅直接主站开始挖,并且在一个很明显的地方,挖到了一个储存xss的高危漏洞。所以,在我们进行漏洞挖掘的时候,不要放弃任何一个可能存在漏洞的地方,每个人都有不同的挖掘方式,网站这么大,总会有几个漏测的地方,并且一个漏洞修复了,谁敢保证,修复完了,就不能再修一个漏洞出来了呢。

耐心

耐心同细心一样,可以说是一对cp。如果你本身就足够信心,那么我想你的耐心也不会。如果说细心是你漏洞挖掘的利剑,那么耐心就是你的磨刀石,很多时候,碰到一个破站盯几天才能挖到一个漏洞,你坚持下来了就是胜利者,有人说挖洞,也是个运气活,运气好了随随便便就是几个高危,运气不好,几天也挖不到一个。虽然有一定的道理,但是当你的能力足够强,有了自己的套路,想挖漏洞还是轻松加愉快。

会看、会记

会看,会记。这个就简单了,就是要多看多记,多看漏洞详情,多看技术文章,漏洞详情可以在乌云看,还有网上很多人分享的案例,主要是乌云。看完就要记,要让你看的东西真正的成为你的东西,如果你面对一个厂商,还是有无从下手的感觉,就去乌云看漏洞详情,一个一个看,然后把漏洞出现的位置,以及使用的一些技巧记下来,成为属于自己的漏洞挖掘手册,这也是我最近在做的一个事情。还有一些好的文章,好的技巧,或许你一时半会也用不到,但是你要学会记,总有用到的一天。

懂收集

key师傅说过,漏洞挖掘说白了就是一个fuzz的过程,而fuzz最关键的是什么,就是一本高效的字典,没错我们要学会收集字典,想公开的字典有fuzzdb,是一个非常好的fuzz字典合集,当然我们在收集他人字典的同时我们也要自己收集字典,曾经看到一个大佬,搜集了github大量的开发项目的路径,然后组成字典。我也不要求小白可以写程序然后自动收集字典,但是,我们在平时的漏洞挖掘过程中,遇到的一些东西还是要多多的去收集一下,逐步慢慢的形成自己的一本专用字典,可以提高你的漏洞挖掘效率。当你有一本自己收集的字典时,相信你也成为一名大佬了。

勤动手

当你看了大量漏洞,记了大量笔记,这个时候,我相信你最需要的,就是实战,实战是可以把所学所看融会贯通的最快方法,没有之一,只有实战可以锻炼自己的挖洞能力,和1. 启用 Tap to click:在 System Preferences -> Trackpad 中启用, 用 tap 替换 click 的作,明明轻轻 tap 就可以完成的, 为何还要用力点击才 OK。现在偶尔用其他人电脑非得用力 click 就太纠结了。同时,还有 "右键"功能,Secondary click,用两个手指 tap 弹出右键菜单。效率。看到新的漏洞多去搭建环境复现,这也是对能力的一种提升。

C#,阴历转换成阳历

,1179,26以下是PC的设计首先启动器,现在的有正版启动器和忘却的旋律。(设置皮肤,插件,设置等等等等)然后主程序,好像mc没有游戏引擎吧,我不清楚,先构造好GUI,设计物品子类,父类,给他们一定的代码代替,然后是随机地图,像这个就复杂了,你可以看看mojang早期作品,地图生成从代码角度就复杂了,你还要设置seed,游戏的话其实这些搞好了,就是拼接问题了。我以前用vb做了个2D的mc我可以把源码给你看看7415,2635,661067,1701,1748,398772,2742,23,330031

//天干

private static string[] TianGan = { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" };

//地支

private static string[] DiZhi = { "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" };

//十二生肖

private static string[] ShengXiao = { "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" };

//农历日期

private static string[] DayName = {"","初一","初二","初三","初四","初五",

"十一","十二","十三","十四","十五",

"十六","十七","十八","十九","二十",

"廿一","廿二","廿三","廿四","廿五",

"廿六","廿七","廿八","廿九","三十"};

//农历月份

private static string[] MonthName = { "", "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "腊" };

//公历月计数天

private static int[] MonthAdd = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };

//农历数据

private static int[] LunarData = {2635,333387,1701,1748,267701,694,23,133423,1175,396438

,3402,3749,331177,1453,694,201326,2350,465197,3221,3402

,400202,2901,1386,267611,605,2349,137515,2709,464533,1738

,2901,330421,1242,2651,199255,1323,529706,3733,1706,398762

,2741,1206,267438,2647,1318,204070,3477,461653,1386,2413

,330077,1197,2637,268877,3365,531109,2900,2922,398042,2395

,1175,1611,200010,3749,527717,1452,2742,332397,2350,3222

,268949,3402,3493,133973,1386,464219,605,2349,334123,2709

,2890,267946,2773,592565,1210,2651,395863,1323,2707,265877};

///

/// 获取对应日期的农历

///

///

公历日期

///

public string GetLunarCalendar(DateTime dtDay)

{string sYear = dtDay.Year.ToString();

string sMonth = dtDay.Month.ToString();

string sDay = dtDay.Day.ToString();

int year;

int month;

int day;

try

{year = int.Parse(sYear);

month = int.Parse(sMonth);

day = int.Parse(sDay);

}catch

{year = DateTime.Now.Year;

month = DateTime.Now.Month;

day = DateTime.Now.Day;

int nIsEnd;

int k, m, n, nBit, i;

string calendar = string.Empty;

//计算到初始时间1921年2月8日的天数:1921-2-8(正月初一)

nTheDate = (year - 1921) 365 + (year - 1921) / 4 + day + MonthAdd[month - 1] - 38;

if ((year % 4 == 0) && (month > 2))

nTheDate += 1;

//计算天干,地支,月,日

nIsEnd = 0;

m = 0;

k = 0;

n = 0;

while (nIsEnd != 1)

{if (LunarData[m] < 4095)

k = 11;

k = 12;

n = k;

while (n >= 0)

{//获取LunarData[m]的第n个二进制位的值

nBit = LunarData[m];

for (i = 1; i < n + 1; i++)

nBit = nBit / 2;

nBit = nBit % 2;

if (nTheDate <= (29 + nBit))

{nIsEnd = 1;

break;

}nTheDate = nTheDate - 29 - nBit;

n 为了便于讨论,做如下设:= n - 1;

}if (nIsEnd == 1)

break;

m = m + 1;

}year = 1921 + m;

month = k - n + 1;

day = nTheDate;

//return year + "-" + month + "-" + day;

if (k == 12)

{if (month == LunarData[m] / 65536 + 1)

month = 1 - month;

else if (month > LunarData[m] / 65536 + 1)

month = month - 1;

}//年

calendar = year + "年";

//生肖

// //天干

calendar += TianGan[(year - 4) % 60 % 10].ToString();

// //地支

calendar += DiZhi[(year - 4) % 60 % 12].ToString() + " ";

if (month < 1)

calendar += "闰" + MonthName[-1 month].ToString() + "月";

calendar += MonthName[month].ToString() + "月";

//农历日

calendar += DayName[day].ToString() + "日";

return calendar;

}

从编程的角度来看,Minecraft 是怎么样设计的

CVPixelBufferLockBaseAddress(imageBuffer,0); // Lock the image buffer

日照香炉生紫烟,遥看瀑布挂前川。

开浏览器、开IDE,再多也不担心内存不足

Ja从入门到入土

//农历月

TCP和UPD详解

UDP 首部格式

首部字段只有 8 个字节,包括源端口、目的端口、长度、检验和。12 字节的伪首部是为了计算检验和临时添加的。

TCP 首部格式

序号 :用于对字节流进行编号,例如序号为 301,表示个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。

确认号 :期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此 B 期望下一个报文段的序号为 701,B 发送给 A 的确认报文段中确认号就为 701。

数据偏移 :指的是数据部分距离报文段起始处的偏移量,实际上指的是首部的长度。

确认 ACK :当 ACK=1 时确认号字段有效,否则"初六","初七","初八","初九","初十",无效。TCP 规定, 在连接建立后所有传送的报文段都必须把 ACK 置 1。

同步 为自己的项目写代码。一个简单功能要花太多时间的话,你就缺少动力完成产品原型而中途放弃。也许成为下一个马云的机会就这么错失了。SYN :在连接建立时用来同步序号。 当 SYN=1,ACK=0 时表示这是一个连接请求报文段 。若对方同意建立连接,则响应报文中 SYN=1,ACK=1。

终止 FIN :用来释放一个连接,当 FIN=1 时,表示此报文段的发送方的数据已发送完毕,并要求释放连接。

窗口 :窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。

设 A 为客户端,B 为端。

三次握手的原因

第三次握手是为了 防止失效的连接请求到达,按照 Apple Doc, 一个 CMSampleBuffers 就是这两种 buffer 之一的一个 wrapper, 因此每一个 CMSampleBuffers 只会包含其中之一。你需要用不同的方法来取出里面的数据。所以我就很正常的按照最正常的写法来取 buffer 了:让错误打开连接 。

客户端发送的连接请求如果在网络中滞留,那么就会隔很长一段时间才能收到端发回的连接确认。客户端等待一个超时重传时间之后,就会重新请求连接。但是这个滞留的连接请求还是会到达,==如果不进行三次握手,那么就会打开两个连接==。如果有第三次握手,客户端会忽略之后发送的对滞留连接请求的连接确认,不进行第三次握手,因此就不会再次打开连接。

以下描述不讨论序号和确认号,因为序号和确认号的规则比较简单。并且不讨论 ACK,因为 ACK 在连接建立之后都为 1。

四次挥手的原因

客户端发送了 FIN连接释放报文之后,收到了这个报文,就进入了 CLOSE-WAIT 状态。这个状态是 为了让端发送还未传送完毕的数据 ,传送完毕之后,会发送 FIN 连接释放报文。 也就是说为了==防止数据丢失== 。

TIME_WAIT作用

客户端接收到端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:

TCP 使用超时重传来实现可靠传输 :如果一个已经发送的报文段在超时时间内没有收到确认,那么就重传这个报文段。

一个报文段从发送再到接收到确认所经过的时间称为往返时间 RTT,加权平均往返时间 RTTs 计算如下:

其中,0 ≤ a < 1,RTTs 随着 a 的增加更容易受到 RTT 的影响。

超时时间 RTO 应该略大于 RTTs,TCP 使用的超时时间计算如下:

其中 RTTd 为偏的加权平均值。

窗口是缓存的一部分,用来暂时存放字节流。 发送方和接收方各有一个窗口,接收方通过 TCP 报文段中的窗口字段告诉发送方自己的窗口大小,发送方根据这个值和其它信息设置自己的窗口大小 。

发送窗口内的字节都允许被发送,接收窗口内的字节都允许被接收 。如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离,直到左部个字节不是已发送并且已确认的状态;接收窗口的滑动类似,接收窗口左部字节已经发送确认并交付主机,就向右滑动接收窗口。

接收窗口只会对窗口内一个==按序到达==的字节进行确认 ,例如接收窗口已经收到的字节为 {31, 34, 35},其中 {31} 按序到达,而 {34, 35} 就不是,因此只对字节 31 进行确认。发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收。

流量控制是为了控制发送方发送速率,保证接收方来得及接收。

接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小 ,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。

也就是说是 通过滑动窗口实现 的。

如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。 流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度 。

TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复 。

发送方需要维护一个叫做拥塞窗口(cwnd)的状态变量,注意拥塞窗口与发送方窗口的区别: 拥塞窗口只是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口 。

接收方有足够大的接收缓存,因此不会发生流量控制;

虽然 TCP 的窗口基于字节,但是这里设窗口的大小单位为报文段。

发送的最初执行慢开始,令 cwnd = 1,发送方只能发送 1 个报文段;当收到确认后,将 cwnd 加倍,因此之后发送方能够发送的报文段数量为:2、4、8 ...

注意到慢开始每个轮次都将 cwnd 加倍,这样会让 cwnd 增长速度非常快,从而使得发送方发送的速度增长速度过快,网络拥塞的可能性也就更高。设置一个慢开始门限 ssthresh,当 cwnd >= ssthresh 时,进入拥塞避免,每个轮次只将 cwnd 加 1。

如果出现了超时,则令 ssthresh = cwnd / 2,然后重新执行慢开始。

在接收方,要求每次接收到报文段都应该对一个已收到的有序报文段进行确认。例如已经接收到 M1 和 M2,此时收到 M4,应当发送对 M2 的确认。

在发送方, 如果收到三个重复确认,那么可以知道下一个报文段丢失,此时执行快重传 ,立即重传下一个报文段。例如收到三个 M2,则 M3 丢失,立即重传 M3。

在这种情况下,只是丢失个别报文段,而不是网络拥塞。因此执行快恢复,令 ssthresh = cwnd / 2 ,cwnd = ssthresh,注意到此时直接进入拥塞避免。

慢开始和快恢复的快慢指的是 cwnd 的设定值 ,而不是 cwnd 的增长速率。慢开始 cwnd 设定为 1,而快恢复 cwnd 设定为 ssthresh。

参考链接:

计算机网络%20-%20传输层.md