买的二手96010系显卡不支持vga,用的vga加div的转换头,显示屏在玩游戏时有波纹电源也是二手的而且电脑会重启

建议大家不要买DVI转VGA的转接线或者转接头,一买一个坑!【显卡吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:3,092,117贴子:
建议大家不要买DVI转VGA的转接线或者转接头,一买一个坑!收藏
如题,前阵子买了片R9 270显卡,却发现原来家里的19寸显示器只有VGA口,卡上却没有VGA口,用了包装附带的DVI转VGA头,玩游戏有水波纹,在网上看了看建议说转接头不好,容易被干扰,用转接线才好。遂买了根19块的带双磁环的DVI转VGA线,水波纹问题照旧,本来打算退货,放学回来一看,过了7天都不能退了。最后走投无路在某猫上23块又买了根DP转VGA的,接上去玩游戏完美无水波纹,问题总算解决其实这原理也很简单,不过当初我自己笨没有认真去考虑。高端显卡不带VGA口,所以输出的信号低通滤波也做得很差,所以数字信号用转换头转换时肯定会有损失,即使找一根抗干扰多强大的线也是没用的,因为在外界干扰之前信号就已经受损了,然而DP转VGA或者HDMI转VGA是用芯片转换的,芯片是带有低通滤波功能的,所以就能够解决玩游戏水波纹的问题所以如果显示器只有VGA口,显卡没有VGA的话就不要去看那些DVI转VGA的头或者线了,直接买DP转HDMI,不然怎么样都会有水波纹,当然不玩游戏的可以无视了。。。。
我也是 上半年买的270X显卡 发现不带VGA. 于是我就把显示器换了.
不好说,我的280x转接的就没事
转接线当然出的问题多,你要买转接头!白色带10cm左右线的那种
毕竟舍不得跟了我几年了的19寸,再大也不喜欢
【所以数字信号用转换头转换时肯定会有损失】这里是错误的DVI-I转VGA并非 数字信号 转 模拟信号而是DVI-I本身就有模拟信号的信号引脚,用转接头的时候,数字信号部分是不起作用的
加钱换显示器完美解决!
其实我不明白用高端显卡了为什么还用没有hdmini或dp的低端显示器?显示器是对着人的眼睛的,也应该多重视一下吧
哈哈 这也算 精品了 该顶了
Vga的显示器早就该换掉了
貌似确实是啊,玩游戏关闭帧数锁定就会有水波纹,回头我也去把dvi转vga头扔了去,买个dp的
用过dvi转vga的转接头
没发现楼主这样的问题
19寸无法忍受…必须23以上
——来自Nokia 909
我的转接头是买显卡只带,没问题啊
我也是,买什么转接头好?
我也是老显示器 280的显卡
用的显卡送的转接头
也是一玩游戏就有水波纹
请问我该买哪种显卡?
天上白玉京,十二楼五城。仙人抚我顶,结发受长生。
转接头,确实坑,原装转接头插上vga线。无法识别显示器、于是在某宝,买了绿联,dvi转VGA,很好,就是贵点,线粗!棒棒棒!!
为什么我没事?我用绿联的转接头,75刷新率一样玩
楼主我家9800gt玩lol也有水波纹怎么办
不好说 我的680就没事
DVI转HDMI路过 --------------------------------------------windows 7 正在为你服务 》_《
我以前用过一段时间的dvi转vga,一点问题也没有
我刚收到280x时,一上机发现没有转接头,然后买了个来用,玩游戏倒也没注意到有什么波纹,过不久我再换显示器
换显示器不就行了
转接头本来就不靠谱。我自己显示器有DVI所以无需转接hhh
-妹妹的胖次好甜呐&w&
还不如换显示器
机制得把显示器换了
hdmi接口4k显示器路过
登录百度帐号在电子工程世界为您找到如下关于“显存”的新闻
显存资料下载
内存带宽对性能的影响究竟有多大编者按:自从P4推出之后,内存带宽这个词儿就越来越流行了,很多所谓的高手都经常用带宽来说明一些问题,这不仅令到不少初学者一头雾水,就算是很多老鸟们也只是一知半解,并没有真正研究过带宽对性能的影响究竟有多大!很多时候都是人云亦云,或者只是想当然的按照理论去计算,在这篇文章里,将会对内存(显存)带宽对系统性能的具体影响作深入的探讨...
对基于最新一代通用GPU--Geforce8800显存带宽的测试样例,对于通用计算而言,带宽的性能是至关重要的。...
MCU与LCD时序控制的基本方法MCU与LCD时序控制的基本方法一般来说,LCD 模块的控制都是通过 MCU 对 LCD模块的内部寄存器、显存进行操作来最终完成的;在此我们设计了三个基本的时序控制程序,分别是:
写寄存器函数(LCD_RegWrite)δ
δ数据写函数(LCD_DataWrite)
数据读函数(LCD_DataRead)δ这三个函数...
Cache (“增强型缓存加速技术”或“智能加 速引擎”或”增速高速缓存” )是NVIDIA的一项软 硬件一体化解决方案。我们把它粗略解释为可以直 接利用系统内存进行渲染,也就是可以大幅减少显 存容量从而降低成本同时又可保持良好3D性能的 技术。具有16或者32MB板载显存的显卡,通过 TC技术,可以得到128MB有效帧缓存用于应用程 序。既然是利用系统内存,这和以前的集成显卡又有什 么区别...
显存地址映射。只要知道该类PCI设备的Vendor号,Device号和索引号myIndex,就可以查找到该类PCI设备的MEMORY地址和IO地址,以及中断级。并将第一个MEMORY地址给出它的从物理地址到虚拟地址的映射。...
针对实际的航空数字化仪表,给出了SVGA 显示模式下动画显示的实现过程,其中包括了直接写屏技术、双缓冲技术等,并提出了一种利用显存自身实现双缓冲动画显示的新方法。关键词:数字化仪表;SVGA;动画;双缓冲目前飞机座舱显示系统中使用的电子显示仪表,基本上沿用传统的指针显示形式。而计算机成像的彩色动画显示格式,则突破了传统的显示形式,使飞行员能迅速掌握瞬息变化的动态信息,做到一目了然,直接提高...
- 1);&&& size = lcd_setmem (addr);&&& gd-&fb_base = //为显存缓冲区地址变量赋值 #endif /* CONFIG_LCD */&/* armboot_start is defined in the board-specific linker &#115...
Digtal(AC3)等。DivX;-) Audio、PCM、MP3、DTS等。
码流(容量) 取决于分辨率和具体的编码设置。
质量 视频画质接近DVD水平,超过VCD和LD;
音频可以达到CD质量(48kHz, 96kBits, stereo) 或者是多声道数码声(例如Dobly Digtal 5.1)
系统配置 300MHz CPU,64M 内存,8M显存,系统安装了相应的Div……...
获取NVidia Control Panel(NV控制面板)参数的源代码可以获取 显卡id,显存,AA AF模式,是否支持SLI,分辨率等信息。...
单片机控制122x32液晶。液晶内部芯片包含RAM(类似于显存),当然不具备2D3D加速。不过,功耗非常低,一般几个毫瓦。...
显存相关帖子
&&业界首款16Gb GDDR6显存芯片即将投入量产,传可提供72GB/s的数据传输率,使用的是10nm级工艺,三星称功耗会降低35%。
& & 三星电子1月18日宣布,开始量产业内首款16Gb(2GB)容量的GDDR6显存芯片。
& & 参数方面,三星表示,GDDR6的单芯片容量是上一代20nm GDDR5的两倍,速度也是两倍...
7.2 本章示例介绍
因为有经验不足的朋友反映在看了这个教程后还是不知道怎么操作,总是不成功,因此这里小梅哥使用我们芯航线FPGA的开发板,一步一步演示这个实现过程,将整个过程具体化。
先说明下我这个设计工程的结构:
EPCS16:用来存储FPGA配置文件和NIOS的固件,本例中最终转换得到的JIC文件也是烧写到该器件中。
512K字节SRAM:作为NIOS II运存或者4.3寸TFT显存...
建议打开SSH(默认就是打开的),是通过网络访问树莓派的基本方式。其它接口根据需要开关。
Performance选项卡
Overclock 超频。这一代树莓派官方还不支持超频。如果使用支持超频的树莓派,一定要注意做好散热措施,避免烧坏。
GPU Memory:显存。显存共享主内存,没有特别需求不用修改。
Localisation选项卡
这4个都是地区相关...
需要使用硬盘空间来模拟,这时就需要CPU的介入,所以占用率一下子就上去了,内存升级到4G就会有很大改观。
Win7的静态内存占用率已经是1G多,Win8占用率更高,如果是整合显卡还要分配显存,这更捉衿见肘,就是只开几个浏览器窗口,内存就耗完了,所以4G内存是起码的,不能再少了,当然这时需要64位的操作系统才能完整寻址。
白丁 发表于
有擦写寿命,但是没你想...
r_tmr_rj0_interrupt(void) //1ms定时器RJ0中断函数
void Display(void)//LED点阵屏刷新显存
void SEL_line(unsigned char line) //选LED点阵屏, 送“行”数据
void Write_595(unsigned char data)//同步移位, 送“列”数据
//定时器rj0初始化 1ms...
; & & & EQU& & & & 60H& & & & & & & & ;显存
& & & & & & & &
& & & &nbsp...
这个Verilog语言中非常基本的一条语句:
always@(posedge clock) Q &= D;
这相当于C里面的一条条件判断语句,意思就是在时钟有上升沿信号的时候,输出信号 \'D\' 被储存在\'Q\'。 就是通过诸如此类的语句描述了触发器电路组成的缓存和显存之间数据交换的基本方式。综合软件就是依靠这些代码描述出来的门电路的工作方式关系生成电路的。在芯片的设计阶段...
,硬件编解码器也工作,怎么反而不抖了呢?
大家各抒己见~! 大家来讨论~也说6410的VGA显示抖动 不一样的,显存是DDR上,是DMA方式处理的,直接驱动LCD的,是系统划分的
DX就是让你对显存操作,直接对屏操作了
这个得狂项一下,真得没整过。
补充一下:以上的描述当中VGA输出的分辨率都是640*480。如果用800*600,则两种方法都会导致抖动,不过,前者抖得厉害,频繁的屏幕...
mailbox可存储多条消息内存管理固定大小内存块管理固定分区内存管理
小内存系统动态内存管理
大内存系统SLAB内存管理定时器只能使用OSTimeDly进行时间间隔处理挂接到OS定时器的硬定时器或软定时器中断嵌套允许允许 适合 DIY显存8M的单片机显卡的开源操作系统RT-THREAD RT-Thread实时操作系统中实现的是一套面向嵌入式设备的虚拟设备文件系统,它结合...
& && & }&&//if end
void write_displaybuf(uchar x)
&&if (displaybufpoint==6)&&&&//6个数码管
你可能感兴趣的标签
热门资源推荐用dvi转vga一定会有波纹?_图拉丁吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:1,882,267贴子:
用dvi转vga一定会有波纹?收藏
显示器只有vga,买的新显卡没有vga,用dvi转vga头,玩游戏时有强烈的波纹,画面模糊,开垂直同步好点,买了根直连线也不能解决,机箱前置音频口,接耳机有吱吱声。我的老显卡就没有这个问题,电源电压也稳定,难道dvi转vga就一定会有波纹?有没有人同样转接没有波纹的?今天是第六天了,大家帮我参谋下,要不要退显卡
不是,要么转接头有问题,要么线有问题
2台机器用DVI转VGA,没发现有。
新显卡都缩水了模拟信号的滤波电路 无解 如果不是这个问题 可以尝试在A卡的设置里调节场行同步的正负极 或者勾上复合同步
7770没遇到
7850遇到过,而且玩cf gps就100
dvi,索泰560se,aoc显示器,没这个问题
换显示器吧。买个有DVI接口的,不然无解。
看到楼主居然关注了同性恋吧,睾丸癌吧,手淫吧,我也是醉了!
新买的HDMI转VGA的也波纹。以前用的DVI转VGA的就没事
昨天刚捡了个旧的dvi转vga的头 并没有水波纹
刷新率高些,分辨率低些就可以了
换线,换显示器吧。
我的也有,以为是显示器问题,直接换了显示器。。用HDMI就没了
我的7750,三星显示器暂时没问题
7850往上的显卡都没有vga
玩个别游戏的时候有水波纹,后来嫌烦直接买个根线把转接头扔了
肯定是转接头的问题啦,而且你用的肯定是24+5的那款吧,你换的线肯定是24+5转vga吧。楼上一堆扯蛋的我还能说什么?
7750vga也会
今天去看4D电影,坐在边上的人手 舞足蹈鬼哭狼嚎的,于是我扇了他 一巴掌,结果他和他的朋友说,卧 槽这电影好逼真我感觉我被人打 了。
我的没问题,转接头还是卖家送的,一切正常,,,,,,多少字了
分辨率太高了,分辨率越高,数据传输量越大,vga线越瓶颈
我的960转vga也会,所以果断换了一个HDMI显示器
vga线的质量不好,去找一根又粗又硬的旧vga线,效果很好,软绵绵的线都是偷工减料的
22l+1,之前转接头用那种针不全的,毫无问题。。。
登录百度帐号占坑。&br& update:&br&&br&&b&============================================================&/b&&br&&blockquote&&ol&&li&&b&笔记本: &/b&&/li&&ol&&li&&b&MacBook Pro(港版13低配,15顶配性价比最高)&/b&&/li&&li&&b&ThinkPad T系列,X 系列&/b&&/li&&/ol&&li&&b&键盘:&/b&&/li&&ol&&li&&b&机械键盘:FILCO 圣手 87键 红轴(日),樱桃(Cherry)G80-3000 茶轴 (德),&/b&&b&DUCKY 2087S(台)&/b&&/li&&li&&b&静电容:HHKB(日)&/b&&/li&&li&&b&情怀插入:小黑USB键盘
ThinkPad USB Track Point 键盘 &/b&&b&0B47082&/b&&/li&&/ol&&li&&b&显示器:Eizo(日 @&a href=&http://www.zhihu.com/people/MarsCaveman& class=&internal&&李柱铭&/a& 推荐),戴尔,三星,明基,22寸以上&br&&/b&&/li&&li&&b&PC配置:i7,16G,SSD,双显示器, &br&&/b&&/li&&li&&b&电脑椅:Aeron Chair(个人经济承受能力下,最贵的)&/b&&/li&&li&&b&萌妹纸一枚(多多益善,不过太多小心受用不起)。&/b&&br&&/li&&li&&b&IDE: &/b&&/li&&ol&&li&&b&Win(Visual Studio)&/b&&/li&&li&&b&Linux(Vim,其他真的还有必要说吗?)&/b&&/li&&li&&b&Mac(Xcode,CodeRunner,SnippetsLab)&/b&&/li&&li&&b&跨平台(Pycharm,UltraEdit,Eclipse,&b&Source Insight&/b&,Codeblocks)&/b&&/li&&li&&b&插件(Visual Assist X,Pydev)&/b&&/li&&/ol&&li&&b&字体:&/b&&/li&&ol&&li&&b&Source Code Pro ,是Adobe 发布的一套开源字体。个人偏爱加粗版。 &a href=&//link.zhihu.com/?target=http%3A//www.oschina.net/p/source-code-pro& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Source Code Pro首页、文档和下载&/a&&/b&&/li&&li&&b&其他详见: &a href=&http://www.zhihu.com/question//answer/& class=&internal&&有哪些适合用于写代码的西文字体?&/a&&/b&&/li&&/ol&&li&耳机:&/li&&ol&&li&听音乐:AKG Q460&/li&&li&玩游戏:赛睿西伯利亚 v1,v2&/li&&/ol&&/ol&&/blockquote&&br&&b&============================================================&/b&&br&&br&&b&配图&/b&&br&&br&&b&1. 笔记本不用说,水果牌和小黑。&/b&&br&&br&&b&MacBook Pro&/b&&br&&blockquote&实用主义至上的代码狗,一定会选&b&MBP &/b&,Air是给小清新们准备的。&/blockquote&&br&&br&&br&&br&&figure&&img src=&https://pic4.zhimg.com/833c5e5be6cdbca2f5f6df_b.jpg& data-rawwidth=&1633& data-rawheight=&751& class=&origin_image zh-lightbox-thumb& width=&1633& data-original=&https://pic4.zhimg.com/833c5e5be6cdbca2f5f6df_r.jpg&&&/figure&&blockquote&购买方案&b&:(港版)&br&&u&方案1:买RMBP 13 低配,外加2块24寸+显示器。比较划算。&br&方案2:买15寸顶配(个人方案)&/u&&/b&&/blockquote&&br&&b&ThinkPad T系列,X 系列(港版,或者走美亚海淘)&/b&&br&&b&推荐:T450P,X1&/b&&br&&br&&b&Mac Mini&/b&&br&&figure&&img src=&https://pic3.zhimg.com/ba5e4a55efe6_b.jpg& data-rawwidth=&1030& data-rawheight=&613& class=&origin_image zh-lightbox-thumb& width=&1030& data-original=&https://pic3.zhimg.com/ba5e4a55efe6_r.jpg&&&/figure&&br&&blockquote&&b&Mac Mini &/b&,给拥有顶配 WIN PC机,偶尔需要Mac下开发,但还是抛弃不了众多Win游戏的代码狗准备的。&br&1. 接上显示器,秒变Mac狗。&br&2. 想玩PC游戏,连上PC机箱,瞬间就美好了。&br&3. 性价比不算太高。&/blockquote&&br&------------------------------------------- 割 -----------------------------------------------------&br&&b&2 键盘&/b&&br&&br&&b&Filco 圣手, GKING 二代 ,87键,粉色,红轴机械键盘 (推荐红轴)(日本制造)&/b&&br&&br&&figure&&img src=&https://pic2.zhimg.com/e53caedb439e1ffbbdbe5_b.jpg& data-rawwidth=&774& data-rawheight=&548& class=&origin_image zh-lightbox-thumb& width=&774& data-original=&https://pic2.zhimg.com/e53caedb439e1ffbbdbe5_r.jpg&&&/figure&&blockquote&&b&update:&br&托出差同事从日本帮带,实体店没白色款,买的黑色红轴。&br&折合650RMB。比国内便宜不少,&/b&&b&可以体会一下。&/b&&br&&b&&br&使用一段时间感受:&br&1. 做工很不错,带钢板很重,键帽很舒服。敲击感觉很爽。&br&2. 与cherry-G80-3000茶轴比较,怎么说,做工好很多,cherry的做工,有点对不起价格。至于敲击感觉,我想说,玩FPS游戏,还是茶轴舒服。更喜欢茶轴多一点。&br&3. 茶轴和红轴对比。茶轴更有节奏感,敲击振幅比较容易均衡。红轴,敲起来,较之要轻。&br&4. 整体对filco这款键盘很满意。&br&5. 87键很适合放背包携带。赞。&br&6. 至于按键声音,其实茶轴和红轴,都很吵的好伐~&br&&/b&&/blockquote&&br&---------------------------------------- 割 -------------------------------------------------&br&&br&&b&HHKB Pro2, 静电容键盘, (日本制造)&/b&&br&&figure&&img src=&https://pic1.zhimg.com/bc7ab52bbf436d3af274bc_b.jpg& data-rawwidth=&451& data-rawheight=&324& class=&origin_image zh-lightbox-thumb& width=&451& data-original=&https://pic1.zhimg.com/bc7ab52bbf436d3af274bc_r.jpg&&&/figure&&blockquote&手感跟机械键盘,完全不同。非Emacs党,无爱。主要是穷。&/blockquote&---------------------------------------------- 割 ----------------------------------------------------&br&&br&&b&Ducky 2087S 魔力鸭 (台湾制造)&/b&&br&&figure&&img src=&https://pic2.zhimg.com/381fbe9fc5bb13137d49_b.jpg& data-rawwidth=&745& data-rawheight=&488& class=&origin_image zh-lightbox-thumb& width=&745& data-original=&https://pic2.zhimg.com/381fbe9fc5bb13137d49_r.jpg&&&/figure&&br&&blockquote&湾湾出产,质量还是过得去。&br&&b&价格是唯一亮点。&/b&手感比 Filco 略差,一分钱一分货。&/blockquote&&br&------------------------------------------ 努力地割 ------------------------------------------------&br&&br&&b&4 工位效果(这是在CHH上盗过来的图,值得借鉴,show一下吧)&br&&/b&&br&&figure&&img src=&https://pic2.zhimg.com/063c7b18b19d2f69ff28ff0b29f13e6d_b.jpg& data-rawwidth=&636& data-rawheight=&423& class=&origin_image zh-lightbox-thumb& width=&636& data-original=&https://pic2.zhimg.com/063c7b18b19d2f69ff28ff0b29f13e6d_r.jpg&&&/figure&&br&&blockquote&&b&原地址:&br&&a href=&//link.zhihu.com/?target=http%3A//www.chiphell.com/thread--1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&电脑桌终极进化论(chh论坛中毒全纪实.)(6.18-更新理线心得)&/a&&br&&br&我自己的工位,没这么nice,在观摩取经ing。&/b&&br&&b&品味嘛,是慢慢熏出来的。&br&&/b&&/blockquote&-------------------------------- 努力地割 ------------------------------------------------------&br&&br&&b&5 电脑椅
&/b&&br&&b&Aeron Chair (据说是世界上最舒服的椅子)&/b&&br&&br&&figure&&img src=&https://pic4.zhimg.com/ec2ffea81f3b_b.jpg& data-rawwidth=&587& data-rawheight=&411& class=&origin_image zh-lightbox-thumb& width=&587& data-original=&https://pic4.zhimg.com/ec2ffea81f3b_r.jpg&&&/figure&&br&&br&&blockquote&&b&《软件随想录》的作者Joel Spolsky 推荐的座椅(Joel是谁,自行google)&/b&&br&&b&我会说,大学看这本书的时候,就默默的记住有这么一款椅子麽。&br&Joel所描绘的软件公司,绝逼是代码狗梦寐以求的所在。&/b&&/blockquote&&br&&b&&a href=&//link.zhihu.com/?target=http%3A//www.joelonsoftware.com/articles/FieldGuidetoDevelopers.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&joelonsoftware.com/arti&/span&&span class=&invisible&&cles/FieldGuidetoDevelopers.html&/span&&span class=&ellipsis&&&/span&&/a&&/b&&br&&b&&a href=&//link.zhihu.com/?target=http%3A//www.chiphell.com/thread--1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&据说是世界上最舒服的椅子——Aeron Chair&/a&&/b&&br&&b&&a href=&http://www.zhihu.com/question/& class=&internal&&为什么aeron椅子在程序员这个群体内非常出名,在设计师的圈子中反而没什么名气?&/a&&/b&&br&&b&&a href=&http://www.zhihu.com/question/& class=&internal&&Herman Miller 的 Embody 办公椅好在哪里?&/a&&/b&&br&&br&------------------------------------ 努力地割 -----------------------------------------------------&br&&b&上面的椅子来镇楼的,下面来个接地气的.&/b&&br&&b& Ergomax 迩高迈思
(这是国产货 ! )&/b&&br&&br&&figure&&img src=&https://pic1.zhimg.com/801b4fefc8_b.jpg& data-rawwidth=&942& data-rawheight=&495& class=&origin_image zh-lightbox-thumb& width=&942& data-original=&https://pic1.zhimg.com/801b4fefc8_r.jpg&&&/figure&&br&&b&&blockquote&价格很亲民。&/blockquote&&br&附淘宝旗舰店:&br&&a href=&//link.zhihu.com/?target=http%3A//ergomax.tmall.com/%3Fspm%3Da1z10.1.0.0.UnNkUC& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&首页-ergomax旗舰店&/a&&/b&&br&&b&------------------------------------ 努力地割 --------------------------------------------&br&&/b&&br&&b&update: &/b&&br&&b&目测点赞要过百了.更新一下吧。&/b&&br&&br&&b&1. 更新个机械键盘。&/b&&b&德国Cherry-G80-3000,(原厂经典)。&/b&&br&&blockquote&&b&自用白色,茶轴。玩FPS射击类游戏很爽。&/b&&br&&b&需要注意的是:键盘很大。(真的很大 ==!)&/b&&br&这个大杀器只适合家用。代码狗考虑随身携带的,请无视掉。&/blockquote&&figure&&img src=&https://pic1.zhimg.com/ad07e44f23e0a03f179908_b.jpg& data-rawwidth=&851& data-rawheight=&782& class=&origin_image zh-lightbox-thumb& width=&851& data-original=&https://pic1.zhimg.com/ad07e44f23e0a03f179908_r.jpg&&&/figure&&br&京东链接:&br&&a href=&//link.zhihu.com/?target=http%3A//item.jd.com/346667.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【樱桃G80-3000LXCEU-0】樱桃(Cherry)G80-3000LXCEU-0 机械键盘(白色茶轴3000)【行情 报价 价格 评测】&/a&&br&&br&&b&2. 鼠标和耳机。&/b&&br&&blockquote&没必要太好。玩游戏麽,适度烧。&br&自用赛睿(SteelSeries)家的(鼠标垫也是)。用着蛮爽的。我是赛睿脑残粉。&/blockquote&&br&&b&鼠标推荐:赛睿Sensei【RAW】系列 &/b&(附京东链接)&br&&blockquote&磨砂的,带呼吸灯。不过有强迫症还是关掉了~ =,=&br&赛睿家的鼠标很好用。灯厂(Razer)的鼠标有点硬。=,=&/blockquote&&br&&b&&a href=&//link.zhihu.com/?target=http%3A//item.jd.com/789959.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【赛睿Sensei [RAW]《使命召唤:黑色行动2》版】赛睿(SteelSeries)Sensei [RAW] 激光游戏鼠标 《使命召唤:黑色行动2》版【行情 报价 价格 评测】&/a&&/b&&br&&br&&b&鼠标垫推荐:赛睿QCK系列 &/b&(附京东链接)&br&&blockquote&玩FPS射击类游戏,不能推荐更多。&/blockquote&&br&&a href=&//link.zhihu.com/?target=http%3A//item.jd.com/265102.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【赛睿QcK Mass】赛睿(SteelSeries)QcK Mass 鼠标垫【行情 报价 价格 评测】&/a&&br&&br&&b&耳机推荐:AKG Q460,赛睿 西伯利亚v1,v2系列&/b&(附京东链接)&br&&blockquote&大爱紫色款。 其实买V1就可以,便宜。非专业,足够。&br&v2贵些,其实我想说紫色很好看啊。&/blockquote&&figure&&img src=&https://pic2.zhimg.com/72de7ec8e2_b.jpg& data-rawwidth=&784& data-rawheight=&831& class=&origin_image zh-lightbox-thumb& width=&784& data-original=&https://pic2.zhimg.com/72de7ec8e2_r.jpg&&&/figure&&br&&br&&b&&a href=&//link.zhihu.com/?target=http%3A//item.jd.com/651272.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【赛睿 西伯利亚v2】赛睿(SteelSeries)西伯利亚v2 耳机 紫色【行情 报价 价格 评测】&/a&&/b&&br&&br&喜欢听音乐,推荐AKG Q460(自用)&br&亮点:耳机线可以拆卸,坏了可以更换。&br&音质麽,配合 Mac,听着还是很爽的。&br&&figure&&img src=&https://pic3.zhimg.com/5e93dffcacc0a1f8e1b62_b.png& data-rawwidth=&1150& data-rawheight=&520& class=&origin_image zh-lightbox-thumb& width=&1150& data-original=&https://pic3.zhimg.com/5e93dffcacc0a1f8e1b62_r.png&&&/figure&&br&&a href=&//link.zhihu.com/?target=http%3A//item.jd.com/600419.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【AKGQ460Lime】爱科技(AKG)Q460
头戴式耳机 大师系列 迷你可折叠便携耳机 绿色【行情 报价 价格 评测】&/a&&br&------------------------------------------ 努力地割 ----------------------------------------&br&&br&(未完,待补充。)
占坑。 update: ============================================================ 笔记本: MacBook Pro(港版13低配,15顶配性价比最高)ThinkPad T系列,X 系列键盘:机械键盘:FILCO 圣手 87键 红轴(日),樱桃(Cherry)G80-3000 茶轴 (德…
作为资深被骗人员,怒答&br&&strong&兼职事件&/strong&&br&1. 大学时想兼职,然后就从学校贴的招兼职的广告打电话过去,然后去了发现是中介,交了60块钱,说保找到兼职。结果当时就联系到个兼职,之后就不管了。&br&&br&2. 上面说到中介联系到的兼职,就是我第二个被骗的经历啊。是一个做手工的兼职,做那种布贴画和沙画,然后先交材料费,貌似360,然后交给你怎么做,做好之后高价回收。然后先做沙画,每周都去学,貌似学了一个多月,马上就要做完了,她就不教给你最后封上那个步骤,然后她就没办法回收,最后怎么了有些忘了,反正就是材料费全没拿回来,期间还收了布贴画的材料费300.。。作为一个兼职的穷学生,简直好打击啊。。。。&br&&br&兼职告一段落,因为后来就找了学校里的兼职。&br&&br&&br&&br&3. &strong&聋哑人事件
&/strong&有一次在KFC吃饭,被聋哑人强制卖给自己一个挂件,花了10块钱。 后来上网查发现是假冒的。再后来在火车站也碰到过,先给你看一个证,然后就往你书包上系东西,然后就找你收钱,有个本,写着XXX50元、100元,打着为什么聋哑人捐款的名义,被骗20块。&br&&br&4.&strong&老奶奶事件
&/strong&跟朋友从宿舍去超市,挺早的,7点多吧,遇见一个50岁左右带着个70左右老奶奶的大婶,穿的还成,一口山东话:“同学,老奶奶2天没吃饭了,给几块钱买点馒头吃吧!”跟同学给了几块钱,本来到这没有什么,挺正常的,不像被骗,然后跟同学又走了几百米,又碰到了一!模!一!样!的事情,主人公变成 了老爷爷!!&br&&br&5.&strong&路费事件
&/strong&在火车站下车,准备回学校。“美女,能帮个忙吗?”我这一听,喊我呢,问个路什么的我还是能指指的。“美女,我从北京来天津玩的,结果钱全花光了,回去车费不够了,还差30块,你能不能先借我,回去我给你充话费。”我这一看,穿的冠冕堂皇的,也不像骗子啊。给了钱和电话,一心觉得做了好事,等着话费进账。然后,呵呵~&br&&br&6.&strong&美容院事件
&/strong&随着我越来越精明,被骗的频率明显下降啊。一次感冒了,想去家乐福里的药店买点药,还下雨,我还一直流鼻涕,钱包也没拿,就兜里揣了100,拿着伞,刚一进家乐福一楼,一个年轻的男的就说:“要不要体验我们的巴拉巴拉的产品,免费体验。。。我一向对免费的不占便宜,而且感冒难受就想赶紧买药回去睡觉,他就一直不让我走,然后讲讲讲,然后说什么帮帮忙啊,进店我就有业绩什么的。我懒得跟他在说话,就去了。就去就换成两个女的,然后就让你躺床上啊,就开始往你脸上涂东西啊,反抗都不行啊!然后只给你涂了一半脸,是美白的,洗了之后真的白了,然后就让我办卡,我说我不办,她就说也不贵什么的,我说我没带钱,她就说什么便宜一类的,我说我就是来买药的,没带多少钱,她说那你有多少钱吧!我说:我!不!办!她就说,你不办就不给你涂另一半脸,当时真的一半白一半黑啊!我坚决不办,并表示要走,那两个人不让走,然后我就放大招了,开始擤鼻涕,你知道,感冒的人一般都比较丑,还邋遢。。。然后其中一个女的嫌弃的说,让她走吧。。。我就半边黑脸赶紧走了。。。事后想报警,但我等P民还是不愿意打电话给警察叔叔的。。&br&&br&7. &strong&蟑螂药事件
&/strong&这真是考验我智商的一件事了,老高明的骗子了!一个周末,我在家,突然一阵敲门,去开门,一个穿着职业正装短裙,拿着一个本I,背一个包,然后一进门就给我看工作证,说是社区工作人员,然后先问了我是租房还是自己的,合租还是自己租之类的基本情况,然后说上海市有一个什么大家共同灭蟑螂这个事情(记不清了,大概这个意思),然后每家每个住户都要用他们统一的药,药是免费的,听着挺合理啊,然后她就那个本让我登记,我看到楼上别的和旁边的家都登记了,然后还写着50块钱,我就问了,还要交钱啊,她说药是免费的,但他们培训我们怎么用,用在哪要交费,巴拉巴拉,反正我深信不疑,社区组织的啊,大家都交了啊,最后交了钱都没什么怀疑。第二天跟同事说这个事,同事表示从来没有过啊,我一上网查,表示被骗了。。。打她电话已打不通。。。&br&&br&8. &strong&网购事件
一次,从当当上抢购了个1元秒杀的东西,付款成功,第二天,接到电话,说是那个店里的,然后由于当当什么失误,导致订单成功,但并未给他们付款,要货到付款什么的,我相信他是他一上来说了我的名字,我买了什么东西,花了多少钱,我的收货地址。完全没有错。但是当时我有点忙,说,要不我不要了,我的地址是公司的,前台收快递,货到付款不方便,他就说那就按他们的步骤怎么怎么样重拍,还是怎么着,普通话不标准,我听不太清,然后又忙,我就说,那我不要了,我就申请退款就好了,正好一个电话进来了,我说我要接个电话,就挂了,之后也没再打进来,然后晚上闲下来,就百度了这个事情,说是骗子,是卖家把买家的个人信息卖了。。。&br&&br&&strong&9.医托事件
&/strong&来大姨妈痛经疼的要死,去医院挂妇科,300多号啊!!!心哇凉哇凉的,但没办法,等吧。然后坐椅子上,旁边的一个妇女就主动聊天,说了一堆,反正就是这个医院看妇不好啊,我之前花了多少多少钱也没看好,后来在哪哪个医院看,没花多少钱就看好了,那个医院离这不远啊,打车10几块就到了,还不用排这么长的队,到那里就能看啊!我确实动心了,因为我实在疼的挺不住了,而且她全程很关心你的样子,说话也不像刻意提到的,只是分享自己的经验那种,然后我说我看看吧,但是!我实在没有力气换医院了,走出医院的力气都没有啊!!就上了个厕所然后换了个位置坐,后来发现她又说动了旁边的一个人去,突然警觉,这是不是就是传说中的医托啊?然后打开万能的百度,查了那个医院,好多人说就是这样被骗去的,花了好几千又什么都没看好。。。对了,她还有个搭档。。。最后吐槽下那个医院,我排了4个小时的号啊!!!我都快死在医院里了就是看不到医生啊!!!&br&&br&&br&&strong&我总结了一下避免上当的经验,最重要的是,不要贪小便宜!免费的不要!不知道什么情况之前先百度!!&/strong&&br&&br&&strong&我居然写了这么长。。。先写这么多,不知道还能想起来什么!&/strong&
作为资深被骗人员,怒答 兼职事件 1. 大学时想兼职,然后就从学校贴的招兼职的广告打电话过去,然后去了发现是中介,交了60块钱,说保找到兼职。结果当时就联系到个兼职,之后就不管了。 2. 上面说到中介联系到的兼职,就是我第二个被骗的经历啊。是一个做…
VS在这里用的魔法叫做Debug Visualizer,通过叫natvis的xml文件描述对象的内存布局以及如何显示。如果希望自己的类也能有自定义的显示,只要写一个natvis文件即可。&br&&br&1. 在工程中添加魔法卷轴。&figure&&img src=&https://pic2.zhimg.com/8afb7a45c2eff5_b.png& data-rawheight=&289& data-rawwidth=&942& class=&origin_image zh-lightbox-thumb& width=&942& data-original=&https://pic2.zhimg.com/8afb7a45c2eff5_r.png&&&/figure&2. 在卷轴上写好要吟唱的魔法。&br&&div class=&highlight&&&pre&&code class=&language-xml&&&span class=&cp&&&?xml version=&1.0& encoding=&utf-8&?&&/span&
&span class=&nt&&&AutoVisualizer&/span& &span class=&na&&xmlns=&/span&&span class=&s&&&http://schemas.microsoft.com/vstudio/debugger/natvis/2010&&/span&&span class=&nt&&&&/span&
&span class=&nt&&&Type&/span& &span class=&na&&Name=&/span&&span class=&s&&&TestVector&*&&&/span&&span class=&nt&&&&/span&
&span class=&nt&&&DisplayString&&/span&{{size={num}}}&span class=&nt&&&/DisplayString&&/span&
&span class=&nt&&&Expand&&/span&
&span class=&nt&&&Item&/span& &span class=&na&&Name=&/span&&span class=&s&&&[size]&&/span& &span class=&na&&ExcludeView=&/span&&span class=&s&&&simple&&/span&&span class=&nt&&&&/span&num&span class=&nt&&&/Item&&/span&
&span class=&nt&&&ArrayItems&&/span&
&span class=&nt&&&Size&&/span&num&span class=&nt&&&/Size&&/span&
&span class=&nt&&&ValuePointer&&/span&ptr&span class=&nt&&&/ValuePointer&&/span&
&span class=&nt&&&/ArrayItems&&/span&
&span class=&nt&&&/Expand&&/span&
&span class=&nt&&&/Type&&/span&
&span class=&nt&&&/AutoVisualizer&&/span&
&/code&&/pre&&/div&3. 见证魔法的奇迹。&br&&figure&&img src=&https://pic1.zhimg.com/f09a0cc9ee854f58e7bd64bba1c94880_b.png& data-rawheight=&448& data-rawwidth=&885& class=&origin_image zh-lightbox-thumb& width=&885& data-original=&https://pic1.zhimg.com/f09a0cc9ee854f58e7bd64bba1c94880_r.png&&&/figure&4. 施法中重写卷轴,实时生效哦!&br&&figure&&img src=&https://pic3.zhimg.com/5c1c32fceb0b16c0e24a_b.png& data-rawheight=&322& data-rawwidth=&1086& class=&origin_image zh-lightbox-thumb& width=&1086& data-original=&https://pic3.zhimg.com/5c1c32fceb0b16c0e24a_r.png&&&/figure&&br&&br&参考: &a href=&//link.zhihu.com/?target=https%3A//msdn.microsoft.com/en-us/library/jj620914.aspx& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Create custom views of native objects&/a&&br&内置的natvis文件在%VSINSTALLDIR%Common7\Packages\Debugger\Visualizers,可以找到关于STL的作为参考。
VS在这里用的魔法叫做Debug Visualizer,通过叫natvis的xml文件描述对象的内存布局以及如何显示。如果希望自己的类也能有自定义的显示,只要写一个natvis文件即可。 1. 在工程中添加魔法卷轴。2. 在卷轴上写好要吟唱的魔法。 &?xml version="1.0" encoding=…
&figure&&img src=&https://pic3.zhimg.com/v2-6afa2a639ea529ffba293_b.jpg& data-rawwidth=&589& data-rawheight=&371& class=&origin_image zh-lightbox-thumb& width=&589& data-original=&https://pic4.zhimg.com/v2-6afa2a639ea529ffba293_r.jpg&&&/figure&&p&本文将以个人(开发)的角度,讲述如何从零开始,编写、搭建和部署一个基于Python的Web应用程序。&/p&&p&从最简单的出发点来剖析,一个web应用后端要完成的工作抽象出来无非就是3点:&/p&&ol&&li&接收和解析请求。&/li&&li&处理业务逻辑。&/li&&li&生产和返回响应。&/li&&/ol&&p&对于初学者来说,我们关心的只需这些步骤就够了。要检验这三个步骤,最简单的方法是先写出一个hello world。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&request-&&hello world&-&response
&/code&&/pre&&/div&&p&python有许多流行的web框架,我们该如何选择呢?试着考虑三个因素:&/p&&ul&&li&易用:该框架是面对初学者友好的,而且具有健全的文档,灵活开发部署。例如flask,bottle。&/li&&li&效率:该框架适合快速开发,拥有丰富的轮子,注重开发效率。例如django。&/li&&li&性能:该框架能承载更大的请求压力,提高吞吐量。例如falcon,tornado,aiohttp,sanic。&/li&&/ul&&p&根据场景使用合适的框架能少走许多弯路,当然,你还能自己写一个框架,这个下面再说。&/p&&p&对于缺乏经验的人来说,易用性无疑是排在第一位的,推荐用flask作为python web入门的第一个框架,另外也推荐django。&/p&&p&首先用virtualenv创建python的应用环境,为什么用virtualenv呢,virtualenv能创建一个纯净独立的python环境,避免污染全局环境。(顺便安利kennethreitz大神的&a href=&https://link.zhihu.com/?target=https%3A//github.com/kennethreitz/pipenv& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&pipenv&/a&)&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&mkdir todo
virtualenv venv
source venv/bin/activate
pip install flask
touch server.py
&/code&&/pre&&/div&&p&代码未写,规范先行。在写代码之前要定义好一套良好代码规范,例如PEP8。这样才能使得你的代码变的更加可控。&/p&&p&心中默念The Zen of Python:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
&/code&&/pre&&/div&&p&下面用flask来编写第一个程序:&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&kn&&from&/span& &span class=&nn&&flask&/span& &span class=&kn&&import&/span& &span class=&n&&Flask&/span&&span class=&p&&,&/span& &span class=&n&&jsonify&/span&
&span class=&n&&app&/span& &span class=&o&&=&/span& &span class=&n&&Flask&/span&&span class=&p&&(&/span&&span class=&n&&__name__&/span&&span class=&p&&)&/span&
&span class=&nd&&@app.route&/span&&span class=&p&&(&/span&&span class=&s1&&'/index'&/span&&span class=&p&&)&/span&
&span class=&k&&def&/span& &span class=&nf&&index&/span&&span class=&p&&():&/span&
&span class=&k&&return&/span& &span class=&n&&jsonify&/span&&span class=&p&&(&/span&&span class=&n&&msg&/span&&span class=&o&&=&/span&&span class=&s1&&'hello world'&/span&&span class=&p&&)&/span&
&span class=&k&&if&/span& &span class=&n&&__name__&/span& &span class=&o&&==&/span& &span class=&s1&&'__main__'&/span&&span class=&p&&:&/span&
&span class=&n&&app&/span&&span class=&o&&.&/span&&span class=&n&&run&/span&&span class=&p&&(&/span&&span class=&n&&host&/span&&span class=&o&&=&/span&&span class=&s1&&'0.0.0.0'&/span&&span class=&p&&,&/span& &span class=&n&&port&/span&&span class=&o&&=&/span&&span class=&mi&&8000&/span&&span class=&p&&)&/span&
&/code&&/pre&&/div&&p&在命令行输入python server.py&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&python server.py
* Running on http://0.0.0.0:8000/ (Press CTRL+C to quit)
&/code&&/pre&&/div&&p&打开浏览器,访问&a href=&https://link.zhihu.com/?target=http%3A//127.0.0.1%3A8000/index%25EF%25BC%258C%25E5%25A6%%%25E6%E5%25A4%2596%25EF%25BC%258C%25E4%25BC%259A%25E7%259C%258B%25E5%%25E4%25B8%258B%25E9%259D%25A2%25E7%259A%%E5%25BA%%& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&http://127.0.0.1:8000/index&/a&,如无意外,会看到下面的响应。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&{
&msg&: &hello world&
&/code&&/pre&&/div&&p&一个最简单的web程序就完成了!让我们看下过程中都发生了什么:&/p&&ol&&li&&p&客户端(浏览器)根据输入的地址&a href=&https://link.zhihu.com/?target=http%3A//127.0.0.1%3A8000/index%25E6%2589%25BE%25E5%%25E5%258D%258F%25E8%25AE%25AE%25EF%25BC%2588http%29%25EF%25BC%258C%25E4%25B8%25BB%25E6%259C%25BA%25EF%25BC%.0.1%25EF%25BC%2589%25EF%25BC%258C%25E7%25AB%25AF%25E5%258F%25A3%25EF%25BC%EF%25BC%%E8%25B7%25AF%25E5%25BE%2584%25EF%25BC%2588/index%25EF%25BC%2589%25EF%25BC%258C%25E4%25B8%258E%25E6%259C%258D%25E5%258A%25A1%25E5%%25EF%25BC%2588application& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&http://127.0.0.1:8000/index&/a&找到协议(http),主机(127.0.0.1),端口(8000)和路径(/index),与服务器(application server)建立三次握手,并发送一个http请求。&/p&&/li&&li&&p&服务器(application server)把请求报文封装成请求对象,根据路由(router)找到/index这个路径所对应的视图函数,调用这个视图函数。&/p&&/li&&li&&p&视图函数生成一个http响应,返回一个json数据给客户端。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 27
Server: Werkzeug/0.11.15 Python/3.5.2
Date: Thu, 26 Jan :36 GMT
&/code&&/pre&&/div&&/li&&/ol&&p&当我们输入python server.py时,会建立一个服务器(也叫应用程序服务器,即application server)来监听请求,并把请求转给flask来处理。那么这个服务器是如何跟python程序打交道的呢?答案就是&a href=&https://link.zhihu.com/?target=http%3A//archimedeanco.com/wsgi-tutorial/%23& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&WSGI&/a&(Web Server Gateway Interface)接口,它是server端(服务器)与application端(应用程序)之间的一套约定俗成的规范,使我们只要编写一个统一的接口,就能应用到不同的wsgi server上。用图表示它们的关系,就是下面这样的:&/p&&br&&figure&&img src=&https://pic4.zhimg.com/v2-4f9eb56fab93afba5f3ca_b.jpg& data-rawwidth=&589& data-rawheight=&371& class=&origin_image zh-lightbox-thumb& width=&589& data-original=&https://pic4.zhimg.com/v2-4f9eb56fab93afba5f3ca_r.jpg&&&/figure&&br&&p&只要application端(flask)和server端(flask内建的server)都遵循wsgi这个规范,那么他们就能够协同工作了,关于WSGI规范,可参阅Python官方的&a href=&https://link.zhihu.com/?target=https%3A//www.python.org/dev/peps/pep-0333/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&PEP 333&/a&里的说明。&/p&&p&目前为止,应用是下面这个样子的:&/p&&br&&figure&&img src=&https://pic3.zhimg.com/v2-73e7f74fcdc3fe0cb30a911_b.jpg& data-rawwidth=&948& data-rawheight=&167& class=&origin_image zh-lightbox-thumb& width=&948& data-original=&https://pic3.zhimg.com/v2-73e7f74fcdc3fe0cb30a911_r.jpg&&&/figure&&br&&p&一切都很简单,现在我们要做一个Todo应用,提供添加todo,修改todo状态和删除todo的接口。&/p&&p&先不考虑数据库,可以迅速地写出下面的代码:&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&kn&&from&/span& &span class=&nn&&flask&/span& &span class=&kn&&import&/span& &span class=&n&&Flask&/span&&span class=&p&&,&/span& &span class=&n&&jsonify&/span&&span class=&p&&,&/span& &span class=&n&&request&/span&&span class=&p&&,&/span& &span class=&n&&abort&/span&&span class=&p&&,&/span& &span class=&n&&Response&/span&
&span class=&kn&&from&/span& &span class=&nn&&time&/span& &span class=&kn&&import&/span& &span class=&n&&time&/span&
&span class=&kn&&from&/span& &span class=&nn&&uuid&/span& &span class=&kn&&import&/span& &span class=&n&&uuid4&/span&
&span class=&kn&&import&/span& &span class=&nn&&json&/span&
&span class=&n&&app&/span& &span class=&o&&=&/span& &span class=&n&&Flask&/span&&span class=&p&&(&/span&&span class=&n&&__name__&/span&&span class=&p&&)&/span&
&span class=&k&&class&/span& &span class=&nc&&Todo&/span&&span class=&p&&(&/span&&span class=&nb&&object&/span&&span class=&p&&):&/span&
&span class=&k&&def&/span& &span class=&nf&&__init__&/span&&span class=&p&&(&/span&&span class=&bp&&self&/span&&span class=&p&&,&/span& &span class=&n&&content&/span&&span class=&p&&):&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&id&/span& &span class=&o&&=&/span& &span class=&nb&&str&/span&&span class=&p&&(&/span&&span class=&n&&uuid4&/span&&span class=&p&&())&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&content&/span& &span class=&o&&=&/span& &span class=&n&&content&/span& &span class=&c1&&#todo内容&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&created_at&/span& &span class=&o&&=&/span& &span class=&n&&time&/span&&span class=&p&&()&/span& &span class=&c1&&#创建时间&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&is_finished&/span& &span class=&o&&=&/span& &span class=&bp&&False&/span& &span class=&c1&&#是否完成&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&finished_at&/span& &span class=&o&&=&/span& &span class=&bp&&None&/span& &span class=&c1&&#完成时间&/span&
&span class=&k&&def&/span& &span class=&nf&&finish&/span&&span class=&p&&(&/span&&span class=&bp&&self&/span&&span class=&p&&):&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&is_finished&/span& &span class=&o&&=&/span& &span class=&bp&&True&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&finished_at&/span& &span class=&o&&=&/span& &span class=&n&&time&/span&&span class=&p&&()&/span&
&span class=&k&&def&/span& &span class=&nf&&json&/span&&span class=&p&&(&/span&&span class=&bp&&self&/span&&span class=&p&&):&/span&
&span class=&k&&return&/span& &span class=&p&&{&/span&
&span class=&s1&&'id'&/span&&span class=&p&&:&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&id&/span&&span class=&p&&,&/span&
&span class=&s1&&'content'&/span&&span class=&p&&:&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&content&/span&&span class=&p&&,&/span&
&span class=&s1&&'created_at'&/span&&span class=&p&&:&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&created_at&/span&&span class=&p&&,&/span&
&span class=&s1&&'is_finished'&/span&&span class=&p&&:&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&is_finished&/span&&span class=&p&&,&/span&
&span class=&s1&&'finished_at'&/span&&span class=&p&&:&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&finished_at&/span&
&span class=&p&&}&/span&
&span class=&n&&todos&/span& &span class=&o&&=&/span& &span class=&p&&{}&/span&
&span class=&n&&get_todo&/span& &span class=&o&&=&/span& &span class=&k&&lambda&/span& &span class=&n&&tid&/span&&span class=&p&&:&/span& &span class=&n&&todos&/span&&span class=&o&&.&/span&&span class=&n&&get&/span&&span class=&p&&(&/span&&span class=&n&&tid&/span&&span class=&p&&,&/span& &span class=&bp&&False&/span&&span class=&p&&)&/span&
&span class=&nd&&@app.route&/span&&span class=&p&&(&/span&&span class=&s1&&'/todo'&/span&&span class=&p&&)&/span&
&span class=&k&&def&/span& &span class=&nf&&index&/span&&span class=&p&&():&/span&
&span class=&k&&return&/span& &span class=&n&&jsonify&/span&&span class=&p&&(&/span&&span class=&n&&data&/span&&span class=&o&&=&/span&&span class=&p&&[&/span&&span class=&n&&todo&/span&&span class=&o&&.&/span&&span class=&n&&json&/span&&span class=&p&&()&/span& &span class=&k&&for&/span& &span class=&n&&todo&/span& &span class=&ow&&in&/span& &span class=&n&&todos&/span&&span class=&o&&.&/span&&span class=&n&&values&/span&&span class=&p&&()])&/span&
&span class=&nd&&@app.route&/span&&span class=&p&&(&/span&&span class=&s1&&'/todo'&/span&&span class=&p&&,&/span& &span class=&n&&methods&/span&&span class=&o&&=&/span&&span class=&p&&[&/span&&span class=&s1&&'POST'&/span&&span class=&p&&])&/span&
&span class=&k&&def&/span& &span class=&nf&&add&/span&&span class=&p&&():&/span&
&span class=&n&&content&/span& &span class=&o&&=&/span& &span class=&n&&request&/span&&span class=&o&&.&/span&&span class=&n&&form&/span&&span class=&o&&.&/span&&span class=&n&&get&/span&&span class=&p&&(&/span&&span class=&s1&&'content'&/span&&span class=&p&&,&/span& &span class=&bp&&None&/span&&span class=&p&&)&/span&
&span class=&k&&if&/span& &span class=&ow&&not&/span& &span class=&n&&content&/span&&span class=&p&&:&/span&
&span class=&n&&abort&/span&&span class=&p&&(&/span&&span class=&mi&&400&/span&&span class=&p&&)&/span&
&span class=&n&&todo&/span& &span class=&o&&=&/span& &span class=&n&&Todo&/span&&span class=&p&&(&/span&&span class=&n&&content&/span&&span class=&p&&)&/span&
&span class=&n&&todos&/span&&span class=&p&&[&/span&&span class=&n&&todo&/span&&span class=&o&&.&/span&&span class=&n&&id&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&n&&todo&/span&
&span class=&k&&return&/span& &span class=&n&&Response&/span&&span class=&p&&()&/span& &span class=&c1&&#200&/span&
&span class=&nd&&@app.route&/span&&span class=&p&&(&/span&&span class=&s1&&'/todo/&tid&/finish'&/span&&span class=&p&&,&/span& &span class=&n&&methods&/span&&span class=&o&&=&/span&&span class=&p&&[&/span&&span class=&s1&&'PUT'&/span&&span class=&p&&])&/span&
&span class=&k&&def&/span& &span class=&nf&&finish&/span&&span class=&p&&(&/span&&span class=&n&&tid&/span&&span class=&p&&):&/span&
&span class=&n&&todo&/span& &span class=&o&&=&/span& &span class=&n&&get_todo&/span&&span class=&p&&(&/span&&span class=&n&&tid&/span&&span class=&p&&)&/span&
&span class=&k&&if&/span& &span class=&n&&todo&/span&&span class=&p&&:&/span&
&span class=&n&&todo&/span&&span class=&o&&.&/span&&span class=&n&&finish&/span&&span class=&p&&()&/span&
&span class=&n&&todos&/span&&span class=&p&&[&/span&&span class=&n&&todo&/span&&span class=&o&&.&/span&&span class=&n&&id&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&n&&todo&/span&
&span class=&k&&return&/span& &span class=&n&&Response&/span&&span class=&p&&()&/span&
&span class=&n&&abort&/span&&span class=&p&&(&/span&&span class=&mi&&404&/span&&span class=&p&&)&/span&
&span class=&nd&&@app.route&/span&&span class=&p&&(&/span&&span class=&s1&&'/todo/&tid&'&/span&&span class=&p&&,&/span& &span class=&n&&methods&/span&&span class=&o&&=&/span&&span class=&p&&[&/span&&span class=&s1&&'DELETE'&/span&&span class=&p&&])&/span&
&span class=&k&&def&/span& &span class=&nf&&delete&/span&&span class=&p&&(&/span&&span class=&n&&tid&/span&&span class=&p&&):&/span&
&span class=&n&&todo&/span& &span class=&o&&=&/span& &span class=&n&&get_todo&/span&&span class=&p&&(&/span&&span class=&n&&tid&/span&&span class=&p&&)&/span&
&span class=&k&&if&/span& &span class=&n&&todo&/span&&span class=&p&&:&/span&
&span class=&n&&todos&/span&&span class=&o&&.&/span&&span class=&n&&pop&/span&&span class=&p&&(&/span&&span class=&n&&tid&/span&&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&n&&Response&/span&&span class=&p&&()&/span&
&span class=&n&&abort&/span&&span class=&p&&(&/span&&span class=&mi&&404&/span&&span class=&p&&)&/span&
&span class=&k&&if&/span& &span class=&n&&__name__&/span& &span class=&o&&==&/span& &span class=&s1&&'__main__'&/span&&span class=&p&&:&/span&
&span class=&n&&app&/span&&span class=&o&&.&/span&&span class=&n&&run&/span&&span class=&p&&(&/span&&span class=&n&&host&/span&&span class=&o&&=&/span&&span class=&s1&&'0.0.0.0'&/span&&span class=&p&&,&/span& &span class=&n&&port&/span&&span class=&o&&=&/span&&span class=&mi&&8000&/span&&span class=&p&&)&/span&
&/code&&/pre&&/div&&p&这个程序基本实现了需要的接口,现在测试一下功能。&/p&&ul&&li&添加一个todo&/li&&/ul&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&http -f POST http://127.0.0.1:8000/todo content=好好学习
HTTP/1.0 200 OK
Content-Length: 0
Content-Type: text/ charset=utf-8
Date: Thu, 26 Jan :37 GMT
Server: Werkzeug/0.11.15 Python/3.5.2
&/code&&/pre&&/div&&ul&&li&查看todo列表&/li&&/ul&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&http http://127.0.0.1:8000/todo
HTTP/1.0 200 OK
Content-Length: 203
Content-Type: application/json
Date: Thu, 26 Jan :16 GMT
Server: Werkzeug/0.11.15 Python/3.5.2
&{\&created_at\&: .305699, \&id\&: \&6f2b28c4-1e83-45b2-8b86-20e28e21cd40\&, \&is_finished\&: false, \&finished_at\&: null, \&content\&: \&\\u597d\\u597d\\u5b66\\u4e60\&}&
&/code&&/pre&&/div&&ul&&li&修改todo状态&/li&&/ul&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&http -f PUT http://127.0.0.1:8000/todo/6f2b28c4-1e83-45b2-8b86-20e28e21cd40/finish
HTTP/1.0 200 OK
Content-Length: 0
Content-Type: text/ charset=utf-8
Date: Thu, 26 Jan :18 GMT
Server: Werkzeug/0.11.15 Python/3.5.2
http http://127.0.0.1:8000/todo
HTTP/1.0 200 OK
Content-Length: 215
Content-Type: application/json
Date: Thu, 26 Jan :22 GMT
Server: Werkzeug/0.11.15 Python/3.5.2
&{\&created_at\&: .305699, \&id\&: \&6f2b28c4-1e83-45b2-8b86-20e28e21cd40\&, \&is_finished\&: true, \&finished_at\&: .650981, \&content\&: \&\\u597d\\u597d\\u5b66\\u4e60\&}&
&/code&&/pre&&/div&&ul&&li&删除todo&/li&&/ul&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&http -f DELETE http://127.0.0.1:8000/todo/6f2b28c4-1e83-45b2-8b86-20e28e21cd40
HTTP/1.0 200 OK
Content-Length: 0
Content-Type: text/ charset=utf-8
Date: Thu, 26 Jan :20 GMT
Server: Werkzeug/0.11.15 Python/3.5.2
http http://127.0.0.1:8000/todo
HTTP/1.0 200 OK
Content-Length: 17
Content-Type: application/json
Date: Thu, 26 Jan :22 GMT
Server: Werkzeug/0.11.15 Python/3.5.2
&data&: []
&/code&&/pre&&/div&&p&但是这个的程序的数据都保存在内存里,只要服务一停止所有的数据就没办法保存下来了,因此,我们还需要一个数据库用于持久化数据。&/p&&p&那么,应该选择什么数据库呢?&/p&&ul&&li&传统的rdbms,例如mysql,postgresql等,他们具有很高的稳定性和不俗的性能,结构化查询,支持事务,由ACID来保持数据的完整性。&/li&&li&nosql,例如mongodb,cassandra等,他们具有非结构化特性,易于横向扩展,实现数据的自动分片,拥有灵活的存储结构和强悍的读写性能。&/li&&/ul&&p&这里使用mongodb作例子,使用mongodb改造后的代码是这样的:&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&kn&&from&/span& &span class=&nn&&flask&/span& &span class=&kn&&import&/span& &span class=&n&&Flask&/span&&span class=&p&&,&/span& &span class=&n&&jsonify&/span&&span class=&p&&,&/span& &span class=&n&&request&/span&&span class=&p&&,&/span& &span class=&n&&abort&/span&&span class=&p&&,&/span& &span class=&n&&Response&/span&
&span class=&kn&&from&/span& &span class=&nn&&time&/span& &span class=&kn&&import&/span& &span class=&n&&time&/span&
&span class=&kn&&from&/span& &span class=&nn&&bson.objectid&/span& &span class=&kn&&import&/span& &span class=&n&&ObjectId&/span&
&span class=&kn&&from&/span& &span class=&nn&&bson.json_util&/span& &span class=&kn&&import&/span& &span class=&n&&dumps&/span&
&span class=&kn&&import&/span& &span class=&nn&&pymongo&/span&
&span class=&n&&app&/span& &span class=&o&&=&/span& &span class=&n&&Flask&/span&&span class=&p&&(&/span&&span class=&n&&__name__&/span&&span class=&p&&)&/span&
&span class=&n&&mongo&/span& &span class=&o&&=&/span& &span class=&n&&pymongo&/span&&span class=&o&&.&/span&&span class=&n&&MongoClient&/span&&span class=&p&&(&/span&&span class=&s1&&'127.0.0.1'&/span&&span class=&p&&,&/span& &span class=&mi&&27017&/span&&span class=&p&&)&/span&
&span class=&n&&db&/span& &span class=&o&&=&/span& &span class=&n&&mongo&/span&&span class=&o&&.&/span&&span class=&n&&todo&/span&
&span class=&k&&class&/span& &span class=&nc&&Todo&/span&&span class=&p&&(&/span&&span class=&nb&&object&/span&&span class=&p&&):&/span&
&span class=&nd&&@classmethod&/span&
&span class=&k&&def&/span& &span class=&nf&&create_doc&/span&&span class=&p&&(&/span&&span class=&n&&cls&/span&&span class=&p&&,&/span& &span class=&n&&content&/span&&span class=&p&&):&/span&
&span class=&k&&return&/span& &span class=&p&&{&/span&
&span class=&s1&&'content'&/span&&span class=&p&&:&/span& &span class=&n&&content&/span&&span class=&p&&,&/span&
&span class=&s1&&'created_at'&/span&&span class=&p&&:&/span& &span class=&n&&time&/span&&span class=&p&&(),&/span&
&span class=&s1&&'is_finished'&/span&&span class=&p&&:&/span& &span class=&bp&&False&/span&&span class=&p&&,&/span&
&span class=&s1&&'finished_at'&/span&&span class=&p&&:&/span& &span class=&bp&&None&/span&
&span class=&p&&}&/span&
&span class=&nd&&@app.route&/span&&span class=&p&&(&/span&&span class=&s1&&'/todo'&/span&&span class=&p&&)&/span&
&span class=&k&&def&/span& &span class=&nf&&index&/span&&span class=&p&&():&/span&
&span class=&n&&todos&/span& &span class=&o&&=&/span& &span class=&n&&db&/span&&span class=&o&&.&/span&&span class=&n&&todos&/span&&span class=&o&&.&/span&&span class=&n&&find&/span&&span class=&p&&({})&/span&
&span class=&k&&return&/span& &span class=&n&&dumps&/span&&span class=&p&&(&/span&&span class=&n&&todos&/span&&span class=&p&&)&/span&
&span class=&nd&&@app.route&/span&&span class=&p&&(&/span&&span class=&s1&&'/todo'&/span&&span class=&p&&,&/span& &span class=&n&&methods&/span&&span class=&o&&=&/span&&span class=&p&&[&/span&&span class=&s1&&'POST'&/span&&span class=&p&&])&/span&
&span class=&k&&def&/span& &span class=&nf&&add&/span&&span class=&p&&():&/span&
&span class=&n&&content&/span& &span class=&o&&=&/span& &span class=&n&&request&/span&&span class=&o&&.&/span&&span class=&n&&form&/span&&span class=&o&&.&/span&&span class=&n&&get&/span&&span class=&p&&(&/span&&span class=&s1&&'content'&/span&&span class=&p&&,&/span& &span class=&bp&&None&/span&&span class=&p&&)&/span&
&span class=&k&&if&/span& &span class=&ow&&not&/span& &span class=&n&&content&/span&&span class=&p&&:&/span&
&span class=&n&&abort&/span&&span class=&p&&(&/span&&span class=&mi&&400&/span&&span class=&p&&)&/span&
&span class=&n&&db&/span&&span class=&o&&.&/span&&span class=&n&&todos&/span&&span class=&o&&.&/span&&span class=&n&&insert&/span&&span class=&p&&(&/span&&span class=&n&&Todo&/span&&span class=&o&&.&/span&&span class=&n&&create_doc&/span&&span class=&p&&(&/span&&span class=&n&&content&/span&&span class=&p&&))&/span&
&span class=&k&&return&/span& &span class=&n&&Response&/span&&span class=&p&&()&/span& &span class=&c1&&#200&/span&
&span class=&nd&&@app.route&/span&&span class=&p&&(&/span&&span class=&s1&&'/todo/&tid&/finish'&/span&&span class=&p&&,&/span& &span class=&n&&methods&/span&&span class=&o&&=&/span&&span class=&p&&[&/span&&span class=&s1&&'PUT'&/span&&span class=&p&&])&/span&
&span class=&k&&def&/span& &span class=&nf&&finish&/span&&span class=&p&&(&/span&&span class=&n&&tid&/span&&span class=&p&&):&/span&
&span class=&n&&result&/span& &span class=&o&&=&/span& &span class=&n&&db&/span&&span class=&o&&.&/span&&span class=&n&&todos&/span&&span class=&o&&.&/span&&span class=&n&&update_one&/span&&span class=&p&&(&/span&
&span class=&p&&{&/span&&span class=&s1&&'_id'&/span&&span class=&p&&:&/span& &span class=&n&&ObjectId&/span&&span class=&p&&(&/span&&span class=&n&&tid&/span&&span class=&p&&)},&/span&
&span class=&p&&{&/span&
&span class=&s1&&'$set'&/span&&span class=&p&&:&/span& &span class=&p&&{&/span&
&span class=&s1&&'is_finished'&/span&&span class=&p&&:&/span& &span class=&bp&&True&/span&&span class=&p&&,&/span&
&span class=&s1&&'finished_at'&/span&&span class=&p&&:&/span& &span class=&n&&time&/span&&span class=&p&&()&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&p&&)&/span&
&span class=&k&&if&/span& &span class=&n&&result&/span&&span class=&o&&.&/span&&span class=&n&&matched_count&/span& &span class=&o&&==&/span& &span class=&mi&&0&/span&&span class=&p&&:&/span&
&span class=&n&&abort&/span&&span class=&p&&(&/span&&span class=&mi&&404&/span&&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&n&&Response&/span&&span class=&p&&()&/span&
&span class=&nd&&@app.route&/span&&span class=&p&&(&/span&&span class=&s1&&'/todo/&tid&'&/span&&span class=&p&&,&/span& &span class=&n&&methods&/span&&span class=&o&&=&/span&&span class=&p&&[&/span&&span class=&s1&&'DELETE'&/span&&span class=&p&&])&/span&
&span class=&k&&def&/span& &span class=&nf&&delete&/span&&span class=&p&&(&/span&&span class=&n&&tid&/span&&span class=&p&&):&/span&
&span class=&n&&result&/span& &span class=&o&&=&/span& &span class=&n&&db&/span&&span class=&o&&.&/span&&span class=&n&&todos&/span&&span class=&o&&.&/span&&span class=&n&&delete_one&/span&&span class=&p&&(&/span&
&span class=&p&&{&/span&&span class=&s1&&'_id'&/span&&span class=&p&&:&/span& &span class=&n&&ObjectId&/span&&span class=&p&&(&/span&&span class=&n&&tid&/span&&span class=&p&&)}&/span&
&span class=&p&&)&/span&
&span class=&k&&if&/span& &span class=&n&&result&/span&&span class=&o&&.&/span&&span class=&n&&matched_count&/span& &span class=&o&&==&/span& &span class=&mi&&0&/span&&span class=&p&&:&/span&
&span class=&n&&abort&/span&&span class=&p&&(&/span&&span class=&mi&&404&/span&&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&n&&Response&/span&&span class=&p&&()&/span&
&span class=&k&&if&/span& &span class=&n&&__name__&/span& &span class=&o&&==&/span& &span class=&s1&&'__main__'&/span&&span class=&p&&:&/span&
&span class=&n&&app&/span&&span class=&o&&.&/span&&span class=&n&&run&/span&&span class=&p&&(&/span&&span class=&n&&host&/span&&span class=&o&&=&/span&&span class=&s1&&'0.0.0.0'&/span&&span class=&p&&,&/span& &span class=&n&&port&/span&&span class=&o&&=&/span&&span class=&mi&&8000&/span&&span class=&p&&)&/span&
&/code&&/pre&&/div&&p&这样一来,应用的数据便能持久化到本地了。现在,整个应用看起来是下面这样的:&/p&&br&&figure&&img src=&https://pic3.zhimg.com/v2-0aa027a5a04db7acb94f78_b.jpg& data-rawwidth=&1240& data-rawheight=&205& class=&origin_image zh-lightbox-thumb& width=&1240& data-original=&https://pic3.zhimg.com/v2-0aa027a5a04db7acb94f78_r.jpg&&&/figure&&br&&p&现在往mongodb插入1万条数据。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&import requests
for i in range(10000):
requests.post('http://127.0.0.1:8000/todo', {'content': str(i)})
&/code&&/pre&&/div&&p&获取todo的接口目前是有问题的,因为它一次性把数据库的所有记录都返回了,当数据记录增长到一万条的时候,这个接口的请求就会变的非常慢,需要500ms后才能发出响应。现在对它进行如下的改造:&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&nd&&@app.route&/span&&span class=&p&&(&/span&&span class=&s1&&'/todo'&/span&&span class=&p&&)&/span&
&span class=&k&&def&/span& &span class=&nf&&index&/span&&span class=&p&&():&/span&
&span class=&n&&start&/span& &span class=&o&&=&/span& &span class=&n&&request&/span&&span class=&o&&.&/span&&span class=&n&&args&/span&&span class=&o&&.&/span&&span class=&n&&get&/span&&span class=&p&&(&/span&&span class=&s1&&'start'&/span&&span class=&p&&,&/span& &span class=&s1&&''&/span&&span class=&p&&)&/span&
&span class=&n&&start&/span& &span class=&o&&=&/span& &span class=&nb&&int&/span&&span class=&p&&(&/span&&span class=&n&&start&/span&&span class=&p&&)&/span& &span class=&k&&if&/span& &span class=&n&&start&/span&&span class=&o&&.&/span&&span class=&n&&isdigit&/span&&span class=&p&&()&/span& &span class=&k&&else&/span& &span class=&mi&&0&/span&
&span class=&n&&todos&/span& &span class=&o&&=&/span& &span class=&n&&db&/span&&span class=&o&&.&/span&&span class=&n&&todos&/span&&span class=&o&&.&/span&&span class=&n&&find&/span&&span class=&p&&()&/span&&span class=&o&&.&/span&&span class=&n&&sort&/span&&span class=&p&&([(&/span&&span class=&s1&&'created_at'&/span&&span class=&p&&,&/span& &span class=&o&&-&/span&&span class=&mi&&1&/span&&span class=&p&&)])&/span&&span class=&o&&.&/span&&span class=&n&&limit&/span&&span class=&p&&(&/span&&span class=&mi&&10&/span&&span class=&p&&)&/span&&span class=&o&&.&/span&&span class=&n&&skip&/span&&span class=&p&&(&/span&&span class=&n&&start&/span&&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&n&&dumps&/span&&span class=&p&&(&/span&&span class=&n&&todos&/span&&span class=&p&&)&/span&
&/code&&/pre&&/div&&p&每次只取十条记录,按创建日期排序,先取最新的,用分页的方式获取以往记录。改造后的接口现在只需50ms便能返回响应。&/p&&p&现在对这个接口进行性能测试:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&wrk -c 100 -t 12 -d 5s http://127.0.0.1:8000/todo
Running 5s test @ http://127.0.0.1:8000/todo
12 threads and 100 connections
Thread Stats
220 requests in 5.09s, 338.38KB read
Socket errors: connect 0, read 0, write 0, timeout 87
Requests/sec:
Transfer/sec:
&/code&&/pre&&/div&&p&rps只有43。我们继续进行改进,通过观察我们发现我们查询todo时需要通过created_at这个字段进行排序再过滤,这样以来每次查询都要先对10000条记录进行排序,效率自然变的很低,对于这个场景,可以对created_at这个字段做索引:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&db.todos.ensureIndex({'created_at': -1})
&/code&&/pre&&/div&&p&通过explain我们轻易地看出mongo使用了索引做扫描&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&& db.todos.find().sort({'created_at': -1}).limit(10).explain()
&queryPlanner& : {
&plannerVersion& : 1,
&namespace& : &todo.todos&,
&indexFilterSet& : false,
&parsedQuery& : {},
&winningPlan& : {
&stage& : &LIMIT&,
&limitAmount& : 10,
&inputStage& : {
&stage& : &FETCH&,
&inputStage& : {
&stage& : &IXSCAN&,
&keyPattern& : {
&created_at& : -1.0
&indexName& : &created_at_-1&,
&isMultiKey& : false,
&multiKeyPaths& : {
&created_at& : []
&isUnique& : false,
&isSparse& : false,
&isPartial& : false,
&indexVersion& : 2,
&direction& : &forward&,
&indexBounds& : {
&created_at& : [
&[MaxKey, MinKey]&
&rejectedPlans& : []
&serverInfo& : {
&host& : &841bf506b6ec&,
&port& : 27017,
&version& : &3.4.1&,
&gitVersion& : &5e103c4fd0baacfbd7&
&ok& : 1.0
&/code&&/pre&&/div&&p&现在再做一轮性能测试,有了索引之后就大大降低了排序的成本,rps提高到了298。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&wrk -c 100 -t 12 -d 5s http://127.0.0.1:8000/todo
Running 5s test @ http://127.0.0.1:8000/todo
12 threads and 100 connections
Thread Stats
47.51ms 357.47ms
1511 requests in 5.06s, 2.27MB read
Requests/sec:
Transfer/sec:
&/code&&/pre&&/div&&p&再把重心放到app server上,目前我们使用flask内建的wsgi server,这个server由于是单进程单线程模型的,所以性能很差,一个请求不处理完的话服务器就会阻塞住其他请求,我们需要对这个server做替换。关于python web的app server选择,目前主流采用的有:&/p&&ul&&li&gunicorn&/li&&li&uWSGI&/li&&/ul&&p&我们看&a href=&https://link.zhihu.com/?target=http%3A//www.jianshu.com/p/docs.gunicorn.org/en/latest/design.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&gunicorn&/a&文档可以得知,gunicorn是一个python编写的高效的WSGI HTTP服务器,gunicorn使用pre-fork模型(一个master进程管理多个child子进程),使用gunicorn的方法十分简单:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&gunicorn --workers=9 server:app --bind 127.0.0.1:8000
&/code&&/pre&&/div&&p&根据文档说明使用(2 * cpu核心数量)+1个worker,还要传入一个兼容wsgi app的start up方法,通过Flask的源码可以看到,Flask这个类实现了下面这个接口:&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&
&span class=&k&&def&/span& &span class=&nf&&__call__&/span&&span class=&p&&(&/span&&span class=&bp&&self&/span&&span class=&p&&,&/span& &span class=&n&&environ&/span&&span class=&p&&,&/span& &span class=&n&&start_response&/span&&span class=&p&&):&/span&
&span class=&sd&&&&&Shortcut for :attr:`wsgi_app`.&&&&/span&
&span class=&k&&return&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&wsgi_app&/span&&span class=&p&&(&/span&&span class=&n&&environ&/span&&span class=&p&&,&/span& &span class=&n&&start_response&/span&&span class=&p&&)&/span&
&/code&&/pre&&/div&&p&也就是说我们只需把flask实例的名字传给gunicorn就ok了:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&gunicorn --workers=9 server:app --bind 127.0.0.1:8000
[ 11:20:01 +0800] [5855] [INFO] Starting gunicorn 19.6.0
[ 11:20:01 +0800] [5855] [INFO] Listening at: http://127.0.0.1:)
[ 11:20:01 +0800] [5855] [INFO] Using worker: sync
[ 11:20:01 +0800] [5889] [INFO] Booting worker with pid: 5889
[ 11:20:01 +0800] [5890] [INFO] Booting worker with pid: 5890
[ 11:20:01 +0800] [5891] [INFO] Booting worker with pid: 5891
[ 11:20:01 +0800] [5892] [INFO] Booting worker with pid: 5892
[ 11:20:02 +0800] [5893] [INFO] Booting worker with pid: 5893
[ 11:20:02 +0800] [5894] [INFO] Booting worker with pid: 5894
[ 11:20:02 +0800] [5895] [INFO] Booting worker with pid: 5895
[ 11:20:02 +0800] [5896] [INFO] Booting worker with pid: 5896
[ 11:20:02 +0800] [5897] [INFO] Booting worker with pid: 5897
&/code&&/pre&&/div&&p&可以看到gunicorn启动了9个进程(其中1个父进程)监听请求。使用了多进程的模型看起来是下面这样的:&/p&&br&&figure&&img src=&https://pic1.zhimg.com/v2-7ecc09cd02f41e092605d_b.jpg& data-rawwidth=&1240& data-rawheight=&548& class=&origin_image zh-lightbox-thumb& width=&1240& data-original=&https://pic1.zhimg.com/v2-7ecc09cd02f41e092605d_r.jpg&&&/figure&&br&&p&继续进行性能测试,可以看到吞吐量又有了很大的提升:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&wrk -c 100 -t 12 -d 5s http://127.0.0.1:8000/todo
Running 5s test @ http://127.0.0.1:8000/todo
12 threads and 100 connections
Thread Stats
16.10ms 251.01ms
4373 requests in 5.07s, 6.59MB read
Requests/sec:
Transfer/sec:
&/code&&/pre&&/div&&p&那么gunicorn还能再优化吗,答案是肯定的。回到之前我们发现了这一行:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&[ 11:20:01 +0800] [5855] [INFO] Using worker: sync
&/code&&/pre&&/div&&p&也就是说,gunicorn worker使用的是sync(同步)模式来处理请求,那么它支持async(异步)模式吗,再看gunicorn的文档有下面一段说明:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&Async Workers
The asynchronous workers available are based on Greenlets (via Eventlet and Gevent). Greenlets are an implementation of cooperative multi-threading for Python. In general, an application should be able to make use of these worker classes with no changes.
&/code&&/pre&&/div&&p&gunicorn支持基于greenlet的异步的worker,它使得worker能够协作式地工作。当worker阻塞在外部调用的IO操作时,gunicorn会聪明地把执行调度给其他worker,挂起当前的worker,直至IO操作完成后,被挂起的worker又会重新加入到调度队列中,这样gunicorn便有能力处理大量的并发请求了。&/p&&p&gunicorn有两个不错的async worker:&/p&&ul&&li&meinheld&/li&&li&gevent&/li&&/ul&&p&&a href=&https://link.zhihu.com/?target=https%3A//github.com/mopemope/meinheld& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&meinheld&/a&是一个基于picoev的异步WSGI Web服务器,它可以很轻松地集成到gunicorn中,处理wsgi请求。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&gunicorn --workers=9 --worker-class=&meinheld.gmeinheld.MeinheldWorker& server:app --bind 127.0.0.1:8000
[ 11:47:01 +0800] [7497] [INFO] Starting gunicorn 19.6.0
[ 11:47:01 +0800] [7497] [INFO] Listening at: http://127.0.0.1:)
[ 11:47:01 +0800] [7497] [INFO] Using worker: meinheld.gmeinheld.MeinheldWorker
[ 11:47:01 +0800] [7531] [INFO] Booting worker with pid: 7531
[ 11:47:01 +0800] [7532] [INFO] Booting worker with pid: 7532
[ 11:47:01 +0800] [7533] [INFO] Booting worker with pid: 7533
[ 11:47:01 +0800] [7534] [INFO] Booting worker with pid: 7534
[ 11:47:01 +0800] [7535] [INFO] Booting worker with pid: 7535
[ 11:47:01 +0800] [7536] [INFO] Booting worker with pid: 7536
[ 11:47:01 +0800] [7537] [INFO] Booting worker with pid: 7537
[ 11:47:01 +0800] [7538] [INFO] Booting worker with pid: 7538
[ 11:47:01 +0800] [7539] [INFO] Booting worker with pid: 7539
&/code&&/pre&&/div&&p&可以看到现在使用的是meinheld.gmeinheld.MeinheldWorker这个worker。再进行性能测试看看:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&wrk -c 100 -t 12 -d 5s http://127.0.0.1:8000/todo
Running 5s test @ http://127.0.0.1:8000/todo
12 threads and 100 connections
Thread Stats
39.90ms 354.42ms
5684 requests in 5.04s, 8.59MB read
Requests/sec:
Transfer/sec:
&/code&&/pre&&/div&&p&果然提升了不少。&/p&&p&现在有了app server,那需要nginx之类的web server吗?看看&a href=&https://link.zhihu.com/?targe

我要回帖

更多关于 div转vga 的文章

 

随机推荐