64880.49元在美国支票怎么写上怎么写

&p&我的新课已登陆网易云课堂,如果你已经懂得 PPT 基础操作,想要提升 PPT 设计的水平,欢迎订阅:&a href=&//link.zhihu.com/?target=http%3A//study.163.com/course/introduction/.htm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&PPT设计思维进阶 - 网易云课堂&/a&&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-6bdfb4f78969e2baccee_b.jpg& data-rawwidth=&1600& data-rawheight=&900& class=&origin_image zh-lightbox-thumb& width=&1600& data-original=&https://pic3.zhimg.com/v2-6bdfb4f78969e2baccee_r.jpg&&&/figure&&p&&br&&/p&&p&作为一个PPT发烧友,我也跟大家分享几款办公常用的神器,希望能提升大家的工作效率。&/p&&p&声明一点:&/p&&p&本文与公众号旁门左道(id:pangmenzd)同步更新,未经授权,请勿擅自转载。&/p&&p&如需转载,请联系我本人,微信:shaoyunjiao456&/p&&p&-------------------------------------------&/p&&p&好了,废话不多,开始正题。&/p&&p&先来介绍第一款神器。&/p&&p&做PPT时,我们经常需要用到图片,一张清晰出彩的图片可以为演示增分不少,而往往我们找到一张称心的图片,却发现分辨率过低,插入到PPT中变得模糊,着实令人懊恼。&/p&&p&所以,今天就跟大家分享第一个神器,PHOTOZOOM PRO,就是为解决这个痛点而生的。&b&它的原理是利用插值算法来放大图片,让分辨率较低的图片可以变得很清晰。&/b&&/p&&p&这是软件界面:&/p&&figure&&img src=&https://pic2.zhimg.com/a3be74c3d7524dcd4faf28d_b.png& data-rawwidth=&1227& data-rawheight=&653& class=&origin_image zh-lightbox-thumb& width=&1227& data-original=&https://pic2.zhimg.com/a3be74c3d7524dcd4faf28d_r.png&&&/figure&&p&&br&&/p&&p&给大家举个例子&/p&&p&比如我们要做一份关于长征的PPT,我们在网络上找好了一张素材图片:&/p&&figure&&img src=&https://pic1.zhimg.com/7fe8efa91f6600_b.png& data-rawwidth=&641& data-rawheight=&356& class=&origin_image zh-lightbox-thumb& width=&641& data-original=&https://pic1.zhimg.com/7fe8efa91f6600_r.png&&&/figure&&p&&br&&/p&&p&但这张图只有113KB,插入到PPT中,肯定很小,拉大会变模糊,但我们又非常中意这张图,怎么办呢?&/p&&p&打开PHOTOZOOM PRO这个软件,在放大的尺寸中,你可以调整图片输出的大小,图片会变得很清晰。&/p&&figure&&img src=&https://pic1.zhimg.com/efdada257bb04_b.png& data-rawwidth=&638& data-rawheight=&342& class=&origin_image zh-lightbox-thumb& width=&638& data-original=&https://pic1.zhimg.com/efdada257bb04_r.png&&&/figure&&p&&br&&/p&&p&然后说第二个神器。&/p&&p&&b&这个神器是一款PPT压缩软件,名字叫做PPTMinimizer。&/b&&/p&&p&也许你会说,一款压缩软件有什么厉害的,我电脑上有好几款压缩软件呢!但&b&这个压缩软件的强大之处在于,专门压缩WORD和POWERPOINT文件,压缩率高到吓死人,最高可以达到98%。&/b&&/p&&p&什么意思?举个例子来说吧,一个100M的PPT文件,经过这个神器压缩过之后,会变成2M,你知道这是什么概念吗?&/p&&p&我做了个实验,源文件大小有41.5M:&/p&&figure&&img src=&https://pic3.zhimg.com/09eb7fb78e56cba99baad6_b.png& data-rawwidth=&397& data-rawheight=&494& class=&content_image& width=&397&&&/figure&&p&&br&&/p&&p&压缩后变成了1,74M,我的天哪!&/p&&figure&&img src=&https://pic3.zhimg.com/36be29aca_b.png& data-rawwidth=&393& data-rawheight=&496& class=&content_image& width=&393&&&/figure&&p&&br&&/p&&p&&br&&/p&&p&接下来说第三款神器。&/p&&p&这是一款&b&做PPT时常用的神奇插件,&/b&来拓展PowerPoint软件自身难以实现的功能。&/p&&p&&b&叫做NT插件,官方地址是:&a href=&//link.zhihu.com/?target=http%3A//www.nordritools.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Nordri Tools——让PPT变得简单起来&/a&。&/b&&/p&&figure&&img src=&https://pic1.zhimg.com/1e81f05fc9fe_b.png& data-rawwidth=&1307& data-rawheight=&535& class=&origin_image zh-lightbox-thumb& width=&1307& data-original=&https://pic1.zhimg.com/1e81f05fc9fe_r.png&&&/figure&&p&&br&&/p&&p&简单介绍这款插件吧,有几个功能真的很好用。&/p&&p&比如环形复制:&/p&&figure&&img src=&https://pic1.zhimg.com/b8acd37fad_b.png& data-rawwidth=&1117& data-rawheight=&447& class=&origin_image zh-lightbox-thumb& width=&1117& data-original=&https://pic1.zhimg.com/b8acd37fad_r.png&&&/figure&&p&&br&&/p&&p&还有矩阵复制:&/p&&figure&&img src=&https://pic3.zhimg.com/32b784a3c58b5a7dfbbd6_b.png& data-rawwidth=&1030& data-rawheight=&424& class=&origin_image zh-lightbox-thumb& width=&1030& data-original=&https://pic3.zhimg.com/32b784a3c58b5a7dfbbd6_r.png&&&/figure&&p&&br&&/p&&p&当然也可以翘起来:&/p&&figure&&img src=&https://pic3.zhimg.com/31bee5f2c133ca2e8d543dc1a1dad3f6_b.png& data-rawwidth=&1071& data-rawheight=&418& class=&origin_image zh-lightbox-thumb& width=&1071& data-original=&https://pic3.zhimg.com/31bee5f2c133ca2e8d543dc1a1dad3f6_r.png&&&/figure&&p&&br&&/p&&p&一键裁剪出相同尺寸的图片:&/p&&figure&&img src=&https://pic4.zhimg.com/93ffb6cf0199c5abf07921b_b.png& data-rawwidth=&1058& data-rawheight=&511& class=&origin_image zh-lightbox-thumb& width=&1058& data-original=&https://pic4.zhimg.com/93ffb6cf0199c5abf07921b_r.png&&&/figure&&p&&br&&/p&&p&一键统一PPT中的字体和段落:&/p&&figure&&img src=&https://pic3.zhimg.com/145d0c32_b.png& data-rawwidth=&436& data-rawheight=&415& class=&origin_image zh-lightbox-thumb& width=&436& data-original=&https://pic3.zhimg.com/145d0c32_r.png&&&/figure&&p&&br&&/p&&p&当然,还有很多了,比如一键删除所有动画效果,提供配色方案,导出为长图等等,你们自己安装后可以去一个个尝试。&/p&&p&&br&&/p&&p&接下来说一说第四款神器。&/p&&p&&br&&/p&&p&这是我去年发现,使用到今天才来补充的一款神器。很小众。名字叫做:&a href=&//link.zhihu.com/?target=https%3A//mubu.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&幕布 - 管理你的大脑。&/a&&/p&&p&&br&&/p&&p&大家可以看到,官网界面非常干净。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-00e6c32b9fed_b.png& data-rawwidth=&1240& data-rawheight=&552& class=&origin_image zh-lightbox-thumb& width=&1240& data-original=&https://pic2.zhimg.com/v2-00e6c32b9fed_r.png&&&/figure&&p&&br&&/p&&p&如果这是一款普通的思维导图软件,也就不必推荐了;&/p&&p&如果这是一款普通的清单记录软件,也不用推荐了;&/p&&p&&br&&/p&&p&但是,注意,重点来了,我对幕布的定义是,&b&这是一款兼具清单软件和思维导图软件优点的神器。&/b&&/p&&p&&br&&/p&&p&什么意思呢?就是说,当你写完了文档之后,就像这样:&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-fce6fdc79d33ffb822dacc9ab4f9f394_b.png& data-rawwidth=&1200& data-rawheight=&750& class=&origin_image zh-lightbox-thumb& width=&1200& data-original=&https://pic1.zhimg.com/v2-fce6fdc79d33ffb822dacc9ab4f9f394_r.png&&&/figure&&p&&i&(备注:点下tab键即可将文段分成不同层级)&/i&&/p&&p&&br&&/p&&p&然后,点击右上角的思维导图按钮:&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-e83b89ca7e_b.png& data-rawwidth=&1900& data-rawheight=&899& class=&origin_image zh-lightbox-thumb& width=&1900& data-original=&https://pic1.zhimg.com/v2-e83b89ca7e_r.png&&&/figure&&p&&br&&/p&&p&就可以立即生成可视化的思维导图,让你对文档的全局有一个全新的把控:&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-f50fdff05e33dbf0fbf4302_b.png& data-rawwidth=&1200& data-rawheight=&749& class=&origin_image zh-lightbox-thumb& width=&1200& data-original=&https://pic3.zhimg.com/v2-f50fdff05e33dbf0fbf4302_r.png&&&/figure&&p&&br&&/p&&p&&b&对于文字工作者而言,简直福音&/b&。特此推荐。&/p&&p&&br&&/p&&p&最后说第四个神器。&/p&&p&&b&这是一个文字云制作工具,&/b&&a href=&//link.zhihu.com/?target=https%3A//tagul.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Tagul - Word Cloud Art&/a&,是一个支持中文的文字云生成工具,操作简单,而且方便!不需要翻墙。&/p&&p&这是网站首页:&/p&&figure&&img src=&https://pic4.zhimg.com/4f0ff815cea4ad3f37fdc7dfae8d6f73_b.png& data-rawwidth=&1029& data-rawheight=&601& class=&origin_image zh-lightbox-thumb& width=&1029& data-original=&https://pic4.zhimg.com/4f0ff815cea4ad3f37fdc7dfae8d6f73_r.png&&&/figure&&p&&br&&/p&&p&点击GET STARTED即可开始创建。&/p&&p&这是工作台:&/p&&figure&&img src=&https://pic2.zhimg.com/ee46dc4d605998cadcc69_b.png& data-rawwidth=&958& data-rawheight=&597& class=&origin_image zh-lightbox-thumb& width=&958& data-original=&https://pic2.zhimg.com/ee46dc4d605998cadcc69_r.png&&&/figure&&p&&br&&/p&&p&操作很简单,不认识英语的可以翻译下,都是很基础的单词。&/p&&p&------------------------------------&/p&&p&再补充更新两个网站和两个微博吧:&/p&&p&第一个网站是office官方的模版网站,&a href=&//link.zhihu.com/?target=http%3A//www.officeplus.cn/Template/Home.shtml& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&OfficePLUS,微软Office官方在线模板网站!&/a&&/p&&p&这里面不仅有高质量且免费的PPT模版:&/p&&figure&&img src=&https://pic2.zhimg.com/02b685e6a6c00ef341309_b.png& data-rawwidth=&933& data-rawheight=&555& class=&origin_image zh-lightbox-thumb& width=&933& data-original=&https://pic2.zhimg.com/02b685e6a6c00ef341309_r.png&&&/figure&&p&&br&&/p&&p&还有许多适配PPT页面的高清无码的素材图片:&/p&&figure&&img src=&https://pic3.zhimg.com/e5afefa808469cca69572_b.png& data-rawwidth=&927& data-rawheight=&551& class=&origin_image zh-lightbox-thumb& width=&927& data-original=&https://pic3.zhimg.com/e5afefa808469cca69572_r.png&&&/figure&&p&&br&&/p&&p&当然,这么好的网站,也少不了word和excel模版咯:&/p&&figure&&img src=&https://pic1.zhimg.com/acbce8941bceb06c5be5724_b.png& data-rawwidth=&976& data-rawheight=&472& class=&origin_image zh-lightbox-thumb& width=&976& data-original=&https://pic1.zhimg.com/acbce8941bceb06c5be5724_r.png&&&/figure&&p&&br&&/p&&p&说的够详细了吧!&/p&&p&有喜欢玩微博的朋友也可以关注officeplus官方的微博:&/p&&p&&a href=&//link.zhihu.com/?target=http%3A//weibo.com/msofficeplus%3Ffrom%3Dfeed%26loc%3Dat%26nick%3D%25E5%25BE%25AE%25E8%25BD%25AFOfficePLUS%26is_all%3D1& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&微软OfficePLUS的微博&/a&&/p&&p&也可以关注秋叶的微博,里面有好多PPT相关的活动,因为会有很多人参与,思想碰撞能产生很多不同的启发,也可以关注下:&/p&&p&&a href=&//link.zhihu.com/?target=http%3A//www.weibo.com/qiuyeppt%3Fis_all%3D1& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&秋叶的微博_微博&/a&&/p&&p&(ps:我本人不喜欢玩微博,所以,我自己那10几个粉丝的微博就不推荐了)&/p&&p&再说第二个网站:&a href=&//link.zhihu.com/?target=http%3A//www.iconfont.cn/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Iconfont-阿里巴巴矢量图标库&/a&&/p&&p&这个是阿里巴巴图标素材库,里面的图标素材具有以下特点:数量大,种类全,可自由变换颜色,可选择PNG和AI两种格式。&/p&&figure&&img src=&https://pic2.zhimg.com/486c65d01bea_b.png& data-rawwidth=&1152& data-rawheight=&530& class=&origin_image zh-lightbox-thumb& width=&1152& data-original=&https://pic2.zhimg.com/486c65d01bea_r.png&&&/figure&&p&&br&&/p&&p&比如我搜索一个【牛】的图标:&/p&&figure&&img src=&https://pic3.zhimg.com/2fa7123edbdf9fdead46baa_b.png& data-rawwidth=&1134& data-rawheight=&563& class=&origin_image zh-lightbox-thumb& width=&1134& data-original=&https://pic3.zhimg.com/2fa7123edbdf9fdead46baa_r.png&&&/figure&&p&&br&&/p&&p&选择合适的:&/p&&figure&&img src=&https://pic2.zhimg.com/fd332ebdd9fa5e1522b35afa6b065fc5_b.png& data-rawwidth=&1111& data-rawheight=&596& class=&origin_image zh-lightbox-thumb& width=&1111& data-original=&https://pic2.zhimg.com/fd332ebdd9fa5e1522b35afa6b065fc5_r.png&&&/figure&&p&&br&&/p&&p&这个网站找图标,简直棒极了!&/p&&p&----------------------------------&/p&&p&再更新一个找图片素材的网站吧。&/p&&p&坦白讲,这个网站真是我的大爱,爱到那种不舍得分享的地步,不过看到大家这么热情,就分享出来吧!&/p&&p&网址是:&a href=&//link.zhihu.com/?target=https%3A//pixabay.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Free Images - Pixabay&/a&&/p&&p&这个网站真是为PPT配图的好去处,不仅图片质量高,还支持中文,更关键的一点是还免费,无版权。&/p&&figure&&img src=&https://pic2.zhimg.com/c7dfc1b0c5b7d5f4f3bd_b.png& data-rawwidth=&1345& data-rawheight=&472& class=&origin_image zh-lightbox-thumb& width=&1345& data-original=&https://pic2.zhimg.com/c7dfc1b0c5b7d5f4f3bd_r.png&&&/figure&&p&&br&&/p&&p&给大家几个例子,比如我们搜索【学习】:&/p&&figure&&img src=&https://pic4.zhimg.com/72c55e0a446fb20adea414cd2829ec47_b.png& data-rawwidth=&1339& data-rawheight=&559& class=&origin_image zh-lightbox-thumb& width=&1339& data-original=&https://pic4.zhimg.com/72c55e0a446fb20adea414cd2829ec47_r.png&&&/figure&&p&&br&&/p&&p&下载也很方便:&/p&&figure&&img src=&https://pic4.zhimg.com/5b19f90acef35e1ba36ea473_b.png& data-rawwidth=&1346& data-rawheight=&603& class=&origin_image zh-lightbox-thumb& width=&1346& data-original=&https://pic4.zhimg.com/5b19f90acef35e1ba36ea473_r.png&&&/figure&&p&&br&&/p&&p&用这个网站为PPT找配图,远超百度N多倍!&/p&&p&----------------------------------------------&/p&&p&再来更新一个PPT遥控器工具。&/p&&p&大家都知道,当站在台上进行演讲时,需要根据演讲的节奏来配合着去翻页,一些专业的舞台都会配备PPT翻页笔,大概也就是几十块钱。&/p&&p&但,更多的场合是不会配这个翻页笔的,也就是说,演讲者需要通过鼠标或键盘自行翻页,这就不爽了,那么有没有一款软件可以解决这个问题呢?肯定是有的。&/p&&p&而且这样的软件很多,我曾经搜集过网上很多的工具,但体验都不是很好,没有较大的创新,知道我遇到了百度做的一款翻页工具——PPT遥控器,我顿时觉得,这才是我真正想要的工具,棒极了。&/p&&p&网址是:&a href=&//link.zhihu.com/?target=http%3A//ppt.baidu.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&PPT遥控器&/a&&/p&&figure&&img src=&https://pic2.zhimg.com/f14bbcf99d0fec41a7787889_b.png& data-rawwidth=&1124& data-rawheight=&587& class=&origin_image zh-lightbox-thumb& width=&1124& data-original=&https://pic2.zhimg.com/f14bbcf99d0fec41a7787889_r.png&&&/figure&&p&&br&&/p&&p&&br&&/p&&p&这款软件之所以有亮点,&b&是因为它只需要在电脑端下载即可,&/b&手机上不用再一次下载(市场上其他同类软件需要下载两个客户端)。&/p&&p&当你在电脑下载之后,打开软件,提示你用手机扫码:&/p&&p&&a href=&//link.zhihu.com/?target=http%3A//ap.baidu.com/pptctrl/%3Fid%3D429fad1ff259debc8ad05f%26st%3D_18386& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&ap.baidu.com/pptctrl/?&/span&&span class=&invisible&&id=429fad1ff259debc8ad05f&st=_18386&/span&&span class=&ellipsis&&&/span&&/a& (二维码自动识别)&/p&&p&&br&&/p&&p&扫码后,即可使用:&/p&&figure&&img src=&https://pic4.zhimg.com/cb8bd620acfb_b.png& data-rawwidth=&624& data-rawheight=&536& class=&origin_image zh-lightbox-thumb& width=&624& data-original=&https://pic4.zhimg.com/cb8bd620acfb_r.png&&&/figure&&p&&br&&/p&&p&虽然百度作恶多端,但是这款软件还是很不错的,操作简单,体验也相当不错。&/p&&p&经微信好友李俊告知,又得到神器一枚,&b&名字叫做图片组合。&/b&&/p&&p&&i&顾名思义,这款软件就是可以轻松将很多图片拼接在一起的一个神器。&/i&&/p&&p&不知道你是否看到过这样的PPT:&/p&&figure&&img src=&https://pic4.zhimg.com/bdc2db0e73e8cd3a634bd6b_b.png& data-rawwidth=&852& data-rawheight=&476& class=&origin_image zh-lightbox-thumb& width=&852& data-original=&https://pic4.zhimg.com/bdc2db0e73e8cd3a634bd6b_r.png&&&/figure&&p&&br&&/p&&p&&br&&/p&&p&或是这样的PPT:&/p&&figure&&img src=&https://pic2.zhimg.com/d4a_b.png& data-rawwidth=&853& data-rawheight=&480& class=&origin_image zh-lightbox-thumb& width=&853& data-original=&https://pic2.zhimg.com/d4a_r.png&&&/figure&&p&&br&&/p&&p&按照传统的方式,在一页PPT中整齐地拼接这么多的图片,并且尺寸相同,真的是一件很困难的事情。不信的可以尝试下(由于我曾为多家科技企业做过发布会PPT文件,多次碰到过这样的事情,真的不是件容易的事情)。&/p&&p&但如果你有了这款神器——图片组合,那么这个问题就迎刃而解了。&/p&&p&打开软件界面,会提示你选择相应模版:&/p&&figure&&img src=&https://pic3.zhimg.com/7fb1ed0e9f8a7daec8a2_b.png& data-rawwidth=&639& data-rawheight=&525& class=&origin_image zh-lightbox-thumb& width=&639& data-original=&https://pic3.zhimg.com/7fb1ed0e9f8a7daec8a2_r.png&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/3e9ddc92894caa25d1e68dd190f30784_b.png& data-rawwidth=&639& data-rawheight=&525& class=&origin_image zh-lightbox-thumb& width=&639& data-original=&https://pic1.zhimg.com/3e9ddc92894caa25d1e68dd190f30784_r.png&&&/figure&&p&&br&&/p&&p&选择了模版,会进入这样的界面,你可以对任何参数进行自由调整:&/p&&figure&&img src=&https://pic2.zhimg.com/bc8c5fe582f1_b.png& data-rawwidth=&876& data-rawheight=&662& class=&origin_image zh-lightbox-thumb& width=&876& data-original=&https://pic2.zhimg.com/bc8c5fe582f1_r.png&&&/figure&&p&&br&&/p&&p&操作很简单,认识汉字就能完成相应图片组合。&/p&&p&最后附上好友李俊做的一张案例:&/p&&figure&&img src=&https://pic3.zhimg.com/b93d6c5ed3e3b1180e6ce_b.png& data-rawwidth=&800& data-rawheight=&450& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&https://pic3.zhimg.com/b93d6c5ed3e3b1180e6ce_r.png&&&/figure&&p&&br&&/p&&p&不想自己上网找这款软件的朋友,可以在我的公众号旁门左道(id:pangmenzd)&b&回复关键词【组合】&/b&即可拿到现成的。&/p&&p&&br&&/p&&p&----------------------------------&/p&&p&上面是几款我做PPT时常用到的神器,它们可以大大提升工作效率,对于需要做PPT的朋友来说,称作神器,简直勿容置疑。&/p&&p&注:如果不想自己下载,可以到我的公众号【旁门左道】(id:pangmenzd)&b&回复【神器】&/b&二字,即可拿到。当然,如果你也经常用到PPT,也可以关注我写的其他文章:&/p&&p&今天刚写了一篇,应该每个人做PPT时都会用到:&br&&a href=&https://www.zhihu.com/question//answer/?from=profile_answer_card& class=&internal&&怎样做出优秀的扁平化设计风格 PPT 或 Keynote 幻灯片演示文稿? - 邵云蛟的回答&/a&&/p&&p&&a href=&https://www.zhihu.com/question//answer/?from=profile_answer_card& class=&internal&&PPT 最后一页写什么结束语既得体又能瞬间提升格调? - 邵云蛟的回答&/a&&/p&&p&&br&&/p&&p&再啰嗦一遍,我的新课已登陆网易云课堂,如果你已经懂得 PPT 基础操作,想要提升 PPT 设计的水平,欢迎订阅:&a href=&//link.zhihu.com/?target=http%3A//study.163.com/course/introduction/.htm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&PPT设计思维进阶 - 网易云课堂&/a&&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-6bdfb4f78969e2baccee_b.jpg& data-rawwidth=&1600& data-rawheight=&900& class=&origin_image zh-lightbox-thumb& width=&1600& data-original=&https://pic3.zhimg.com/v2-6bdfb4f78969e2baccee_r.jpg&&&/figure&&p&&br&&/p&&p&号外,今天刚写了一篇新的文章,里面有一些新的,做 ppt 时的知识点,很实用的那种,如果感兴趣,各位可以看看:&a href=&https://www.zhihu.com/question//answer/& class=&internal&&有哪些必备的知识技能? - 知乎&/a&&/p&&p&&br&&/p&&p&以及另外一些所谓的干货文章:&/p&&p&&a href=&https://www.zhihu.com/question//answer/?from=profile_answer_card& class=&internal&&有哪些简单的 PPT、Word 和 Excel 小技巧,可以在工作中省力? - 邵云蛟的回答&/a&&a href=&https://www.zhihu.com/question//answer/& class=&internal&&PPT 模板的下载资源有哪些? - 邵云蛟的回答&/a&&a href=&https://www.zhihu.com/question//answer/& class=&internal&&如何让 PowerPoint 幻灯片「高大上」? - 邵云蛟的回答&/a&&/p&
我的新课已登陆网易云课堂,如果你已经懂得 PPT 基础操作,想要提升 PPT 设计的水平,欢迎订阅: 作为一个PPT发烧友,我也跟大家分享几款办公常用的神器,希望能提升大家的工作效率。声明一点:本文与公众号旁门左道(id:pang…
&p&&b&摘要&/b&&i&:&/i& SystemTap是一个Linux非常有用的调试(跟踪/探测)工具,常用于Linu内核或者应用程序的信息采集,本篇文章介绍其原理、安装、入门、脚本语言及技巧,由阿里云CDN安防专家金九撰写。&/p&&h2&&b&1.简介&/b&&/h2&&figure&&img src=&https://pic3.zhimg.com/v2-828fe7b70a494dc85b189_b.jpg& data-rawwidth=&871& data-rawheight=&103& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic3.zhimg.com/v2-828fe7b70a494dc85b189_r.jpg&&&/figure&&h2&&b&2.何时使用&/b&&/h2&&figure&&img src=&https://pic2.zhimg.com/v2-fc6ce5eac9ba8d2f1afc64a17af18a84_b.jpg& data-rawwidth=&871& data-rawheight=&157& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic2.zhimg.com/v2-fc6ce5eac9ba8d2f1afc64a17af18a84_r.jpg&&&/figure&&p&&br&&/p&&h2&&b&3.原理&/b&&/h2&&p&在网上找了个原理图:&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-dec55ad7146faa4b0d96b7_b.jpg& data-rawwidth=&951& data-rawheight=&766& class=&origin_image zh-lightbox-thumb& width=&951& data-original=&https://pic2.zhimg.com/v2-dec55ad7146faa4b0d96b7_r.jpg&&&/figure&&p&SystemTap的处理流程有5个步骤:解析script文件(parse)、细化(elaborate)、script文件翻译成C语言代码(translate)、编译C语言代码(生成内核模块)(build)、加载内核模块(run)&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-e267fbb7b7cc_b.jpg& data-rawwidth=&516& data-rawheight=&404& class=&origin_image zh-lightbox-thumb& width=&516& data-original=&https://pic1.zhimg.com/v2-e267fbb7b7cc_r.jpg&&&/figure&&h2&&b&4.安装&/b&&/h2&&p&SystemTap依赖的package:&/p&&p&elfutils、gcc、kernel-devel、kernel-debuginfo&/p&&p&如果调用用户态进程,还需要该程序有调试符号,否则无法调试。&/p&&p&推荐使用最新稳定版的SystemTap,目前最新稳定版为:systemtap-2.9.tar.gz&/p&&h2&&b&5.入门&/b&&/h2&&p&&b&5.1 stap命令&/b&&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-ae3e98a92a75fbaeb98e_b.jpg& data-rawwidth=&872& data-rawheight=&231& class=&origin_image zh-lightbox-thumb& width=&872& data-original=&https://pic1.zhimg.com/v2-ae3e98a92a75fbaeb98e_r.jpg&&&/figure&&p&Hello World:&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-30d51d2cdf_b.jpg& data-rawwidth=&871& data-rawheight=&265& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic1.zhimg.com/v2-30d51d2cdf_r.jpg&&&/figure&&p&&b&5.2 staprun命令&/b&&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-9b9bccffe_b.jpg& data-rawwidth=&871& data-rawheight=&33& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic1.zhimg.com/v2-9b9bccffe_r.jpg&&&/figure&&p&stap命令与staprun命令的区别在于:&/p&&p&stap命令的操作对象是stp文件或script命令等,而staprun命令的操作对象是编译生成的内核模块。&/p&&h2&&b&6.脚本语言&/b&&/h2&&p&&b&6.1 probe&/b&&/p&&p&“probe” &=& “探测”, 是SystemTap进行具体地收集数据的关键字。&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-c484c897a84e455d0c93ef592be22143_b.jpg& data-rawwidth=&794& data-rawheight=&215& class=&origin_image zh-lightbox-thumb& width=&794& data-original=&https://pic1.zhimg.com/v2-c484c897a84e455d0c93ef592be22143_r.jpg&&&/figure&&p&“probe point” 是probe动作的时机,也称探测点。也就是probe程序监视的某事件点,一旦侦测的事件触发了,则probe将从此处插入内核或者用户进程中。&/p&&p&“probe handle” 是当probe插入内核或者用户进程后所做的具体动作。&/p&&p&probe用法:&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-71f0e404bee72ad5e67d0_b.jpg& data-rawwidth=&871& data-rawheight=&31& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic2.zhimg.com/v2-71f0e404bee72ad5e67d0_r.jpg&&&/figure&&p&在Hello World例子中begin和end就是probe-point, statement就是该探测点的处理逻辑,在Hello World例子中statement只有一行print,statement可以是复杂的代码块。&/p&&p&探测点语法:&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-05b5acb07fdc1676768e_b.jpg& data-rawwidth=&872& data-rawheight=&337& class=&origin_image zh-lightbox-thumb& width=&872& data-original=&https://pic2.zhimg.com/v2-05b5acb07fdc1676768e_r.jpg&&&/figure&&p&PATTERN语法为:&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-5e7eed7cab210c56b9bb827cc58193a7_b.jpg& data-rawwidth=&870& data-rawheight=&51& class=&origin_image zh-lightbox-thumb& width=&870& data-original=&https://pic1.zhimg.com/v2-5e7eed7cab210c56b9bb827cc58193a7_r.jpg&&&/figure&&p&例如:&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-d5187d44aafbf420e1c7cfe_b.jpg& data-rawwidth=&871& data-rawheight=&87& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic4.zhimg.com/v2-d5187d44aafbf420e1c7cfe_r.jpg&&&/figure&&p&在return探测点可以用\$return获取该函数的返回值。&/p&&p&inline函数无法安装.return探测点,也无法用$return获取其返回值。&/p&&p&&b&6.2 基本语法&/b&&/p&&p&SystemTap脚本语法比较简单,与C语言类似,只是每一行结尾&;&是可选的。主要语句如下:&/p&&p&if/else、while、for/foreach、break/continue、return、next、delete、try/catch&/p&&p&其中:&/p&&p&next:主要在probe探测点逻辑处理中使用,调用此语句时,立刻从调用函数中退出。不同于exit()的是,next只是退出当前的调用函数,而此SystemTap并没有终了,但exit()则会终止SystemTap。&/p&&p&&b&6.2.1 变量&/b&&/p&&p&不需要明确声明变量类型,脚本语言会根据函数参数等自动判断变量是什么类型的。&/p&&p&局部变量:在声明的probe和block(”{ }“范围内的部分)内有效。&/p&&p&全局变量:用”global“声明的变量,在此SystemTap的整个动作过程中都有效。全局变量的声明位置没有具体要求。需要注意的是,全局变量默认有锁保护,使用过多会有性能损失,如果用全局变量保存指针,可能出现指针所指的内容被进程修改,在探测点中拿不到真正的数据。&/p&&p&获取进程中的变量(全局变量、局部变量、参数)直接在变量名前面加$即可(后面会有例子)&/p&&p&&b&6.2.2 注释&/b&&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-bdb76f703994bac53c6ac_b.jpg& data-rawwidth=&870& data-rawheight=&69& class=&origin_image zh-lightbox-thumb& width=&870& data-original=&https://pic4.zhimg.com/v2-bdb76f703994bac53c6ac_r.jpg&&&/figure&&p&&b&6.2.3 操作符&/b&&/p&&p&比较运算符、算数运算符基本上与C语言一样,需要特别指出的是:&/p&&p&(1)、.操作符:连接两个字符串,类似于php;&/p&&p&(2)、=~和!~:正则匹配和正则不匹配;&/p&&p&&b&6.2.4 函数&/b&&/p&&p&函数定义例子:&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-aaee679c53cd79b1805b_b.jpg& data-rawwidth=&871& data-rawheight=&284& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic3.zhimg.com/v2-aaee679c53cd79b1805b_r.jpg&&&/figure&&p&官方有很多很有用的函数,详情请参考:&a href=&https://link.zhihu.com/?target=https%3A//sourceware.org/systemtap/tapsets/%3Fspm%3D.blogcont.632Iqx& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&https://sourceware.org/systemtap/tapsets/&/a&&/p&&p&以及在本机安装了SystemTap之后在目录/usr/local/share/systemtap/tapset/下也可以看具体函数的实现以及一些奇特的用法。&/p&&h2&&b&7.技巧&/b&&/h2&&p&&b&7.1 定位函数位置&/b&&/p&&p&在一个大型项目中找出函数在哪里定义有时很有用,特别是一些比较难找出在哪里定义的函数,比如内核或者glibc中的某个函数想要看其实现时,首先得找出其在哪个文件的哪一行定义,用SystemTap一行命令就可以搞定。&/p&&p&比如要看printf在glibc中哪里定义的:&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-6f3cab6c2d3b5a15e298_b.jpg& data-rawwidth=&872& data-rawheight=&50& class=&origin_image zh-lightbox-thumb& width=&872& data-original=&https://pic4.zhimg.com/v2-6f3cab6c2d3b5a15e298_r.jpg&&&/figure&&p&可以看出printf是在printf.c第29行定义的。&/p&&p&再比如要看内核中recv系统的调用是在哪里定义的:&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-f6ab335ce82b69ef6388494_b.jpg& data-rawwidth=&873& data-rawheight=&50& class=&origin_image zh-lightbox-thumb& width=&873& data-original=&https://pic1.zhimg.com/v2-f6ab335ce82b69ef6388494_r.jpg&&&/figure&&p&可以看出recv是在socket.c第1868行定义的。&/p&&p&甚至可以*号来模糊查找:&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-8cbf64ce8aab6eabb00218_b.jpg& data-rawwidth=&871& data-rawheight=&266& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic3.zhimg.com/v2-8cbf64ce8aab6eabb00218_r.jpg&&&/figure&&p&同理,也可以用来定位用户进程的函数位置:&/p&&p&比如tengine的文件ngx_shmem.c里面为了兼容各个操作系统而实现了三个版本的ngx_shm_alloc,用#if (NGX_HAVE_MAP_ANON)、#elif (NGX_HAVE_MAP_DEVZERO)、#elif (NGX_HAVE_SYSVSHM)、#endif来做条件编译,那怎么知道编译出来的是哪个版本呢,用SystemTap的话就很简单了,否则要去grep一下这几宏有没有定义才知道了。&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-2c766d258baabebde50d43_b.jpg& data-rawwidth=&870& data-rawheight=&48& class=&origin_image zh-lightbox-thumb& width=&870& data-original=&https://pic1.zhimg.com/v2-2c766d258baabebde50d43_r.jpg&&&/figure&&p&&b&7.2 查看可用探测点以及该探测点上可用的变量&/b&&/p&&p&在一些探测点上能获取的变量比较有限,这是因为这些变量可能已经被编译器优化掉了,优化掉的变量就获取不到了。一般先用-L参数来看看有哪些变量可以直接使用:&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-61dd72bb0aef_b.jpg& data-rawwidth=&870& data-rawheight=&50& class=&origin_image zh-lightbox-thumb& width=&870& data-original=&https://pic3.zhimg.com/v2-61dd72bb0aef_r.jpg&&&/figure&&p&可见在该探测点上可以直接使用$shm这个变量,其类型是ngx_shm_t*。&/p&&p&statement探测点也类似:&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-bfd25fa117d_b.jpg& data-rawwidth=&871& data-rawheight=&159& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic1.zhimg.com/v2-bfd25fa117d_r.jpg&&&/figure&&p&&b&7.3 输出调用堆栈&/b&&/p&&p&用户态探测点堆栈:print_ubacktrace()、sprint_ubacktrace()&/p&&p&内核态探测点堆栈:print_backtrace()、sprint_backtrace()&/p&&p&不带s和带s的区别是前者直接输出,后者是返回堆栈字符串。&/p&&p&这几个函数非常有用,在排查问题时可以根据一些特定条件来过滤函数被执行时是怎么调用进来的,比如排查tengine返回5xx时的调用堆栈是怎样的:&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-56fe3493a_b.jpg& data-rawwidth=&871& data-rawheight=&446& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic4.zhimg.com/v2-56fe3493a_r.jpg&&&/figure&&p&比如看看内核是怎么收包的:&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-d3c908cbedf97de112acb49d5e1aeb2e_b.jpg& data-rawwidth=&870& data-rawheight=&356& class=&origin_image zh-lightbox-thumb& width=&870& data-original=&https://pic3.zhimg.com/v2-d3c908cbedf97de112acb49d5e1aeb2e_r.jpg&&&/figure&&p&&b&7.4 获取函数参数&/b&&/p&&p&一些被编译器优化掉的函数参数用-L去看的时候没有找到,这样的话在探测点里面也不能直接用$方式获取该参数变量,这时可以使用SystemTap提供的*_arg函数接口,*是根据类型指定的,比如pointer_arg是获取指针类型参数,int_arg是获取整型参数,类似的还有long_arg、longlong_arg、uint_arg、ulong_arg、ulonglong_arg、s32_arg、s64_arg、u32_arg、u64_arg:&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-d4d4adbd628bcfa_b.jpg& data-rawwidth=&667& data-rawheight=&98& class=&origin_image zh-lightbox-thumb& width=&667& data-original=&https://pic1.zhimg.com/v2-d4d4adbd628bcfa_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-107b3bd41d87835eac156_b.jpg& data-rawwidth=&870& data-rawheight=&285& class=&origin_image zh-lightbox-thumb& width=&870& data-original=&https://pic4.zhimg.com/v2-107b3bd41d87835eac156_r.jpg&&&/figure&&p&再比如两个函数的函数参数类型兼容也可以使用这种方法获取:&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-57fbcb32166ddfda6c0e441f_b.jpg& data-rawwidth=&672& data-rawheight=&63& class=&origin_image zh-lightbox-thumb& width=&672& data-original=&https://pic4.zhimg.com/v2-57fbcb32166ddfda6c0e441f_r.jpg&&&/figure&&p&&br&&/p&&p&这两个函数的参数完全兼容,只是第二个参数命名不一样而已,可以像下面这么用:&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-82c4acfd5c5afa778be50ac34f9d995d_b.jpg& data-rawwidth=&871& data-rawheight=&177& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic4.zhimg.com/v2-82c4acfd5c5afa778be50ac34f9d995d_r.jpg&&&/figure&&p&&b&7.5 获取全局变量&/b&&/p&&p&有时候用$可以直接获取到全局变量,但有时候又获取不到,那可以试试@var:&/p&&p&比如获取nginx的全局变量ngx_cycyle:&/p&&p&&br&&/p&&figure&&img src=&https://pic6.zhimg.com/v2-0eaea34f96f1bfeb698f_b.jpg& data-rawwidth=&870& data-rawheight=&518& class=&origin_image zh-lightbox-thumb& width=&870& data-original=&https://pic6.zhimg.com/v2-0eaea34f96f1bfeb698f_r.jpg&&&/figure&&p&&b&7.6 获取数据结构成员用法&/b&&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-dff51d58a8f4e_b.jpg& data-rawwidth=&870& data-rawheight=&282& class=&origin_image zh-lightbox-thumb& width=&870& data-original=&https://pic2.zhimg.com/v2-dff51d58a8f4e_r.jpg&&&/figure&&p&上面这个是nginx里面的http请求结构里面的几个成员,在C语言里,如果r是struct ngx_http_request_t *,那么要获取uri的data是这样的:r-&uri.data,但在SystemTap里面,不管是指针还是数据结构,都是用-&访问其成员:&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-008d1ef5ebe29cae2acb4e_b.jpg& data-rawwidth=&871& data-rawheight=&570& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic2.zhimg.com/v2-008d1ef5ebe29cae2acb4e_r.jpg&&&/figure&&p&&b&7.7 输出整个数据结构&/b&&/p&&p&SystemTap有两个语法可以输出整个数据结构:在变量的后面加一个或者两个&/p&&p&$即可,例子如下:&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-f837b0ce6fedeceb41eef_b.jpg& data-rawwidth=&872& data-rawheight=&159& class=&origin_image zh-lightbox-thumb& width=&872& data-original=&https://pic4.zhimg.com/v2-f837b0ce6fedeceb41eef_r.jpg&&&/figure&&p&其中r-&pool的结构如下:&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-fbff482d2babe01bed088_b.jpg& data-rawwidth=&872& data-rawheight=&373& class=&origin_image zh-lightbox-thumb& width=&872& data-original=&https://pic3.zhimg.com/v2-fbff482d2babe01bed088_r.jpg&&&/figure&&p&ngx_pool_s包含了结构ngx_pool_data_t。变量后面加和$的区别是后者展开了里面的结构而前者不展开,此用法只输出基本数据类型的值。&/p&&p&&b&7.8 输出字符串指针&/b&&/p&&p&用户态使用:user_string、user_string_n&/p&&p&内核态使用:kernel_string、kernel_string_n、user_string_quoted&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-c8a605c6f3008edacc89_b.jpg& data-rawwidth=&872& data-rawheight=&174& class=&origin_image zh-lightbox-thumb& width=&872& data-original=&https://pic4.zhimg.com/v2-c8a605c6f3008edacc89_r.jpg&&&/figure&&p&user_string_quoted是获取用户态传给内核的字符串,代码中一般有__user宏标记:&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-fb3d8f3b9d894aa0ae6add4_b.jpg& data-rawwidth=&662& data-rawheight=&105& class=&origin_image zh-lightbox-thumb& width=&662& data-original=&https://pic2.zhimg.com/v2-fb3d8f3b9d894aa0ae6add4_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-f62ebccbba208_b.jpg& data-rawwidth=&868& data-rawheight=&175& class=&origin_image zh-lightbox-thumb& width=&868& data-original=&https://pic2.zhimg.com/v2-f62ebccbba208_r.jpg&&&/figure&&p&&b&7.9 指针类型转换&/b&&/p&&p&SystemTap提供@cast来实现指针类型转换,比如可以将void *转成自己需要的类型:&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-faa89acf5ee0e2a82354b77f_b.jpg& data-rawwidth=&492& data-rawheight=&113& class=&origin_image zh-lightbox-thumb& width=&492& data-original=&https://pic3.zhimg.com/v2-faa89acf5ee0e2a82354b77f_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-8e5fee47f1b6ded5a510e_b.jpg& data-rawwidth=&455& data-rawheight=&181& class=&origin_image zh-lightbox-thumb& width=&455& data-original=&https://pic1.zhimg.com/v2-8e5fee47f1b6ded5a510e_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-621f9b37b41c8e748a610d3b4363e3ea_b.jpg& data-rawwidth=&869& data-rawheight=&228& class=&origin_image zh-lightbox-thumb& width=&869& data-original=&https://pic3.zhimg.com/v2-621f9b37b41c8e748a610d3b4363e3ea_r.jpg&&&/figure&&p&&b&7.10 定义某个类型的变量&/b&&/p&&p&同样是用@cast,定义一个变量用来保存其转换后的地址即可,用法如下:&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-acd0ab880d482e4dd1d281dacd6324db_b.jpg& data-rawwidth=&871& data-rawheight=&211& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic4.zhimg.com/v2-acd0ab880d482e4dd1d281dacd6324db_r.jpg&&&/figure&&p&&b&7.11 多级指针用法&/b&&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-3dca8610b7b_b.jpg& data-rawwidth=&871& data-rawheight=&589& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic1.zhimg.com/v2-3dca8610b7b_r.jpg&&&/figure&&p&简言之:通过[0]去解引用即可。&/p&&p&&b&7.12 遍历C语言数组&/b&&/p&&p&下面是在nginx处理请求关闭时遍历请求头的例子:&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-d3d1cd541378fbb2c8d94c320ef7723a_b.jpg& data-rawwidth=&870& data-rawheight=&446& class=&origin_image zh-lightbox-thumb& width=&870& data-original=&https://pic4.zhimg.com/v2-d3d1cd541378fbb2c8d94c320ef7723a_r.jpg&&&/figure&&p&&b&7.13 查看函数指针所指的函数名&/b&&/p&&p&获取一个地址所对应的符号:&/p&&p&用户态:usymname&/p&&p&内核态:symname&/p&&figure&&img src=&https://pic1.zhimg.com/v2-cd63e9a9af14d1acac812_b.jpg& data-rawwidth=&870& data-rawheight=&176& class=&origin_image zh-lightbox-thumb& width=&870& data-original=&https://pic1.zhimg.com/v2-cd63e9a9af14d1acac812_r.jpg&&&/figure&&p&&b&7.14 修改进程中的变量&/b&&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-16f6d0f056e4ddcaa77fc7_b.jpg& data-rawwidth=&872& data-rawheight=&434& class=&origin_image zh-lightbox-thumb& width=&872& data-original=&https://pic2.zhimg.com/v2-16f6d0f056e4ddcaa77fc7_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-1fcf44ac5bf494e129f2_b.jpg& data-rawwidth=&869& data-rawheight=&285& class=&origin_image zh-lightbox-thumb& width=&869& data-original=&https://pic4.zhimg.com/v2-1fcf44ac5bf494e129f2_r.jpg&&&/figure&&p&可以看出在第17行用SystemTap修改后的值在第19行就生效了。&/p&&p&需要注意的是stap要加-g参数在guru模式下才能修改变量的值。&/p&&p&&b&7.15 跟踪进程执行流程&/b&&/p&&p&thread_indent(n): 补充空格&/p&&p&ppfunc(): 当前探测点所在的函数&/p&&p&在call探测点调用thread_indent(4)补充4个空格,在return探测点调用thread_indent(-4)回退4个空格,效果如下:&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-dbdef5744ff2d_b.jpg& data-rawwidth=&870& data-rawheight=&548& class=&origin_image zh-lightbox-thumb& width=&870& data-original=&https://pic4.zhimg.com/v2-dbdef5744ff2d_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-e03f8a243aaad9eedc837ed9aff5beb3_b.jpg& data-rawwidth=&869& data-rawheight=&315& class=&origin_image zh-lightbox-thumb& width=&869& data-original=&https://pic2.zhimg.com/v2-e03f8a243aaad9eedc837ed9aff5beb3_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-98976c01bba2b21bcabffec_b.jpg& data-rawwidth=&872& data-rawheight=&271& class=&origin_image zh-lightbox-thumb& width=&872& data-original=&https://pic3.zhimg.com/v2-98976c01bba2b21bcabffec_r.jpg&&&/figure&&p&&b&7.16 查看代码执行路径&/b&&/p&&p&pp(): 输出当前被激活的探测点&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-fee18fa70ae24e691f7a14_b.jpg& data-rawwidth=&870& data-rawheight=&445& class=&origin_image zh-lightbox-thumb& width=&870& data-original=&https://pic2.zhimg.com/v2-fee18fa70ae24e691f7a14_r.jpg&&&/figure&&p&可以看出该函数哪些行被执行了。&/p&&p&&b&7.17 巧用正则匹配过滤&/b&&/p&&p&在排查问题时,可以利用一些正则匹配来获取自己想要的信息,比如下面是只收集*.&a href=&https://link.zhihu.com/?target=http%3A//j9.com& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&j9.com&/span&&span class=&invisible&&&/span&&/a&的堆栈:&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-9be4ef84ebe7d45ff14354_b.jpg& data-rawwidth=&871& data-rawheight=&420& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic2.zhimg.com/v2-9be4ef84ebe7d45ff14354_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-9fc12efb0c215c382f5e422a_b.jpg& data-rawwidth=&872& data-rawheight=&517& class=&origin_image zh-lightbox-thumb& width=&872& data-original=&https://pic2.zhimg.com/v2-9fc12efb0c215c382f5e422a_r.jpg&&&/figure&&p&&b&7.18 关联数组用法&/b&&/p&&p&SystemTap的关联数组必须是全局变量,需要用global进行声明,其索引可以支持多达9项索引域,各域间以逗号隔开。支持 =, ++ 与 +=操作,其默认的初始值为0。&/p&&p&例如:&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-169ae8d504f297dfa53d896e18bf7d1f_b.jpg& data-rawwidth=&872& data-rawheight=&608& class=&origin_image zh-lightbox-thumb& width=&872& data-original=&https://pic3.zhimg.com/v2-169ae8d504f297dfa53d896e18bf7d1f_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-a1a3b972c3f5fcc09fc5cea581ca34a3_b.jpg& data-rawwidth=&870& data-rawheight=&607& class=&origin_image zh-lightbox-thumb& width=&870& data-original=&https://pic1.zhimg.com/v2-a1a3b972c3f5fcc09fc5cea581ca34a3_r.jpg&&&/figure&&p&&b&7.19 调试内存泄漏以及内存重复释放&/b&&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-7f8a0f613af222df8df5acf_b.jpg& data-rawwidth=&872& data-rawheight=&515& class=&origin_image zh-lightbox-thumb& width=&872& data-original=&https://pic4.zhimg.com/v2-7f8a0f613af222df8df5acf_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-0a1fc3a9a606b43eb1614201bcd37a4c_b.jpg& data-rawwidth=&868& data-rawheight=&370& class=&origin_image zh-lightbox-thumb& width=&868& data-original=&https://pic4.zhimg.com/v2-0a1fc3a9a606b43eb1614201bcd37a4c_r.jpg&&&/figure&&p&详细请看:&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/wangzuxi/article/details/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&blog.csdn.net/wangzuxi/&/span&&span class=&invisible&&article/details/&/span&&span class=&ellipsis&&&/span&&/a&&/p&&p&&b&7.20 嵌入C代码&/b&&/p&&p&在进程fork出子进程时打印出进程id和进程名:&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-eb777920fdc95758b38fd_b.jpg& data-rawwidth=&871& data-rawheight=&572& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic2.zhimg.com/v2-eb777920fdc95758b38fd_r.jpg&&&/figure&&p&&b&有三个需要注意的地方:&/b&&/p&&p&1)、SystemTap脚本里面嵌入C语言代码要在每个大括号前加%前缀,是%{…… %} 而不是%{ …… }%;&/p&&p&2)、获取脚本函数参数要用STAP_ARG_前缀;&/p&&p&3)、一般long等返回值用STAP_RETURN,而string类型返回值要用snprintf、strncat等方式把字符串复制到STAP_RETVALUE里面。&/p&&p&&b&7.21 调试内核模块&/b&&/p&&p&这小节就不细讲了,这篇博客 (&a href=&https://link.zhihu.com/?target=http%3A//blog.chinaunix.net/uid--id-4726046.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&blog.chinaunix.net/uid-&/span&&span class=&invisible&&-id-4726046.html&/span&&span class=&ellipsis&&&/span&&/a&) 写得很详细,这里只copy两个关键点过来记录一下:&/p&&p&要调试自己的内核模块,需要注意的有两个关键点:&/p&&p&1)、使用SystemTap调试内核模块,探测点的编写格式示例:&/p&&p&module(&ext3&).function(&ext3_*&)&/p&&p&2)、需要将自己的模块cp到/lib/modules/uname -r/extra目录中,否则找不到符号,如果/lib/modules/uname -r/目录下没有extra这个目录,自己mkdir一下就可以。&/p&&p&&b&7.22 一些错误提示及解决办法&/b&&/p&&p&错误提示1:&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-7e39f0cbc4_b.jpg& data-rawwidth=&871& data-rawheight=&50& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic4.zhimg.com/v2-7e39f0cbc4_r.jpg&&&/figure&&p&解决办法:&/p&&p&加上stap参数:-DMAXACTION=102400,如果还报这种类型的错误,只需把102400调成更大的值即可。&/p&&p&错误提示2:&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-940ce20cf24d85816a49fad0_b.jpg& data-rawwidth=&871& data-rawheight=&31& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&https://pic4.zhimg.com/v2-940ce20cf24d85816a49fad0_r.jpg&&&/figure&&p&解决办法:&/p&&p&加上-DMAXSKIPPED=102400和-DSTP_NO_OVERLOAD参数&/p&&p&还有一些可以去掉限制的宏:&/p&&p&MAXSTRINGLEN:这个宏会影响sprintf的buffer大小,默认为512字节。&/p&&p&MAXTRYLOCK:对全局变量进行try lock操作的次数,超过则次数还拿不到锁则放弃和跳过该探测点,默认值为1000.全局变量多的时候可以把这个宏开大一点。&/p&&p&(完)&/p&&p&原文链接:&a href=&https://link.zhihu.com/?target=http%3A//click.aliyun.com/m/28902/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【技术干货】听阿里云CDN安防技术专家金九讲SystemTap使用技巧-博客-云栖社区-阿里云&/a&&/p&&h2&&b&更多技术干货敬请关注云栖社区知乎机构号:&a href=&https://www.zhihu.com/org/a-li-yun-yun-qi-she-qu-48& class=&internal&&阿里云云栖社区 - 知乎&/a&&/b&&/h2&
摘要: SystemTap是一个Linux非常有用的调试(跟踪/探测)工具,常用于Linu内核或者应用程序的信息采集,本篇文章介绍其原理、安装、入门、脚本语言及技巧,由阿里云CDN安防专家金九撰写。1.简介2.何时使用 3.原理在网上找了个原理图: SystemTap的处理流程…
楼主的问题只能针对具体JVM实现来回答,在JVM规范里是没有规定的——具体实现用1:1(内核线程)、N:1(用户态线程)、M:N(混合)模型的任何一种都完全OK。Java并不暴露出不同线程模型的区别,上层应用是感知不到差异的(只是性能特性会不太一样…)&br&&br&Java SE最常用的JVM是Oracle/Sun研发的HotSpot VM。在这个JVM的较新版本所支持的所有平台上,它都是使用1:1线程模型的——除了Solaris之外,它是个特例。&br&&br&这是HotSpot VM在Solaris上所支持的线程模型:&a href=&//link.zhihu.com/?target=http%3A//www.oracle.com/technetwork/java/threads-140302.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Java(TM) and Solaris(TM) Threading&/a&&br&&- 可以看到HotSpot VM在Solaris上支持M:N和1:1模型。当前默认是用1:1模型。&br&&br&前面的回答里大家提到的“肯定不是用户态线程,不然怎么利用多核”、“多线程优势何在”,这些问题在使用N:1、M:N模型的JVM实现上确实存在。&br&&br&我喜欢用的一个例子是Oracle/Sun的另一个JVM实现,用于Java ME CLDC的CLDC HotSpot Implementation(CLDC-HI)。它支持两种线程模型,默认使用N:1线程模型,所有Java线程都映射到一个内核线程上,是典型的用户态线程模型;它也可以使用一种特殊的混合模型,Java线程仍然全部映射到一个内核线程上,但当Java线程要执行一个阻塞调用时,CLDC-HI会为该调用单独开一个内核线程,并且调度执行其它Java线程,等到那个阻塞调用完成之后再重新调度之前的Java线程继续执行。&br&有权限访问到的同学可以去读读CLDC HotSpot Implementation Architecture Guide(百度文库有对应CLDC-HI 2.0的版本:&a href=&//link.zhihu.com/?target=http%3A//wenku.baidu.com/view/2a0c7fb069dc5022aaea00f3.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CLDC-Hotspot-Architecture_百度文库&/a&),里面的第5章介绍了CLDC-HI的线程模型,下面引用部分内容过来:&br&&br&&blockquote&The system has two distinct threading models. &b&The simplest and preferred model supports LWTs (light weight threads). In this model, CLDC HotSpot Implementation implements all LWTs on a single native OS thread.&/b& LWTs are essentially co-routines created and scheduled by the virtual machine. This is transparent at the Java runtime environment level.&br&...&br&A special style of handling threading might be preferable in some ports. This style relies on the availability of native thread support in the target platform OS. It is called &b&hybrid threading&/b&, ...&/blockquote&然后在另一份文档,CLDC HotSpot Implementation Porting Guide的第4章里介绍了如何移植CLDC-HI的线程系统到别的平台。&a href=&//link.zhihu.com/?target=http%3A//elastos.org& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&elastos.org&/span&&span class=&invisible&&&/span&&/a&有一份CLDC-HI 1.1.3版本的:&a href=&//link.zhihu.com/?target=http%3A//elastos.org/elorg_files/FreeBooks/java/thesis/CLDC-Hotspot-Port.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&elastos.org/elorg_files&/span&&span class=&invisible&&/FreeBooks/java/thesis/CLDC-Hotspot-Port.pdf&/span&&span class=&ellipsis&&&/span&&/a&。同样摘抄一小段描述出来:&br&&blockquote&&b&Non-blocking scheduling&/b& - The native method de-schedules its lightweight&br&thread (LWT) until another part of the virtual machine determines that the native&br&method can be executed without blocking. Then the native method is reentered to&br&proceed with the given problematic call that is now guaranteed to be of&br&sufficiently short duration.&br&&b&Hybrid threading&/b& - The native method de-schedules its LWT after delegating the&br&task to an OS thread to execute the given blocking call. When this OS thread,&br&which is truly concurrent to the rest of the virtual machine, completes the call, it&br&causes the LWT to resume. The LWT then reenters the native method to fetch the&br&results of the blocking call.&br&...&br&If you port to another platform, it might be the case that only one of the styles can be&br&implemented. Non-blocking scheduling depends on the existence of functions that&br&can determine whether a subsequent call would block. Take for example the&br&select() function for BSD sockets that can be used to determine whether a socket&br&is ready for a non-blocking data transmission call. Hybrid threading requires that&br&several OS threads are available and that all the blocking OS calls that you want to&br&employ are reentrant.&/blockquote&&br&可见,使用用户态线程是会有潜在的并行瓶颈问题,但也有(一定程度的)解决办法。
楼主的问题只能针对具体JVM实现来回答,在JVM规范里是没有规定的——具体实现用1:1(内核线程)、N:1(用户态线程)、M:N(混合)模型的任何一种都完全OK。Java并不暴露出不同线程模型的区别,上层应用是感知不到差异的(只是性能特性会不太一样…) Java S…
&figure&&img src=&https://pic2.zhimg.com/v2-9e09d1aa4ebfbff29cb095_b.jpg& data-rawwidth=&546& data-rawheight=&546& class=&origin_image zh-lightbox-thumb& width=&546& data-original=&https://pic2.zhimg.com/v2-9e09d1aa4ebfbff29cb095_r.jpg&&&/figure&&p&&strong&下载:&/strong& &a href=&https://link.zhihu.com/?target=https%3A//www.microsoft.com/en-us/download/details.aspx%3Fid%3D35460& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Microsoft Garage Mouse without Borders&/a&&/p&&p&今天推荐的软件叫做&strong&无界鼠标&/strong&(Mouse without Borders),微软官方出品,主要功能是实现一套鼠标键盘控制局域网中最多4台电脑,除了支持键鼠操作,还支持不同电脑间文件拷贝与剪切板共享。&/p&&p&下面说说安装说明,以两台电脑为例。 &/p&&p&局域网控制嘛,当然得有控制端(&u&服务端&/u&)和被控制端(&u&客户端&/u&)&/p&&h2&&strong&一、服务端安装配置:&/strong&&/h2&&p&&strong& 1、双击安装文件,各种下一步后,出现如下界面,点击NO。&/strong&&/p&&p&&strong&&figure&&img src=&https://pic4.zhimg.com/v2-aab4dbe733d_b.jpg& data-rawwidth=&477& data-rawheight=&439& class=&origin_image zh-lightbox-thumb& width=&477& data-original=&https://pic4.zhimg.com/v2-aab4dbe733d_r.jpg&&&/figure&2、然后出现如下界面,记住security code和电脑名字。&/strong&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-7db9f13c893d4522b38efa59fe9fb9d7_b.jpg& data-rawwidth=&477& data-rawheight=&439& class=&origin_image zh-lightbox-thumb& width=&477& data-original=&https://pic2.zhimg.com/v2-7db9f13c893d4522b38efa59fe9fb9d7_r.jpg&&&/figure&&br&&h2&&strong&二、客户端安装配置:&/strong&&/h2&&br&&b&1、客户电脑也是双击同样安装文件,各种下一步后,出现如下界面,点击YES。&br&&/b&&figure&&img src=&https://pic7.zhimg.com/v2-f3cef0ade723e_b.jpg& data-rawwidth=&477& data-rawheight=&439& class=&origin_image zh-lightbox-thumb& width=&477& data-original=&https://pic7.zhimg.com/v2-f3cef0ade723e_r.jpg&&&/figure&&b&2、输入服务端的security code和电脑名字,点击LINK即可搞定。&/b&&figure&&img src=&https://pic1.zhimg.com/v2-8e448ed5a386f4f041990_b.jpg& data-rawwidth=&477& data-rawheight=&382& class=&origin_image zh-lightbox-thumb& width=&477& data-original=&https://pic1.zhimg.com/v2-8e448ed5a386f4f041990_r.jpg&&&/figure&&br&&p&&u&然后就会发现鼠标,在两个电脑之间滑动(相当于拓展屏幕),文件复制也是拖拽到另一台电脑即可。&/u&&/p&&p&好了,点到为止,更多有趣的东西还是自己体会与发现吧!&/p&&br&&p&&b&往期:&/b&&/p&&p&&a class=&internal& href=&https://zhuanlan.zhihu.com/p/&&局域网工具系列 1 --局域网屏幕分享InletexEMC - 知乎专栏&/a&&/p&&p&&a class=&internal& href=&https://zhuanlan.zhihu.com/p/&&局域网工具系列 2 --手机控制电脑的百度袋鼠 - 知乎专栏&/a&&br&&/p&&p&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&局域网工具系列 3 --手机看电脑共享的资源 - 知乎专栏&/a&&br&&/p&&br&&p&------------------------------------------------------------------------&/p&&p&from 微信公众号:&b&wnsouba&/b& (每天来点精简的分享)&/p&&p&------------------------------------------------------------------------&/p&
下载: 今天推荐的软件叫做无界鼠标(Mouse without Borders),微软官方出品,主要功能是实现一套鼠标键盘控制局域网中最多4台电脑,除了支持键鼠操作,还支持不同电脑间文件拷贝与剪切板共享。下面说说安装说明,以…
&figure&&img src=&https://pic7.zhimg.com/v2-ad7f4ed19e3c54c2c3039_b.jpg& data-rawwidth=&1400& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1400& data-original=&https://pic7.zhimg.com/v2-ad7f4ed19e3c54c2c3039_r.jpg&&&/figure&&p&目前知乎站内的 spammer 为了快速取得收效,往往倾向于大批量地产生相似的 spam 内容,或者密集地产生特定的行为。针对这种大量,相似,和相对聚集的特点,我们最近开始尝试使用聚类的方式去发现和挖掘 spammer。 anti-spam 现阶段使用到聚类的场景主要有面向内容和行为的聚类。&/p&&p&聚类的目的在于把相似的内容和行为聚集在一起。常见的聚类方法有 k-means, 层次聚类。另外还有基于密度和图的聚类分析方案。&/p&&blockquote&&p&聚类分析仅根据在数据中发现的描述对象及其关系的信息,将数据对象分组。其目标是,组内的对象相互之间是相似的(相关的),而不同组之间的对象是不同的(不相关的)。组内的相似性(同质性)越大,组间差别越大,聚类就越好。&br&&b&《数据挖掘导论》&/b&&/p&&/blockquote&&p&从上面的定义来看,相似度的度量是聚类的关键之一,常见的相似度算法有 edit distance,conscine similarity, Jaccard 相似度,pearson 相关系数等。本次聚类我们使用了一些文本相似度的算法,主要包括 jaccard 和 sim-hash.&/p&&h3&&strong&Jaccard&/strong&&/h3&&p&Jaccard 相似度以两个集合交集占并集的比例作为两个集合的相似度,e.g. 集合 A, B 的相似度 J(A, B) 可以表示成:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-248b841c6ab3f9e23dae67_b.jpg& data-rawwidth=&294& data-rawheight=&106& class=&content_image& width=&294&&&/figure&&h3&&strong&sim-hash&/strong&&/h3&&p&然而对于数据量比较大的场景下,jaccard 的表现差强人意, 于是我们将尝试使用 sim-hash。 sim-hash 由 Charikar 在 2002 年提出,后续在 google 被得以应用,用于近似网页的检测。sim-hash 为输入的文本生成一个 n 位的指纹,与传统的 MD5, SHA-1 这类哈希函数不同的是,对于近似的文本,sim-hash 生成的指纹也近似; 越近似的文本,其指纹不同的二进制位数(记为 k)越少。对于两个文本,比较其 sim-hash 相似度的步骤如下:&/p&&ol&&li&&strong&分词&/strong&,对文本进行分词,为了减少停用词和其他常见词(e.g. 的,是,在..)带来的影响,使用 tf-idf(Term Frequency-Inverse Document Frequency) 为每个词增加权重,这里 tf 指的是某个词在该文本中出现的频率,idf 则与一个词的常见程度相关(即包含这个词的文本数),越常见的词,其 idf 值越低。tf-idf 权重就是 tf 与 idf 的乘积,在一段文本中,tf-idf 权重相对高的词就成为了这段文本的关键词。更详细的解释请参考 &a href=&https://link.zhihu.com/?target=http%3A//www.ruanyifeng.com/blog/2013/03/tf-idf.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&这篇文章&/a&。&/li&&li&&strong&hash&/strong&,计算每个词的 hash 值,通过将文字转换成数字来提高计算效率。&/li&&li&&strong&加权&/strong&,将 hash 中的 1 乘以正数的权重,0 乘以负数的权重。&/li&&li&&strong&合并&/strong&,将加权后的hash值按列相加,得到一个数字组成的序列。&/li&&li&&strong&降维&/strong&,将步骤 4 得到的数字序列转换成 0,1 串,大于 0 的数字转换成 1,小于 0 的数字转换成 0。&/li&&li&&strong&相似度比较&/strong&,比较生成的 sim-hash 值的 hamming distance。hamming distance 即两个 hash 值的汉明距离,相信大家都很熟悉了,更多的介绍可以参考&a href=&https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Hamming_distance& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&链接&/a&里面的解释。&/li&&/ol&&figure&&img src=&https://pic3.zhimg.com/v2-dfcfe7d3add796caf054e5d_b.jpg& data-rawwidth=&1420& data-rawheight=&992& class=&origin_image zh-lightbox-thumb& width=&1420& data-original=&https://pic3.zhimg.com/v2-dfcfe7d3add796caf054e5d_r.jpg&&&/figure&simhash 生成过程示意图&br&&p&我们测试了两种方法运行 100w 次的时间耗费,测试代码如下:&/p&&div class=&highlight&&&pre&&code class=&language-scala&&&span&&/span&&span class=&k&&def&/span& &span class=&n&&test&/span&&span class=&o&&()&/span&&span class=&k&&:&/span& &span class=&kt&&Unit&/span& &span class=&o&&={&/span&
&span class=&k&&var&/span& &span class=&n&&s1&/span& &span class=&k&&=&/span& &span class=&s&&&这是一个测试测试测试啦,哈哈哈哈哈哈&&/span& &span class=&o&&;&/span&
&span class=&k&&var&/span& &span class=&n&&s2&/span& &span class=&k&&=&/span& &span class=&s&&&这是一个测试测试测试哈,啦啦啦啦啦啦&&/span& &span class=&o&&;&/span&
&span class=&k&&var&/span& &span class=&n&&t1&/span& &span class=&k&&=&/span& &span class=&nc&&System&/span&&span class=&o&&.&/span&&span class=&n&&currentTimeMillis&/span&&span class=&o&&();&/span&
&span class=&k&&for&/span& &span class=&o&&(&/span&&span class=&n&&i&/span& &span class=&k&&&-&/span& &span class=&mi&&0&/span& &span class=&n&&to&/span& &span class=&mi&&1000000&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&k&&var&/span& &span class=&n&&dis&/span& &span class=&k&&=&/span& &span class=&nc&&ZSimilarity&/span&&span class=&o&&.&/span&&span class=&n&&jaccard&/span&&span class=&o&&(&/span&&span class=&n&&s1&/span&&span class=&o&&.&/span&&span class=&n&&split&/span&&span class=&o&&(&/span&&span class=&s&&&&&/span&&span class=&o&&),&/span& &span class=&n&&s2&/span&&span class=&o&&.&/span&&span class=&n&&split&/span&&span class=&o&&(&/span&&span class=&s&&&&&/span&&span class=&o&&));&/span&
&span class=&o&&}&/span&
&span class=&k&&var&/span& &span class=&n&&t2&/span& &span class=&k&&=&/span& &span class=&nc&&System&/span&&span class=&o&&.&/span&&span class=&n&&currentTimeMillis&/span&&span class=&o&&();&/span&
&span class=&n&&println&/span&&span class=&o&&(&/span&&span class=&s&&&jaccard 耗费时间: &&/span& &span class=&o&&+&/span& &span class=&o&&(&/span&&span class=&n&&t2&/span& &span class=&o&&-&/span& &span class=&n&&t1&/span&&span class=&o&&)&/span& &span class=&o&&+&/span& &span class=&s&&&
ms &&/span&&span class=&o&&);&/span&
&span class=&n&&t1&/span& &span class=&k&&=&/span& &span class=&nc&&System&/span&&span class=&o&&.&/span&&span class=&n&&currentTimeMillis&/span&&span class=&o&&();&/span&
&span class=&k&&val&/span& &span class=&n&&hash_s1&/span& &span class=&k&&=&/span& &span class=&nc&&ZSimHash&/span&&span class=&o&&.&/span&&span class=&n&&hash&/span&&span class=&o&&(&/span&&span class=&n&&s1&/span&&span class=&o&&,&/span& &span class=&mi&&64&/span&&span class=&o&&)&/span&
&span class=&k&&val&/span& &span class=&n&&hash_s2&/span& &span class=&k&&=&/span& &span class=&nc&&ZSimHash&/span&&span class=&o&&.&/span&&span class=&n&&hash&/span&&span class=&o&&(&/span&&span class=&n&&s2&/span&&span class=&o&&,&/span& &span class=&mi&&64&/span&&span class=&o&&)&/span&
&span class=&k&&for&/span& &span class=&o&&(&/span&&span class=&n&&i&/span& &span class=&k&&&-&/span& &span class=&mi&&0&/span& &span class=&n&&to&/span& &span class=&mi&&1000000&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&k&&var&/span& &span class=&n&&dis&/span& &span class=&k&&=&/span& &span class=&nc&&ZSimHash&/span&&span class=&o&&.&/span&&span class=&n&&hammingDistance&/span&&span class=&o&&(&/span&&span class=&n&&hash_s1&/span&&span class=&o&&,&/span& &span class=&n&&hash_s2&/span&&span class=&o&&,&/span& &span class=&mi&&64&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&span class=&n&&t2&/span& &span class=&k&&=&/span& &span class=&nc&&System&/span&&span class=&o&&.&/span&&span class=&n&&currentTimeMillis&/span&&span class=&o&&();&/span&
&span class=&n&&println&/span&&span class=&o&&(&/span&&span class=&s&&&sim-hash 耗费时间: &&/span& &span class=&o&&+&/span& &span class=&o&&(&/span&&span class=&n&&t2&/span& &span class=&o&&-&/span& &span class=&n&&t1&/span&&span class=&o&&)&/span& &span class=&o&&+&/span& &span class=&s&&&
ms &&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&/code&&/pre&&/div&&p&结果显示:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&jaccard 耗费时间: 21772
sim-hash 耗费时间: 9981
&/code&&/pre&&/div&&p&在文本较短的情况下,sim-hash 可以提升至少一半的检测效率;检测长文本的差距更为明显。所以采用 sim-hash 可以有效的缩短相似度检测的时间。&/p&&p&经过试验,对于 64 位的 sim-hash 指纹,k=3 是判断两个文本是否相似比较合理的阈值,因为在 k=3 的时候, 召回率和准确率都能处在一个比较满意的水平(75%左右)。为了提高召回和准确率,在实践当中,我们使用 k=4 来保证召回,并在 sim-hash 的基础上,对每一组再次进行一次 jaccard 相似度计算,提高其准确率。&/p&&br&&figure&&img src=&https://pic4.zhimg.com/v2-c43f569b8fbf371c2722f26ecc7a4524_b.jpg& data-rawwidth=&1030& data-rawheight=&732& class=&origin_image zh-lightbox-thumb& width=&1030& data-original=&https://pic4.zhimg.com/v2-c43f569b8fbf371c2722f26ecc7a4524_r.jpg&&&/figure&
不同阈值下的准确率和召回率曲线&br&&br&&br&&br&&p&目前站内每天 web 端产生近千万的写行为。拿私信举例, 如果用单进程去比较每天 10w 条私信的相似度,每一条私信需要和其他 99999 条私信进行两两比较,根据实验数据, 使用 sim-hash 一次遍历需要近 1s, 将 10w 的数据全都检测一遍则需要接近 27个小时。在这种场景下,如何有效,快速地对全量的数据进行聚类呢?&/p&&p&spark 是目前我们采用的方案。spark,是一个高性能分布式计算框架。spark 的计算是基于内存的,spark 支持将计算的中间结果和数据集存储在内存,大大减少了磁盘 io,网络通信的时间。与 map-reduce 模型相比,提供了更为丰富的算子 (e.g. filter,flatMap等)。这些算子被分成两类,转换(transformation)和执行 (action),所有的 transformation 操作具有延迟性,当一个 transformation 操作被调用时,计算不会立即触发,只有 action 被调用时,计算才会被触发。这一点也良好的保证了 spark 的容错性,当一个 task 在某个节点挂掉时,在一个新的节点重新进行计算的成本不会很高。&/p&&br&&br&&h3&&strong&内容聚类&/strong&&/h3&&ul&&li&数据准备:&/li&&/ul&&p&在使用 spark 之前,数据准备是由 HiveQL 结合 python 脚本完成的,在数据量大的情况下,效率存在问题。而 spark 可以与 hive 进行无缝整合,因此数据处理的效率提升了不少。在 hive 上,HiveQL 实际上被转换成一系列的 map-reduce 过程,在 hadoop 平台上执行计算;而在 spark 上执行 hive 语句,HiveQL 会被转化成一系列的 transformation 和 action。spark 会直接读取 hive 的元数据,将元数据转化成 spark RDD, 并在此基础上进行计算。得益于 spark 丰富的算子和基于内存的特点,加上原来由 python 脚本完成的数据清洗工作也可以由 spark 的算子来代替完成,spark sql 的执行效率要比原来采用 hiveQL 的执行效率高至少 10 倍有余。&/p&&ul&&li&聚类实现:&/li&&/ul&&p&内容聚类的实现采用了图分割的方式,即构建一个相似度图 G=(V, E),以每个文档为顶点,文档之间的相似度作为相连边的权重。以 sim-hash 为例,两点之间相连边的权重就是两个 hash 值的 hamming distance。如下图所示,假如我们以 k=3 作为阈值,取所有权重小于等于阈值的边作为新的子图(即图中黑色的边),并计算子图中的连通子图即可得到(1,2,3)和(4,5,6,7)两个cluster。&/p&&p&在实际使用中,我们本来使用 Graphx(spark 对于图和图的并行计算的 api,详情见&a href=&https://link.zhihu.com/?target=http%3A//spark.apache.org/graphx/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GraphX | Apache Spark&/a&) 提供的 connectedComponents 接口,但是后续发现在数据量比较大的情况下,反复的迭代带来了比较大的性能问题。于是利用文本相似度的传播性(a与b相似,且 b与c相似,则a与c相似),我们使用 spark SQL 将问题转化为 “寻找最小相似节点” 的问题。举个例子,在下图中,与1相似的最小节点是1,与2相似最小的节点为1,与3相似最小的节点也为1,这三个点最小相似节点均为1,所以他们属于同一个 cluster。而 4,5,6,7 这四个节点,因为最小相似节点为 4,所以他们属于另外一个独立的 cluster。&figure&&img src=&https://pic4.zhimg.com/v2-3f51cb58bcea6ef201edeed62a42ee47_b.jpg& data-rawwidth=&706& data-rawheight=&496& class=&origin_image zh-lightbox-thumb& width=&706& data-original=&https://pic4.zhimg.com/v2-3f51cb58bcea6ef201edeed62a42ee47_r.jpg&&&/figure&cluster 分割示意图&/p&&br&&p&由于 Jaccard 相似度计算成本比较高,实践中使用 sim-hash 来提升相似度计算的效率。使用 64 位哈希值,将 k=4 作为阈值,将输入的数据进行一个预先分组。由于这种条件下可以保证比较高的召回,而准确率相对来说比较低, 需要再针对每个分组使用 Jaccard 进行细分,进而提高准确度。这种方式减少了需要计算 Jaccard 相似度的数量,也弥补了 sim-hash 相似度在召回高时准确率不足的问题。另外,为了减少不必要的计算资源浪费,相连两个节点的相似度只单向计算了一次。但是相似度的比较仍然是一个近似笛卡尔积的计算,为了提高这部分的计算效率,我们采用 spark 的广播机制,在所有节点的内存缓存一份变量,从而减少在计算过程中的通信开销。&/p&&p&目前针对私信,聚类可以在 1-3 min 之内完成,使用 spark 充分提高了数据处理的效率。&/p&&h3&&strong&行为聚类&/strong&&/h3&&p&行为聚类的主要思路是将用户的行为路径以文本的方式表达出来,将行为聚类转换成内容聚类,通过文本相似度聚类,将相似的行为聚集在一起。&/p&&ul&&li&数据准备:&/li&&/ul&&p&行为路径的表达:以用户的一个 post 行为为单位,取前后至少两个请求,并计算每个行为之间的时间间隔,将用户的行为序列表达成由“请求路径|请求方法|与上一次请求的时间间隔|”构成的文本组合。&/p&&ul&&li&聚类实现:&br&&/li&&/ul&&br&&p&相对于内容聚类,行为聚类面对着更大的数据量, 在数据清洗过后大概每天有 30w+ 的关键业务写行为。考虑到比较不同类别的写行为之间的相似度没有太大意义,因此针对每个业务单独进行聚类,这样一来将 30w * 30w 的计算规模减少到了 1w * 1w + 3w * 3w + .....。由于聚类的实现与内容聚类的逻辑大体一致,这里就不再多做介绍。&/p&&p&&strong&总结&/strong&:针对批量的 spammer 内容和行为,聚类是一种替代人工策略行之有效的方法。目前行为和内容聚类均以离线处理的方式上线,聚类是 antispam 使用 spark 的初步尝试,后续会继续优化提高其处理效率,也会尝试使用 spark streaming 来提高聚类的实时性。&br&&/p&&p&&b&作者&/b&:周奥特 &a href=&https://www.zhihu.com/people/qin-luo-68& class=&internal&&孙先&/a&&a href=&https://www.zhihu.com/people/F1zzy& class=&internal&&陈磊&/a&&br&&/p&&p&同时感谢反作弊团队其他同学的帮助&br&&/p&&br&&p&&strong&Reference&/strong&&/p&&p&[1] &a href=&https://link.zhihu.com/?target=http%3A//www2007.org/papers/paper215.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Detecting Near-Duplicates for Web Crawling&/a&&/p&&p&[2] &a href=&https://link.zhihu.com/?target=http%3A//www.ruanyifeng.com/blog/2013/03/tf-idf.html%25E5%25BC%25A6%25E7%259B%25B8%25E4%25BC%25BC%25E6%%25E7%259A%%25BA%%& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TF-IDF与余弦相似性的应用&/a&&/p&
目前知乎站内的 spammer 为了快速取得收效,往往倾向于大批量地产生相似的 spam 内容,或者密集地产生特定的行为。针对这种大量,相似,和相对聚集的特点,我们最近开始尝试使用聚类的方式去发现和挖掘 spammer。 anti-spam 现阶段使用到聚类的场景主要有面…
&p&Belleve博客: &a href=&//link.zhihu.com/?target=http%3A//typeof.net/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Typeof.net&/a& &/p&&p&徐宥博客: &a href=&//link.zhihu.com/?target=http%3A//blog.youxu.info/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&4G spaces&/a& (科普向)&/p&&p&陈皓博客:&a href=&//link.zhihu.com/?target=http%3A//coolshell.cn/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&coolshell.cn/&/span&&span class=&invisible&&&/span&&/a& (不解释)&/p&

我要回帖

更多关于 支票20日怎么写 的文章

 

随机推荐