首页 文章 精选 留言 我的

精选列表

搜索[思考模型],共10004篇文章
优秀的个人博客,低调大师

对Context的重新思考

Android.view.WindowManager$BadTokenException:Unabletoaddwindow-tokennullisnotvalid;isyouractivityrunning? 问题发生的情景:当我从一个activity跳转到另外一个activity时,第二次跳转崩溃。后来终于找到了原因 第一次progDialog实例化用的是第二个activity的context,然后第二次进入第二个activity的时 候progDialog并没有实例化,progDialog还保留着第2个activity第一次的context,但是这个时候的 activity已经销毁,context也就不存在 。 不要纯粹地节约一个new的过程,而不去创建对象。 但是每次都new一个对象也不是明智之举,于是利用view.getContext来对Context进行一下判断可以 对代码进行一下优化 1 2 3 4 5 6 7 if (progDialog== null ){ progDialog= new ProgressDialog(context); } else { if (progDialog.getContext()!=context){ progDialog= new ProgressDialog(context); } } 本文转自屠夫章哥 51CTO博客,原文链接:http://blog.51cto.com/4259297/1793253,如需转载请自行联系原作者

优秀的个人博客,低调大师

大数据应用方向思考

一、 警惕大数据过热 1.1 过热产生盲目性 国内大数据的宣传早已过热,很多区县级政府也在考虑成立大数据局,政府对大数据热几乎没有抵抗力,企业没有紧跟就对了,在大数据高潮中反省政府的大数据行为、冷静一下头脑是有益的,毕竟大数据应用是一个经济问题,一窝蜂地大数据会使人犯“大炼钢铁”一类的错误。 1.2 大数据应用效益存在问题 大数据最积极的推动者是政府,但是政府工作如何从大数据应用中获益一直没有清晰的答案,有效的大数据应用集中于互联网企业和金融领域并非政府工作,迄今一本像样的政府大数据应用案例都编写不出来,这种情况下推力政府大数据应用会带有很大的盲目性,这是技术导向而不是问题导向,技术导向必然会造成浪费。 1.3 大数据不是包治百病的神药 现在对大数据的宣传已经远远胜过对城市问题的探讨,问题还没搞清药方就先开出来了,大数据药方再灵也不可能解决自己都没有诊断清楚的问题。任何技术都有其长处和短处,大数据也是一样,都有其能解决与不能解决的问题,各地政府首先要明确要问题是什么,然后再审视大数据技术能否发挥作用,不能反过来先定大数据再去找问题,政府工作明确目标永远比搞清技术更重要。 二、 大数据源自互联网的推动 2.1 大数据是如何产生的? 任何有社会影响力的新名词都不是望文生义可以解释的,这些名词都被赋予了成语含义,“大数据”便是其一。历史上超大规模的数据很多却不被称为大数据,是因为单纯数据量增长并没有形成巨大社会影响力。 大数据概念是大的数据量与现代信息技术环境相结合涌现的结果,因此引发了巨大的效益机会,“大数据”一词的发明与宣传是为了抓住这个新机会。 2.2 没有互联网便没有大数据 任何资源的价值展现都离不开特定的环境,互联网前的海量数据因缺少规模化的社会应用而不为人们重视,互联网创造了大数据应用的规模化环境,大数据应用成功的案例大都是在互联网上发生的,互联网业务提供了数据,互联网企业开发了处理软件,互联网企业的创新带来了大数据应用的活跃,没有互联网便没有今天的大数据产业。 2.3大数据是“大智移云物”的共同产物 如果没有汽车与高速公路石油产业不会那么重要,同样,没有互联网、云计算、物联网、移动终端与人工智能组合的环境大数据也没那么重要。大数据的价值并非与生俱来而是应用创新之结果,价值是由技术组合创新涌现出来的。离开环境的支持大数据毫无价值,就像离开了身体的手不再有手的功能一样。 三、 传统大数据思维局限于支持决策 3.1 传统的大数据应用理念 人们对事物的想象力很容易受所用词汇的暗示,“大数据”容易暗示人们关注数据规模而忽略信息技术背境的巨大变化所涌现的新机会。政府官员的工作经历很容易把大数据应用想象为只是统计应用在数量上的升级,大数据的作用是提取信息,信息的作用是改进决策,数据多意味着信息多,信息越多决策就越准确。在不少干部的理解中,部门数据整合起来就是大数据。 3.2 两种数据使用方向:支持决策与支持操作 在政府的工作中,数据对领导层的作用主要是改进决策,但基层工作人员不需要决策,数据是用来直接操作的。政府公共服务业务主要是操作问题,服务是规范的数据处理,基层工作人员只是按章办事不需要决策分析。使用信息技术是为了提高操作服务的效率。发改委等十部门提出的“一号一窗一网”的服务要求所要解决的只是提高操作的效率。改进决策与改进操作是大数据两种不同的使用方向。 3.3 专家(人脑)与系统(电脑)使用大数据的特点 支持决策的数据应用是面向专家(包括领导)的,专家需要从数据中提取信息,以信息支持决策,从数据中领悟信息是人脑独有的本领,但不同人信息领悟力并不一致,同样的数据不同人领悟的信息不同,对决策的影响也不同,应用结果的不确定性是专家使用大数据的特点。。 支持操作的数据应用不能有不确定性,操作系统的数据应用是由系统控制的,操作按确定的规则进行,没有自由量裁的可能,数据应用结果由软件决定,这种应用是电脑在使用数据,电脑不懂信息只会严格依数据操作,这种使用数据的模式保证了大规模业务行为的一致性。 3.4 政府不能忽略操作型大数据应用 政府工作存在着两种大数据应用:支持决策与支持操作,但是在多数政府官员只想着大数据支持决策而想不到改进服务操作更有效益。大部分的政府服务的精细化改进并不是决策层次上改进,而是操作层次上的改进,政府提出的“一号一窗一网”式服务关键是提高操作的效率,实践证明操作的优化的改进空间更大,大数据在提高政府决策水平上的成效往往不如提高操作效率成效明显。 四、 大数据决策的局限性 4.1 大数据小数据的不同来源 以数据量来划分大数据与小数据会忽略两种数据更实质的差别,从数据产生的过程看,小数据是经人触摸过的数据,包括人工填报或更新、核对等。大数据是机器自动记录的、未经人触摸过数据。 小数据来自业务流程中的人工填报、统计调查等渠道,统计调查是可以根据决策信息的需要专门设计的,为降低成本统计经常采用抽样调查的方法。 大数据来自自动化业务运行的副产品,出于成本的考虑,政府不大可能专为收集信息而设计大数据收集链,为决策服务大数据只能利用业务系统产生的数据副产品,大数据的收集成本是由业务系统承担的。大数据的来源受到业务系统种类的限制,不是所有的信息需求都能找到恰当的数据源。 4.2 大数据适合小决策而不适合大决策 大数据适合在狭窄范围内对具体事务决策而不适合于大范围的决策。因为大数据的形成包含着先天的局限性,很多影响重大决策的信息恰恰是无法数字化的,例如国内外形势、技术创新、队伍士气、重大事件(类似美国9.11 事件)都无法数字化,可数字化的现象只是小部分,以为靠数据决策就能更全面也是一种误解。政府重大决策需要考虑各方面的平衡,局部领域的大数据仅适合局部领域的决策,不适合面向全局的政府决策,精细化与全面性是不可得兼的。 4.3 改进政府操作的大数据应用 政府的大数据应用不能只关注决策应用,改进操作的大数据应用往往能够获得更好的效益。政府对公众的服务主要使用的还是以小数据为中心的数据库,但是融入现场服务数据的应用可以将服务提高到大数据的层次上并增加智能化的应用。对政府基层工作人员的支持现场化、连机化,通过云平台与实时通信能显著提高一线人员的工作效率,是提高政府基层服务的智能化的重要措施,以改进服务操作效率的智能大数据应用会有更大的成效。 五、 没有人脑参与系统才能高效与智能 5.1 人脑使用数据模式的效率制约 为人脑决策使用的大数据应用模式存在两点不足:一是效率上不去,大数据分析结果一旦交付大数据应用就结束了,无法形成连续服务型业务,信息的进一步应用是领导的事情,与大数据处理无关了,人脑决策的慢节奏抵消了大数据快处理的价值。 其次是大数据信息决策的效果的不确定性,决策质量与领导人的知识、思维方式、决策风格密切相关,决策效果又与执行团队的能力相关,涉及的不确定因素太多。人脑使用数据的模式无法实现数据应用效果的确定性。 5.2 电脑使用数据模式的效率优势 电脑使用数据的模式排除了人脑的参与,系统完全是由事先编写的软件直接处理数据,排除了人脑介入有两点好处:一是运行速度快,信息技术的速度优势得以充分发挥;二是保证了结果的确定性,系统的行为是可预测的,这将有利于系统可成为可组合、可叠加的功能模块,能够被集成为更复杂的系统。 5.3 智能大数据应用可形成连续性业务 排除人脑参与的数据应用模式是信息技术的自动化应用,这种模式可综合使用各种技术资源(包括云平台、物联网、移动终端、人工智能等等)建立高速、流畅连续型服务,进入智能服务的新阶段,常见的互联网搜索、电子商务、移动支付、摩拜单车、蚂蚁金服无一不是这类的智能大数据应用,这种持续的智能大数据服务更受公众欢迎、社会影响力也更大。 六、 智能大数据应用的发展空间 6.1 所有的智能应用都是大数据应用 大数据是机器与机器对话的语言,只有机器与机器的高速对话才能产生如此规模的大数据。物联网、云平台、宽带网、移动终端等设施要发挥作用都要依赖机器与机器的对话,随着信息技术的大发展,机器与机器的对话速度越来越快、范围越来越广、规模越来越大,系统也越来越智能化,所有的智能数据应用都属于大数据的应用范围。 6.2 智能化的作用是提高执行的效果 虽然大数据可以用于改进决策,但智能化的目标是提高执行的效果。计算机系统的作用是使规范性、可重复的工作做的更快。对于需要创造性的、非重复性的工作信息技术是依然无能为力的,人们发现几十年来计算机对于人脑决策能力的提高始终不大,智能化应用机会还是集中在对规范业务的改进,规范业务是确定性的服务,远比充满不确定性的决策业务更能让计算机发挥作用。 6.3 操作型大数据应用的智能化趋势 以提高执行效率为目标的大数据应用将向智能化发展,以互联网为基层的现代信息技术的大发展已经为服务的智能化创造力良好的条件,早期由于通信与网络能力的限制只能在一台设备上存储自动处理系统被称为自动化处理阶段,今天自动处理系统可以综合应用网络通信、云平台数据与软件、物联网感知数据与机器学习来实现更有效的自动管理,则被称为智能化服务阶段,排除了人脑参与的大数据应用进入智能化服务没有任何障碍,大数据应用智能化成为必然趋势。 七、 智能大数据应用的活力 7.1 鲜活的数据 智能化应用中的大数据资源与信息决策中的数据资源的重大不同在于前者是动态形成的,其数据环境是不断变化、不断更新的,很多数据是在运行中自动生成的,数据资源与智能系统共生,这种数据资源很难转让,数据与服务系统是统一的生命体不能单独存在的,离开了系统的数据可以用来分析但失去了原来的意义,如同离开了人体的手再也没有原来的功能了。 7.2 实时的处理 在智能系统中的大数据应用是实时处理,面向信息决策中的大数据应用是批处理。实时处理能够确保及时性,这对于提高服务效率、保持业务的连续性很重要,现在强调“一号一窗一网”式的为民办事离不开对数据的实时处理。而信息决策类大数据应用则并不需要这种高效。 7.3 持续高效的服务 智能化的大数据应用排除了人脑的干预,全部流程都是由电脑对电脑一气呵成,这样就能够达到很高的运行效率,而这是智能化系统巨大的优势,也是智能服务系统得以生存的原因,不论是搜索、购物还是其它自动化的服务,人的耐心都是很有限的,处理慢一点人们就会弃之而去。在信息决策大数据应用的结果是供人脑一次性使用的,处理速度就不那么重要了。 7.4 不断积累的智慧 能够不断积累智慧的业务更有活力,易于修改是以软件为基础的业务的极大优点,这使得软件系统成为积累智慧最方便的工具,信息系统的高速发展也得益于系统智慧积累的能力。一项可持续的智能化业务系统始终处于不停的改进、完善与扩展之中,不断推出新版本的过程是智慧积累的过程,智慧的不断积累增添了系统的服务能力与可持续性。 信息决策大数据应用则不具有这一优势,其业务不连续很难推出一个又一个的新版本,智慧积累效率就慢多了。 八、 小数据服务决定大数据中心的生存 8.1 数据资源的时效性 数据资源像蔬菜一样有保鲜期,极少有越老越值钱的数据。数据集中存储很容易,由此而来的数据质量维护却是一大难题。数据生成得快贬值也快,很多数据往往还来不及处理数据就失效了,反而是那些变化稍慢、稳定期稍长的数据容易得到较多用户且服务也容易开展,这类数据大部分是小数据。 不同的数据使用方式对数据质量有不同的要求,面向操作的应用则对数据质量非常敏感,例如证照库若不能及时更新就无法使用。信息决策类应用对数据的敏感性会差一些,大数据中心应当使数据的时效性与应用需求同步,要根据需求的价值有重点有选择地组织好数据质量的维护。 8.2 大数据交易中心的困难 大数据交易中心与成为建设热点,在大数据应用刚刚开始,人们还没搞清大数据交易是什么概念时就建交易中心实在太早了。 实时服务的智能大数据应用的数据是鲜活的、是服务中自动生成的动态数据,要交易的是动态数据流还是截取的静态数据,动态的大数据交易很难,不仅谈判难处理也难,用户需要建立动态数据的实时处理系统。 静态的大数据交易更可行一些,但数据资源与应用需求并不容易匹配,这将会限制交易数的增长,另一困难是隐私权保护问题,数据需要脱敏,未脱敏的数据交易会受到限制,交易中心将长期面对交易稀缺的局面,经营很不容易。 8.3 小数据服务需要补课 发达国家是在小数据充分应用之后才开始应用大数据,国内是在小数据应用还很不足时跨越式应用大数据。小数据应用补课是各地大数据中心必须重视的问题。要看到越是简单的东西应用面越广,小数据的应用空间比大数据大得多,尤其是整合后的小数据服务,极可能成为的数据中心最火的业务。 政府服务的精细化依赖的主要是小数据,把小数据的整合服务做好,大数据中心的工作即完成了90%,千万不能轻视小数据服务,大数据中心的立身之本恰恰是小数据整合服务。 8.4 大数据中心的经济价值 大数据中心的生存本质上是一个经济问题,人们想做交易中心也是希望能够在经济上更节约、更有效益,但是效益的基础是应用规模,只有大量重复性、相似性的工作才有可能利用平台与工具来提高服务效率创造用户价值,目前小数据服务更能够满足规模经营的条件。 政府公共服务的支柱还是小数据,单独成规模的大数据服务不多,各种数据资源的综合使用会有更大的创新机会,地理数据与政府服务相结合、推动政府服务的连线化动态化可能提升用户价值,大数据中心要发展必须全力创造用户价值,唯有用户价值才能支撑大数据中心生存。 九、 拓展视野,推动大数据应用创新 9.1理念创新,积极宣传智能大数据应用 首先要拓展大数据应用理念,不能将大数据应用局限在政府信息决策的狭窄领域之中,而要看到智能大数据应用的广泛空间,将智能大数据应用与大众创业万众创新结合起来,将一切智能化应用都归入大数据应用的范围,大数据概念越广阔应用越繁荣。 利用大数据改善政府决策是大数据应用的重要方面,过去已强调得很多了,现在需要强调的是政府公共服务的智能化、精细化。大数据不仅能改善决策还能改善服务,改善服务有着更广阔的发展空间,公众的获得感更好。 9.2 为大数据应用创造良好的基础环境 对大数据应用最给力的推动是提供优良的通信环境和完善的信息基础设施。大数据应用的基础是超强的通信能力,通信能力影响全社会大数据应用的成本,包括用户的时间成本与服务商的开发与服务成本,降低通信成本是对大数据应用创新极大的支持,土壤肥沃庄稼才能茂盛。 政府数据开放是推动大数据应用的措施之一,可为大数据应用带来示范效果,政府要鼓励企业利用政府大数据开展增值服务,使更多缺乏大数据处理能力的公众也能从政府数据开放中获益。 9.3 鼓励社会大数据应用的自组织创新 大数据应用是一项创新,政府不能只从政府决策的视角来引导大数据应用方向,而要从方便公众受益的视角推动智能化的大数据应用,要鼓励社会各界智能化大数据应用的合作与自组织创新,好服务都是各种应用技术组合创新的结果,政府宜推动智慧城市大数据应用的互操作,降低不同技术合作创新的成本来促进应用创新的繁荣。 本文作者:胡小明 来源:51CTO

优秀的个人博客,低调大师

🎉 echarts-for-react 开源思考

echarts 是什么,不用多说了, 国内最知名的可视化图表库之一。echarts-for-react 是它的一个极简的 React 封装。 一、前言 🎉 echarts** v5 发布之后**,echarts-for-react 上已经有很多很多的 issue 请求支持最新版本,所以,过年期间升级了 v3 版本,支持了最新的 echarts v5。 **很尴尬,目前我是在蚂蚁,主要做大数据 BI 产品 + AntV 数据可视化技术栈。理论上来说,echarts 使我们的竞品,哈哈,然而,我居然还在过年给它升级周边,我想这应该就是开源精神吧。**那就顺便一起打个广告吧,欢迎大家支持我现在的工作。 G2:基于图形语法的数据可视化,提供灵活性、定制性 G2Plot:基于 G2 做的一图已封装,降低大部分简单场景的使用成本 Charts:基于 G2Plot,在 Ant Design 上透出的 React 图表组件库 本文还是重点软一下 echarts 和它的 react 封装吧! 二、起源 在蚂蚁之前,自己在网易游戏入坑前端,当时内部使用 SVG 做代码版本控制,所以自己做了一个类似于 travis(但是没有 GitHub Action) 的面向 SVG 的 ci 工具。这个项目是我初次上手 React(0.14.x 版本)。 然而在 JQuery 技术栈下, echarts 很好用,而在 React 下,居然没有一个开箱即用的库,所以每次都要自己在 React 的环境找到 DOM,然后调用 echarts.init,非常 low,且代码重复率很高很高,所以在项目中做了一个 React 封装,然后就开源出来了。 毕业之前,在学校做 Java 的,干过 Java 的知道,Java 的包名很多都会去 4j 后缀,意思是 xx for java。所以因为惯性,给他取名为** echarts-for-react**。 三、定位 和我自己做开源包皮的习惯和原则有关: 封装就要有自己的明确定位,不要过度封装 透传概念,不新增数据结构和技术概念 符合技术栈的习惯(按照 React 的使用性质,按需增加一些开发优化的内容) 所以这个包,主要的内容和特性包括: 1. className + style 属性 React 组件本质还是 ui 组件,我的意识中,每一个 React 组件应该有 className 和 style 属性,为其做样式的自定义。 2. echarts.init 参数作为顶层 props 顶层 API 参数作为顶层 props,概念层级对等,开发者易于理解。这些包含有: notMerge showLoading loadingOption opts.renderer ... 3. echarts option 完全透传 echarts 使用 option 方式来构件图表,结果完善的文档、丰富的官网 DEMO,让开发者开发一个图形非常容易,几乎直接 copy 即可。 所以 echarts-for-react 对于 option 也是完全透传,不做任何修改,甚至都没有默认值的处理,达到的就是官网代码中的 option copy 到这里一样可用。 这大大降低了我自己的维护成本,也降低了开发者同学的调试成本。“react 报错了,先去 echarts 官网试试看,官网上可以,这边一定可以!” 4. 按需决定 update 还是 new? 针对顶层 props,还是 option 变化,包内决定是否新建实例,还是在旧实例上进行更新。让开发者只需要关注在 props,它包里处理好不同 props 要做不同操作。 5. 自动适配容器大小 这个特性可以说是这个 200 行代码的封装库中,最核心的特性,图表自动根据容器的大小做 resize。为了这个功能, 我还特意增加了一个模块 size-sensor(为什么不用开源?之前用的开源各种问题,拖延不解决,所以自己实现一个简单一些的。) 自动适配容器大小,在目前 low-code、搭建产品中,非常非常必须,几乎可以说是必备功能。这一点在目前我负责的 G2、G2Plot 中同样有大量 issue。 6. 按需加载 echarts 包本身还是很大的,混淆后接近 1M。所以按需加载是 echarts 的一个特性,本模块也通过一些代码架构,分拆除 core,让开发者决定如何进行分包和按需引入。 四、升级 给自己立的 Flag,过年期间完成就得完成。 本次升级主要的内容在于: 1. 完全 typescript 之前是在 React 0.14 时代,还是使用 props-types 校验 props,然后 ts 类型定义单独自己手写,也非常痛苦。所以这次直接使用 ts 写,自动生成 类型定义 文件。 当然主要原因,还是因为来蚂蚁之后,基本都写 ts 了,真香。 ** 2. 单测覆盖率 之前使用 jest-canvas-mock 进行单元测试,毕竟是 mock 而不是真实运营,所有一些逻辑测试不到,覆盖率一直提不上去。 所以这次换成了 jest-electron,真实运行,覆盖率直接提升到 ,运行也改成使用 GitHub action 了。当然 jest-electron 这个模块,也是为了给 AntV 系列技术栈做单测,而开发的轮子,个人觉得还是挺好用的。 然而,前者的下载量都 2M 每月了,后者才 4K。 3. 全新官网 之前的官网是自己初学 React 的时候,完全自己搭建的,没有 lint、ci,代码凌乱,样式也不好看。所以这次直接使用 dumi 这个库自动生成,网站全部 markdown 开发,也方便大家遇到官网 typo,直接一键提交 PR。 同时 Example 实例也可直接一键导航到其他代码编辑工具上。 然而,之前还可以官网放一些 google adsense,现在 dumi 上,不知道怎么加一个自定义的谷歌广告组件上去,慢慢在弄吧! 4. README 排版 项目很简单,概念也很简单,所以直接 Readme 作为 document,但是之前的文档结构、样式排版比较凌乱,所以按照现在的个人审美,重新写了写! 五、最后 从之前用 echarts,到现在做 AntV 和大数据产品,自己也算是一直在可视化这个领域了,目前 AntV G2 有很多的规划和内容,需要一些对可视化有兴趣的同学加入。如果对以下有兴趣,可以联系我投简历(我的 GitHub 主页有微信号): 大数据、数据分析 可视化搭建、Low Code 数据可视化技术 欢迎你的加入,我们一起来干 AntV G2 的 5.0 版本!

优秀的个人博客,低调大师

实例讲解:React Hook的思考

翻译原文:https://wattenberger.com/blog/react-hooks React在一年前引入了hooks,对于许多开发人员来说,它们已经改变了我们的编码习惯,但我想谈一谈从React类组件切换到功能组件基本变化。 使用类组件,我们将更新放置在特定的生命周期事件中 ❝ 类组成中 ❞ classChartextendsComponent{componentDidMount(){//挂载时}componentDidUpdate(prevProps){if(prevProps.data==props.data)return//数据更新时}componentWillUnmount(){//卸载时}render(){return(<svgclassName="Chart"/>)}} 在功能组件中,我们改为使用useEffect挂钩在主要生命周期事件期间运行代码。 ❝ 功能组件中 ❞ constChart=({data})=>{useEffect(()=>{//挂载时//数据更新时return()=>{}},[data])return(<svgclassName="Chart"/>)} 此时,您可能在想:所以,useEffect() 这只是一种进入生命周期事件的新方法!但是这种理解是错误的! 嗯,让我们看一个具体的例子,看看有什么区别。例如,如果我们有一个计算量大的 getDataWithinRange()函数,该函数基于指定的函数返回经过过滤的数据集,该dateRange怎么办?因为getDataWithinRange()运行需要一些时间,所以我们希望将其存储在组件的state对象中,并且仅在dateRange发生更改时进行更新。 类组成: 对于生命周期事件,我们需要一站式处理所有更改。我们的想法如下所示: 当我们的组件加载时,以及props更改时(其实就是dateRange),就相对的更新data 大致如下: classChartextendsComponent{state={data:null,}componentDidMount(){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})}componentDidUpdate(prevProps){if(prevProps.dateRange!=this.props.dateRange){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})}}render(){return(<svgclassName="Chart"/>)}} 功能组成 在功能组件中,我们需要考虑哪些值保持同步。每次更新的流程更像以下语句: 保持dateRange同步data 大致如下: constChart=({dateRange})=>{const[data,setData]=useState()useEffect(()=>{//假设getDataWithinRange在外部定义了,暂时不考虑这个constnewData=getDataWithinRange(dateRange)setData(newData)},[dateRange])return(<svgclassName="Chart"/>)} 看到将变量保持同步的方式简单多了是吗?不仅仅是代码量减少了! 类组成 classChartextendsComponent{state={data:null,}componentDidMount(){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})}componentDidUpdate(prevProps){if(prevProps.dateRange!=this.props.dateRange){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})}}render(){return(<svgclassName="Chart"/>)}} 功能组成 实际上,最后一个示例仍在类组件中。我们存储data是state为了防止每次组件更新时重新计算它。 但是我们不再需要使用state!而是使用useMemo(),仅data当其依赖项数组更改时才会重新计算。 constChart=({dateRange})=>{constdata=useMemo(()=>(getDataWithinRange(dateRange)),[dateRange])return(<svgclassName="Chart"/>)} ❝ 注意,我们可以只在函数内部定义变量。 ❞ constChart=({dateRange})=>{constnewData=getDataWithinRange(dateRange)return(<svgclassName="Chart"/>)} 除非我们的getDataWithinRange()函数在计算上消耗很大,否则这就是非常完美。我平时使用useMemo用的非常多,特别是在处理大型数据集时,以保持性能。 考虑使用context 想象一下,我们有许多需要计算的值,但是它们取决于不同的props。例如,我们需要计算: 我们 data在我们的 dateRange变化 的 dimensions图表的时 margins变化 我们 scales在我们的 data变化 类组成 classChartextendsComponent{state={data:null,dimensions:null,xScale:null,yScale:null,}componentDidMount(){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})this.setState({dimensions:getDimensions()})this.setState({xScale:getXScale()})this.setState({yScale:getYScale()})}componentDidUpdate(prevProps,prevState){if(prevProps.dateRange!=this.props.dateRange){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})}if(prevProps.margins!=this.props.margins){this.setState({dimensions:getDimensions()})}if(prevState.data!=this.state.data){this.setState({xScale:getXScale()})this.setState({yScale:getYScale()})}}render(){return(<svgclassName="Chart"/>)}} 功能组成 在我们的功能组件中,我们只需要简单的几句: constChart=({dateRange,margins})=>{constdata=useMemo(()=>(getDataWithinRange(dateRange)),[dateRange])constdimensions=useMemo(getDimensions,[margins])constxScale=useMemo(getXScale,[data])constyScale=useMemo(getYScale,[data])return(<svgclassName="Chart"/>)} 在我们的示例中,我们的类组件为什么会笨拙? 这是因为我们有很多的声明代码来去同步变量props和state,但在功能组件,我们只注重什么保持同步。 平时尽可能使用useMemo()钩子-让我们来实现功能效果。 现在再来一个需求 好的!继续前进-如果我们scales需要根据dimensions图表的图表进行更改怎么办? 类组成 在我们的类组件中,我们需要比较我们prevState和current state classChartextendsComponent{state={data:null,dimensions:null,xScale:null,yScale:null,}componentDidMount(){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})this.setState({dimensions:getDimensions()})this.setState({xScale:getXScale()})this.setState({yScale:getYScale()})}componentDidUpdate(prevProps,prevState){if(prevProps.dateRange!=this.props.dateRange){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})}if(prevProps.margins!=this.props.margins){this.setState({dimensions:getDimensions()})}if(prevState.data!=this.state.data||prevState.dimensions!=this.state.dimensions){this.setState({xScale:getXScale()})this.setState({yScale:getYScale()})}}render(){return(<svgclassName="Chart"/>)}} 功能组成 constChart=({dateRange,margins})=>{constdata=useMemo(()=>(getDataWithinRange(dateRange)),[dateRange])constdimensions=useMemo(getDimensions,[margins])constxScale=useMemo(getXScale,[data,dimensions])constyScale=useMemo(getYScale,[data,dimensions])return(<svgclassName="Chart"/>)} 是不是爽歪歪! 保持代码简洁 较短的代码不一定更易于阅读,但是使我们的组件尽可能地整洁无疑是一个优势! 最后 关注我们添加【前端进阶技术群】,回复:【资料包】领取前端进阶资料包 在看、转发支持作者❤️ 本文分享自微信公众号 - 前端人(FrontendPeople)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

优秀的个人博客,低调大师

关于云原生应用的思考

文中前半部分截取、参照、截取了周志明《Graal VM 云原生时代的Java》视频讲解公开的PPT的部分内容,特此声明,在此对周志明精彩的分享表示感谢。 云原生的核心是什么? 技术人员谈技术问题直接、要看本质,不能东拉西扯。现在很多厂商都在谈云原生应用,那么云原生应用的核心是什么? 云原生的应用开发框架。 提到开发框架。传统的Java系的应用开发框架比较著名的是SSH(Spring框架、Hibernate框架、Struts框架)。 Spring MVC是基于 Servlet 的一个 MVC 框架 主要解决 WEB 开发的问题,因为 Spring 的配置非常复杂,各种XML、 JavaConfig、hin处理起来比较繁琐。于是为了简化开发者的使用,从而创造性地推出了Spring boot,约定优于配置,简化了spring的配置流程。 现有的绝大多数企业级应用都是由Java开发的。Java的特点如下: 所以说,Java通过众多的规范(JSR),让应用开发人员遵从,这有助于提升应用的规模、稳定性。 在微服务时代,传统Java的理念与时代产生了巨大的矛盾。 随着Web应用的发展,微服务时代,应用的稳定性不再依赖于单个单体应用实例的稳定性,而是借助于应用集群、K8S等技术保证应用的高可用性。好比传统应用是宠物,微服务是牛羊。微服务更关注与单个应用实例是否消耗资源,启动速度是否快。 在微服务时代,如果我们只是将应用运行的“底座”由Linux换成容器,如下图所示,那效果就会比较尴尬(例如在容器中运行weblogic,承载应用),这不是成不成的问题,而是效果好不好的问题。 那么问题的根源是什么呢? 还是由Java本身的特点决定的。Java的解释型语言,解释型语言就需要解释器,JVM。而JVM是相当耗费内存的,并且启动也慢。 此外,Java的代码域是动态的。常用到的Java动态特性主要是反射,在运行时查找对象属性、方法,修改作用域,通过方法名称调用方法等。这样做的好处是,Java 程序可以加载一个运行时才得知名称的.class文件,然后获悉其完整构造,并生成其对象实体、或对其 fields(变量)设值、或调用其 methods(方法)。 解决Java问题的方法 Oracle当然也意识到Java在微服务时代的尴尬之处,因此在前两年推出了新一代JVM:GraalVM。 GraalVM是一款高性能的可嵌入式多语言虚拟机,它能运行不同的编程语言,包括: 基于JVM的语言,比如Java, Scala, Kotlin和Groovy 解释型语言,比如JavaScript, Ruby, R和Python LLVM支持的原生语言,比如C, C++, Rust和Swift GraalVM中包含Graal Compiler编译器。Graal Compiler是GraalVM与HotSpotVM(从JDK10起)共同拥有的服务端即时编译器,是C2编译器未来的替代者。 Graal Compiler支持提前编译(AOT)和即时编译(JIT)。 两者的优缺点对比如下表所示: 总结起来,AOT编译后,应用包更小、消耗内存更少、启动速度更快。JIT编译的应用,吞吐量更高、延迟更低。 此外,我们知道,HotSpotVM是JVM标准的技术实现。HotSpotVM是Sun JDK和OpenJDK中自带的JCM,使用很广。而Substrate VM是一个框架,可以将Java程序编译为独立的可执行文件,它的架构如下图所示。对于GraalVM而言,HotSpotVM是可选的: 接下来,我们再看一下GraalVM的版本。Oracle推出了社区版本(CE)和企业版(EE),两者区别如下图所示: 截止到目前,我们已经清楚了针对Java不适用于微服务,Oracle的做法,就是通过GraalVM实现本地编译,从而甩来HotSpot。 那么,针对Java不适用于微服务的现状,让我们跳出Java圈,IT圈的大佬们是想如何解决的呢? 解决问题的流派 解决问题的方法大致有如下几种: 在上图中,后两种主要是更为靠谱的。 至于采取第二种还是第三种,那不同的厂商显然会有自己的思路。 从技术角度看:传统的Java应用改造成GraalVM Native还是有难度的。 Quarkus是红帽主导发布的新一代云原生Java。Quarkus确实面临重新书写应用的问题。从红帽的角度,传统的应用与其向GraalVM Native迁移,不如向基于K8S的轻量级应用服务器JBoss EAP迁移更为靠谱(后面也会给出介绍)。 Quarkus红帽在2020年正式GA(开源项目去年发布),目前github上有5000个Star,还算不错。 Quarkus的框架 Quarkus的框架如下, 由于Quarkus依赖GraalVM CE,而GraalVM CE是由Oracle发布的。因此红帽发布了GraalVM CE的下游社区:Mandrel。通过Mandrel红帽将GraalVM特性集成在在Red Hat Enterprise Linux和OpenJDK 11发行版上,以便红帽可以对此提供企业级支持。 Quarkus的一个特点是包含很多扩展。Quarkers 的扩展是一组依赖项,可以将它们添加到 Quarkus 项目中,从而获得特定的功能,例如健康检查等。扩展将配置或引导框架或技术集成到 Quarkus 应用程序中。通过命令行可以列出 Quarkers 可用和支持的扩展: 此外,Quarkus还有个优势是:支持热加载。即以开发模式启动应用后,修改应用源代码无需重新编译和重新运行,应用而直接生效。如果是 web 应用,在前台刷新浏览器即可看到更新结果。Quarkus 的开发模式非常适合应用调试阶段、经常需要调整源码并验证效果的需求。 Quarkus还可以和Kafka对接(后面其他文章会介绍)。 Quarkus具体的实战内容,可以参照笔者在IBM官网发表的文章: https://www.ibm.com/developerworks/cn/cloud/library/cl-lo-quarkus-supersonic-subatomic-java-experience/index.html 根据IDC在2020年5月份发布的数据,Quarkus Native比其他框架节约64%的云资源。如果运行在JVM模式,可以节约37%的资源。 Quarkus Native运行只需要21M内存 在基于AWS部署的OpenShift4.2上运行10个pod,消耗内存的对比: 吞吐量对比: 实例扩容所需时间对比: 启动时间对比: GraalVM的限制 GraalVM的限制如下链接所示:有的需要配置才能实现,因此在开发时应注意这些限制。 https://github.com/oracle/graal/blob/master/substratevm/LIMITATIONS.md Dynamic Class Loading / Unloading Runtime Bytecode Generation * InvokeDynamic Bytecode and Method Handles Finalizers Serialization Security Manager JVMTI、JVMCI,other native VM interfaces 传统应用向JBoss EAP迁移的步骤 针对客户现有的运行在传统应用服务器上(如WebLogic)的应用,如何迁移到JBossEAP上呢?我们可以借助Red Hat Application MigrationToolkit(简称:RHAMT) RHAMT是开放源代码工具的组合,可实现大规模的应用程序迁移和现代化。该工具由多个单独的组件组成,这些组件为迁移过程的每个阶段提供支持。支持的迁移包括应用程序平台升级、向云原生部署环境的迁移、以及从几种商业应用服务器到JBoss EAP的迁移。 RHAMT提供三种软件包下载: COMMAND LINETOOLING:命令行界面提供了一个高级界面,用于以自动化方式对许多应用程序进行批处理分析。该界面可以提供详细的评估报告,这些报告可以纳入对应用程序的完整评估中,以便进行优先级排序和规划。 WEB CONSOLE:Web控制台提供简化的界面,用于管理大量应用程序以进行评估和分析。使用此工具,用户可以管理大量应用程序,以便有效地确定优先级并计划要迁移的应用程序,并评估每次迁移所涉及的难度。 IDE TOOLING:IDE插件为开发人员提供了交互式的实施时间帮助。通过提供内联帮助以及使迁移和现代化过程中的复杂步骤自动化的全自动快速修复程序,这简化了应用程序的迁移过程。 我们查看工具下载界面(https://developers.redhat.com/products/rhamt/download), 我们先下载CLI工具。安装CLI工具的系统需要安装JavaSE Development Kit(JDK)版本8,我们建议使用OpenJDK或OracleJDK。 安装RHAMTCLI工具很简单,直接解压缩即可: # unzipmigrationtoolkit-rhamt-cli-4.3.1-offline.zip 接下来,我们展示如何运行CLI来分析示例WebLogic应用程序,以识别将其迁移到JBossEAP 7所需的更改。示例程序为:simple-sample-app.ear(下载地址为:https://github.com/ocp-msa-devops/RHAMT.git) 执行如下命令: # ./rhamt-cli-4.3.1.Final/bin/rhamt-cli--input ./simple-sample-app.ear --output --source weblogic --target eap:7--packages com.acme 此命令使用以下选项: --input:要分析的应用程序的路径。 --output:生成的报告的输出目录。 --source:应用程序的源技术。 --target:用于应用程序迁移的目标技术。 --packages:要评估的软件包列表。 命令执行结果如图显示的名为index.html的评估报告。 针对报告指出的问题进行调整: 将报告提示的问题点修改完毕后,再次运行报告,确保story points为0 源码修改成功后,重新打包应用,然后使用OpenShift上的JBoss EAP Builder Image进行应用容器化即可。 结论 针对云原生Java这个话题,红帽推荐的方案是Quarkus。Quarkus可以运行在Hospot或GraalVM上。至于选择哪种,需要参照GraalVM自身的限制。Quarkus+GraalVM+AOT是应用所需资源最少、启动最快的方式。 针对传统的应用,既可以迁移到轻量级的应用服务器如EAP上,也可以将遗留代码升级成GraalVMNative应用。这两种方法都可以,这取决于客户传统应用的复杂度和规划。 参考文档: https://developers.redhat.com/blog/2020/06/05/mandrel-a-community-distribution-of-graalvm-for-the-red-hat-build-of-quarkus/ 本文分享自微信公众号 - 大魏分享(david-share)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

优秀的个人博客,低调大师

2019年APT回顾与思考

在这一年里,APT进行了哪些活动?我们可以从中学到什么? 这不是一个容易回答的问题,因为研究人员对APT攻击活动只有部分的可见性,不可能完全理解某些攻击的动机。不过从不同的角度来探讨这个问题,可以更好的理解发生了什么,从中获得更多的经验。 供应链攻击 近年来,针对供应链的攻击已经被证明是非常成功的,例子包括ShadowPad、expertr和CCleaner的后门。 今年1月发现了一个复杂的供应链攻击,涉及一个硬件供应商,攻击者向供应商的笔记本电脑和台式机提供BIOS、UEFI和软件更新。攻击者向供应商的程序添加了一个后门,通过官方渠道将其分发给用户。攻击者将目标MAC地址列表硬编码到木马中,从攻击中发现超过200个样本中提取超过600个唯一的MAC地址,具体分析报告:ShadowHammer 泄密事件 第三季度针对伊朗活动的APT泄密事件。 今年3月,有人通过Dookhtegan或Labúu Dookhtegan开始使用标签apt34在Twitter上发布消息。他们分享了几个文件,其中包括几名黑客受害者的登录名和密码、工具、基础设施的详细信息、攻击者的简历和一份2014-2018年期间网络工具清单。 4月22日,名为Bl4ck_B0X创建了GreenLeakers频道。该频道的目的是发布有关MuddyWater APT组成员信息。除了免费信息,Bl4ck_B0X也将出售与MuddyWater有关的“高度机密”信息。4月27日,GreenLeakers Telegram频道发布了三张截图,其中包含来自MuddyWater C2服务器的截图。5月1日,该频道对公众关闭,改为私人频道,关闭的原因仍然不清楚。 最后,一个名为“隐藏现实”的网站公布了与伊朗拉纳研究所有关的泄密信息。这是两个月来第三次披露伊朗组织的细节。这次泄密与其他泄密不同,它允许任何人浏览泄密文件的网站。网站包含内部文档、聊天信息和其他与拉纳研究所的CNO(计算机网络操作)能力相关的数据,以及有关受害者的信息。以前的泄漏更多地集中在工具、源代码和参与者信息上。 Shadow Brokers Shadow Brokers中包括一个Python脚本sigs.py,其中许多函数来检查系统是否已经被其他攻击者破坏。每个检查都是在系统中查找唯一签名实现的,sigs.py列出了44个条目,其中许多与尚未公开的未知apt相关。 2019年sigs.py文件的第27个函数,被命名为DarkUniverse,DarkUniverse与ItaDuke活动有关,存在代码重叠。主要组件是一个简单的DLL,只有一个导出函数,实现持久控制、与C2的通信以及对其他模块的控制。在西亚和非洲东北部发现了大约20名受害者,包括医疗机构、原子能机构、军事组织和电信公司。 手机攻击 移动手机攻击是许多APT工具集的标准部分。 今年5月,英国《金融时报》报道称,黑客利用WhatsApp的零日漏洞窃听用户,读取加密的聊天,打开麦克风和摄像头,安装间谍软件,甚至可以进行进一步的监控。WhatsApp触发缓冲区溢出,使攻击者能够控制应用程序并执行任意代码,WhatsApp很快就发布了漏洞补丁。10月份,该公司提起诉讼,指控总部位于以色列的NSO挖掘利用了这一漏洞。WhatsApp声称,NSO出售的这项技术用于瞄准20个不同国家1400多名客户的手机,其中包括人权活动家、记者和其他人。 今年7月,报告介绍了2018年开发的针对Android和iOS的FinSpy最新版本。FinSpy的开发者将该软件出售给世界各地的政府和执法机构,这些机构使用该软件在各种平台上收集私人用户信息,如联系人、信息、电子邮件、日历、GPS位置、照片、内存中的文件、电话录音和数据。Android植入需要通过已知漏洞获得root权限,在设备尚未越狱的情况下,需要对受害者的设备进行物理访问。最新版本包含了多个新功能。在最近的研究中,在近20个国家的中检测到了最新版本,真正的受害者人数可能要高得多。 今年8月,谷歌Project Zero团队发布了一份在野发现的至少14个iOS 零日分析报告,攻击者在5个攻击链中使用以提升权限。攻击者自三年前使用了一些被控网站来作为攻击平台。虽然没有关于网站的详细信息,也没有说明这些网站是否仍然活跃,但谷歌称这些网站“每周有数千名访客”。 今年9月,零日经纪公司Zerodium表示,Android的零日价值已超过iOS,该公司愿意花250万美元购买Android的零日,该公司此前为远程iOS越狱支付200万美元。相比之下,Zerodium还减少了苹果一键式攻击的支出。同一天,有人在v412(Video4Linux)驱动程序中发现了一个高严重性的零日。谷歌9月份的安全更新中没有包含此漏洞,该漏洞可能会导致权限提升。几天后,安卓系统的一个缺陷被发现,使得超过10亿的三星、华为、LG和索尼智能手机容易受到攻击,攻击者能够使用短信完全访问设备上的电子邮件。 工具持续改良 1. Turla 在调查中亚地区的恶意活动时发现了一个名为Tunnus新的后门,其归属于Turla组织。它基于.NET的恶意软件,能够在受感染的系统上运行命令或文件操作,并将结果发送到C2。到目前为止,攻击者已用有漏洞的WordPress安装构建了其C2基础设施。 今年,Turla还将其JavaScript KopiLuwak恶意软件封装在一个名为Topinambour的dropper中,Topinambour是一个新的.NET文件,攻击者使用该文件通过受感染的vpn等合法软件程序的安装包传播和植入KopiLuwak。该恶意软件几乎完全“无文件”:感染的最后阶段,一个用于远程管理的加密木马被嵌入到计算机的注册表中,以便后期访问。该组织使用两种类似的KopiLuwak(即.NET RocketMan木马和PowerShell MiamiBeach木马)进行网络间谍活动。 此外还发现一个新的COMpfun恶意软件。攻击者在将原始COMpfun用作下载程序,根据一些样本中留下的a.pdb路径命名它为Reductor。攻击者花费了大量精力来操作Reducer中的数字根证书,并使用唯一的主机相关标识符标记出站TLS通信。该恶意软件将嵌入的根证书添加到目标主机,并允许攻击者通过管道远程添加其他证书。 2. Zebrocy Zebrocy继续使用各种编程语言向其库中添加新工具。Zebrocy在东南亚一个外交组织内部署了一个编译好的PythocyDbg脚本。该模块主要提供网络代理和通信调试功能进行情报秘密收集。2019年初,Zebrocy使用Nimrod/Nim(一种语法类似于Pascal和Python的编程语言,可以编译成JavaScript或C)。今年9月,Zebrocy spear在欧洲各地对北约等多个目标进行网络钓鱼,试图获取电子邮件通信、凭据和敏感文件。与Zebrocy以往的活动类似,在电子邮件中使用与目标相关的内容,并压缩包含无害文档附件,以及带有相同文件名的可执行文件。该组还利用Word模板从合法的Dropbox文件共享站点中获取文件。 3. Platinum 今年6月发现了一组不寻常的样本,其主要针对南亚和东南亚国家的外交、政府和军事组织,最终将其归属于Platinum,Platinum是技术最先进的APT之一。在这次行动中,攻击者使用了精心设计的隐写技术来隐藏通信。今年晚些时候,在一次网络攻击活动中,发现了Platinum组织使用的新的后门Titanium,这个恶意软件和ProjectC的工具集有相似之处,在2016年检测到ProjectC被用作横向移动的工具集。 4. Lazarus 在2018年AppleJeus报告的主要发现是Lazarus组织瞄准Mac OS系统。从那时起Lazarus扩大了他们的业务范围。今年又发现了新的活动,以苹果的客户为目标利用PowerShell来控制Windows系统和Mac OS恶意软件。Lazarus还瞄准了韩国的一家移动游戏公司,其目的是窃取应用程序源代码。Lazarus一直在快速更新它的工具。 Andariel是Lazarus的一个子组织,专注于韩国的地缘政治和金融情报。攻击者利用存在漏洞的Weblogic服务器构建C2,在样本使用的是CVE-2017-10271。成功突破后,攻击者植入有韩国安全软件供应商合法签名的恶意软件。这个恶意软件是一个后门,叫做ApolloZeus。这个后门使用了一个相对较大的外壳代码,使分析变得困难。此外还找到了几个相关的样本,以及攻击者用来传播它的文档。 5. BlueNoroff 在第三季度跟踪了BlueNoroff的新活动,确认了受害者是缅甸的一家银行。研究人员立即与银行联系,分享已经发现的IOC,并获得攻击者横向移动工具。攻击者使用公共登录凭据转储程序和自制的PowerShell脚本进行横向移动。BlueNoroff还使用了一种新结构恶意软件,可以减慢分析速度。根据命令行参数的不同,此恶意软件可以作为后门或隧道。此外还发现了另一种类型的PowerShell脚本,其主要目标为土耳其,这个PowerShell脚本的功能与之前使用的类似,但BlueNoroff不断地更改它以逃避检测。 6. DarkHotel 今年10月偶然发现一个样本,使用的诱饵文件和图片中包含朝鲜海外居民的联系名单,所有的诱饵都包含朝鲜半岛国庆节和朝鲜国庆节的内容,内容还涉及外交问题和商业关系。攻击者利用鱼叉钓鱼和多阶段感染,植入量身定制的恶意软件。研究发现该攻击活动归属于DarkHotel APT组织。 7. Lamberts Lamberts是一个或多个攻击者使用的复杂攻击工具家族。武器库包括网络驱动后门、模块化后门、破坏性攻击等。Silver Lambert是Gray Lambert的升级,它是一个成熟的后门,在中国的航空部门发现了他的踪迹。Violet Lambert是一款模块化后门,于2018年开发和部署,可在各种版本的Windows上运行,包括Windows XP,以及Vista和更高版本的Windows。还在中东一个重要基础设施的电脑上发现了其他新的Lamberts后门,这个恶意软件在网络上监听,等待一个ping命令,然后执行一个我们无法解密的负载,后门发现后不久,所有受感染的电脑都离线了。 8. LuckyMouse 今年早些时候监测到了由LuckyMouse发起的活动,该活动至少从2018年4月起就针对越南政府和海外外交。他们利用网络服务漏洞作为其主要的初始感染切入点,同时在网络钓鱼消息中使用的诱饵文件,显示了其灵活使用运营商。攻击者还将HTran-TCP代理源代码包含到恶意软件中,重定向流量。一些NetBot配置数据包含LAN ip,它从本地网络中另一个受感染的主机下载下一阶段程序。根据检测内部数据库服务器是目标之一。最后一步,攻击者使用32位和64位木马注入系统进程内存。 从2019年初开始,在中亚和中东LuckyMouse的活动都出现了高峰。攻击者目标集中在电信运营商,大学和政府,通过直接攻击、鱼叉式网络钓鱼,水坑攻击等手段。 9. HoneyMyte HoneyMyte已经活跃了好几年了。在过去几年中,该组织采用了不同的技术实施攻击,目标是缅甸、蒙古、埃塞俄比亚、越南和孟加拉国的政府,以及位于巴基斯坦、韩国、美国、英国、比利时、尼泊尔、澳大利亚和新加坡外国大使馆。今年,该组织的目标是缅甸与自然资源管理有关的政府组织和一个非洲大陆组织,其主要动机之一是收集地缘政治和经济情报。 10. Icefog 自2011年以来Icefog目标一直是主要位于韩国、日本和中亚的政府机构、军事承包商、海事和造船组织、电信运营商、卫星运营商、工业和高科技公司以及大众媒体。2013年该组织的行动速度放缓,2016略有增加,从2018年初开始Icefog开始对中亚政府机构和军事承包商进行大规模攻击。在最新一波的攻击中,感染源于一封包含恶意文档的钓鱼邮件,该邮件利用已知漏洞攻击并最终部署有效负载。 从2018年到2019年初,有效载荷是典型的Icefog后门。自2019年5月以来,攻击者把Poison Ivy作为他们的主要后门。Poison Ivy利用“load order hijacking”技术加载恶意DLL,这项技术非常普遍,在以前的Icefog攻击活动中也使用过。另外还检测到使用从GitHub下载的TCP扫描器、Mimikatz变体、键盘记录器以及Quarian的后门。Quarian后门用于在受害者基础设施内创建隧道,以避免网络检测,其功能包括操作远程文件系统、获取有关受害者的信息、窃取保存的密码、下载或上载任意文件、使用端口转发创建隧道、执行任意命令和启动反向shell。 “新来者”的演变 1. ShaggyPather 在2018年1月的一份报告中讨论了ShaggyPather,这是一个以前未被发现的针对台湾和马来西亚的恶意软件。相关的活动可以追溯到十多年前,类似的代码编译时间为2004年。最近一次活动是在7月份印度尼西亚,以及在3月份叙利亚。较新的2018年和2019年后门代码添加了新的混淆,不再保持明文C2字符串。其使用的外壳SinoChopper不仅执行主机识别和后门传递,还执行电子邮件窃取和其他活动。 2. TajMahal 今年4月,研究人员发布了关于TajMahal的报告,TajMahal是一个未发现的APT框架,在过去五年中一直处于活跃状态。它是一个高度复杂的间谍软件框架,包括后门、加载程序、C2通信程序、录音机、键盘记录器、屏幕和网络摄像头抓取程序、文档和密码密钥窃取程序和文件索引器,其加密文件系统中发现了多达80个恶意模块,这是APT工具集中见过的数量最多之一。该恶意软件有两个不同的软件包,自称Tokyo和Yokohama,攻击者利用Tokyo作为第一阶段感染,在目标受害者身上部署功能齐全的Yokohama。检测显示只有一个受害者,来自中亚国家的外交机构,研究人员认为可能还有其他的受害者还没有找到。 3. FrutiyArmor和SandCat 今年2月检测到有人试图利用Windows中的漏洞进行攻击,进一步的分析发现win32k.sys中存在一个零日漏洞,FruityArmor和SandCat利用了这一漏洞。FrutiyArmor和SandCat攻击活动各不相同,两者同时使用相同的漏洞,似乎表明存在第三方为他们提供漏洞。 4. 未明确攻击者 2019年2月发现俄罗斯南部发生了一次目标明确的攻击,其使用名为Cloudmid的未知恶意软件。这个间谍程序通过电子邮件传播,伪装成俄罗斯一家知名安全公司的VPN客户端。到目前为止还无法将此活动与任何已知攻击者联系起来。恶意软件本身是一个简单的文件偷取程序。 今年2月发现了一场针对印度军事组织的行动,但无法将其归属于任何已知的攻击者。攻击者依靠水坑和鱼叉钓鱼来感染受害者。他们能够破坏陆战研究中心(CLAWS)的网站,利用该网站托管一份恶意文件来分发Netwire RAT。 5. DADJOKE 在第三季度发现了DADJOKE的恶意软件活动。该恶意软件于2019年1月首次在野使用,随后不断发展。自今年1月以来只在少数活动中见过这种恶意软件,这些活动的目标都是东南亚地区的政府、军事和外交。最近的一次是在8月份,针对某个军事组织的工作人员。 隐私问题 1月17日,安全研究员Troy Hunt报告称,有超过7.73亿封电子邮件和2100万条密码记录泄露。这些数据被称为Collection#1,最初是在云服务MEGA上共享的。Collection#1只是约1tb数据泄漏的一小部分,总数据分成7部分,通过数据交易论坛分发。Collection#1只是大量泄露凭证的一部分,其中包括22亿个被盗账户记录。 2月份又发生了数据泄露事件。黑客从16家公司盗取的6.17亿个账户详细信息在DreamMarket出售。黑客攻击的公司包括Dubsmash、MyFitnessPal、Armor Games和CoffeeMeetsBagel。随后,又有8家公司的数据被发布到同一个市场。在3月份黑客又发布了另外6家公司的被盗数据。 新闻中关于电子邮件地址和密码泄露的源源不断的报道,这种“传统”认证形式的失窃会导致严重的后果,但其他认证方法的泄密影响可能会更严重。今年8月,两名以色列研究人员在一个可公开访问的数据库中发现了Suprema Biostar 2生物控制系统的指纹、面部识别数据和其他个人信息。生物测数据的泄露尤其令人关注。泄露的密码可以更改,但生物特征是终身的。 智能设备在我生活新领域中的广泛使用为攻击者提供了一个更大的数据池。例如智能扬声器在家里可监听谈话的影响。社交媒体巨头正拥有越来越多的个人信息,这些信息对犯罪分子和APT组织都是非常有价值的。

优秀的个人博客,低调大师

业务开发的思考与提升

业务开发:永远被业务驱使或者强奸,越来越忙,支持业务越来越疲于奔命。产品、业务上线快,bug也很多。 这可能是大多数业务开发的写照吧,换了份工作之后,自己也是一直在写业务相关的东西,想说说最近业务开发的经历 每天都在做什么 经常做的是熟悉需求、梳理业务、新的,旧的系统功能点、讨论、写代码。而写业务代码,基本上用到的都是公司封装好的框架,使用起来简化了很多开发步骤,并且根基本上是参照之前代码的写法。 熟悉需求,肯定要做新功能啊,但是新功能从最老大的哪里提出来,产品梳理好之后告诉我们,开发不在第一线,产品与开发各自分工,文档给了开发,要做功能,只有梳理需求,需求文档基本上在整个开发过程都用得到。 梳理业务,新员工都要熟悉公司的业务,时间比较久的公司业务复杂,所以需要梳理。 新、旧系统功能点,也在和梳理业务,需求有很密切的关系,旧系统的功能是超级多的,有需要的都要看。新功能要理 讨论,需求宣讲会,功能点讨论,设计方案讨论等, 完全取决于会议是否高效 写代码,比重不是很大,但一切都要落实到代码上,写代码才能实现需求啊。 总的感觉,不是像网上传的天天码代码,熬夜加班, 这里基本不存在。反而觉得写业务代码太简单...梳理流程重要而且复杂,麻烦。 写业务代码对技术要求不高,公司提供的基础设施比较丰富。 既然是业务开发,那就是业务很复杂,觉得都在试着理解业务。业务代码一个旧的模块几十万行代码,几百个对外服务接口,调用其它模块也很多。而重构是我们要做的事,梳理几十万行代码。 如何提升自己 业务方面每个公司的业务都不同,而写业务代码技术不会有太多提高,所有的业务依赖的都是技术。 提升技术能力,研究轮子,自己造轮子,或造产品 提升对业务的理解能力,如下建议,优化业务架构 业务开发:除了满足产品提出的各种需求外,需要给留20%-40%的时间(用加班也行),想着怎样优化本身的业务架构:如怎样提升原来设计不合理的架构,优化之,提升稳定性、性能(容量)。一些通用的架构,需要提交到架构组,讨论方案。个人认为,能满足未来至少3年以上需求的架构方案,才算合格。 针对自己的情况,我时间还算过得去,这些时间取决于自己怎么利用,最终会产生不同的结果 早上:7点30左右到公司,到9点的时候都可以试着钻研一些技术相关的东西 晚上:20点多点以后基本上都是自己的时间 坚持做一件有意义的能让自己成长的事吧 最后 共勉,早日实现程序员的百万年薪!

优秀的个人博客,低调大师

架构设计的几点思考

软件架构的意义 软件架构的意义是什么,有很多不同的理解和争议,这里不想就软件架构的意义给出完整的定义,而是想聊聊其中的一点:软件架构是沟通 (Architecture is communication),关于软件架构的更多意义,建议参考这篇别人的旧文。 为什么软件架构意味着沟通呢?因为软件工程本身是一个组织一群人为了一个问题进行创造性劳动的过程,因为软件工程本身的特点,所以沟通的重要性是软件工程区别于传统工程的一个显著特点。关于这一点,我之前的帖子已经解释过,这里不再展开。 什么样的架构有利于沟通呢? 在回答这个问题之前,我们先来看一张图。 如果汽车设计师通过这张图来向其他人解释汽车是什么的时候,我想除了相关的专家不会有人能够轻易理解每个部件在整个汽车中的用途,以及他们是如何在一起工作的。 为什么呢?在《金字塔原理》这本书里提到,人一次能够理

优秀的个人博客,低调大师

思考gRPC :为什么是protobuf

背景 谈到RPC,就避免不了序列化的话题。 gRPC默认的序列化方式是protobuf,原因很简单,因为两者都是google发明的,哈哈。 在当初Google开源protobuf时,很多人就期待是否能把RPC的实现也一起开源出来。没想到最终出来的是gRPC,终于补全了这一块。 跨语言的序列化方案 事实上的跨语言序列化方案只有三个: protobuf, thrift, json。 json体积太大,并且缺少类型信息,实际上只用在RESTful接口上,并没有看到RPC框架会默认选json做序列化的。 国内一些大公司的使用情况: protobuf ,腾迅,百度等 thrift,小米,美团等 hessian, 阿里用的是自己维护的版本,有js/cpp的实现,因为阿里主用java,更多是历史原因。 序列化里的类型信息 序列化就是把对象转换为二进制数据,反序列化就把二进制数据转换为对象。 各种序列化库层出不穷,其中有一个重要的区别:类型信息存放在哪? 可以分为三种: 不保存类型信息 典型的是各种json序列化库,优点是灵活,缺点是使用的双方都要知道类型是什么。当然有一些json库会提供一些扩展,偷偷把类型信息插入到json里。 类型信息保存到序列化结果里 比如java自带的序列化,hessian等。缺点是类型信息冗余。比如RPC里每一个request都要带上类型。因此有一种常见的RPC优化手段就是两端协商之后,后续的请求不需要再带上类型信息。 在生成代码里带上类型信息 通常是在IDL文件里写好package和类名,生成的代码直接就有了类型信息。比如protobuf, thrift。缺点是需要生成代码,双方都要知道IDL文件。 类型信息看起来是一个小事,但在安全上却会出大问题,后面会讨论。 实际使用中序列化有哪些问题 这里讨论的是没有IDL定义的序列化方案,比如java自带的序列化,hessian, 各种json库。 大小莫名增加,比如用户不小心向map里put了大对象。 对象之间互相引用,用户根本不清楚序列化到底会产生什么结果,可能新加一个field就不小心被序列化了 enum类新增加的不能识别,当两端的类版本不一致时就会出错 哪些字段应该跳过序列化 ,不同的库都有不同的 @Ignore ,没有通用的方案 很容易把一些奇怪的类传过来,然后对端报ClassNotFoundException 新版本jdk新增加的类不支持,需要序列化库不断升级,如果没人维护就悲剧了 库本身的代码质量不高,或者API设计不好容易出错,比如kryo gRPC是protobuf的一个插件 以gRPC官方的Demo为例: package helloworld; // The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. message HelloRequest { string name = 1; } // The response message containing the greetings message HelloReply { string message = 1; } 可以看到rpc的定义也是写在proto文件里的。实际上gRPC是protobuf的一个扩展,通过扩展生成gRPC相关的代码。 protobuf并不是完美解决方案 在protobuf出来以后,也不断出现新的方案。比如 https://github.com/capnproto/capnproto https://github.com/google/flatbuffers https://avro.apache.org/ protobuf的一些缺点: 缺少map/set的支持(proto3支持map) Varint编码会消耗CPU 会影响CPU缓存,比如比较大的int32从4字节用Varint表示是5字节就不对齐了 解码时要复制一份内存,不能做原地内存引用的优化 protobuf在google 2008年公开的,内部使用自然更早。当时带宽还比较昂贵,现在人们对速度的关注胜过带宽了。 protobuf需要生成代码的确有点麻烦,所以会有基于java annotation的方案: https://github.com/protostuff/protostuff 同样thrift有: https://github.com/facebookarchive/swift 序列化被人忽视的安全性问题 序列化漏洞危害很大 序列化漏洞通常比较严重,容易造成任意代码执行 序列化漏洞在很多语言里都会有,比如Python Pickle序列化漏洞。 很多程序员不理解为什么反序列化可以造成任意代码执行。 反序列化漏洞到底是怎么工作的呢?很难直接描述清楚,这些漏洞都有很精巧的设计,把多个地方的代码串联起来。可以参考这个demo,跑起来调试下就可以有直观的印象: https://github.com/hengyunabc/dubbo-apache-commons-collections-bug 这里有两个生成java序列化漏洞代码的工具: https://github.com/frohoff/ysoserial https://github.com/mbechler/marshalsec 常见的库怎样防止反序列化漏洞 下面来看下常见的序列化方案是怎么防止反序列化漏洞的: Java Serialization jdk里增加了一个filter机制 http://openjdk.java.net/jeps/290 ,这个一开始是出现在jdk9上的,后面移值回jdk6/7/8上,如果安装的jdk版本是比较新的,可以找到相关的类 Oracle打算废除java序列化:https://www.infoworld.com/article/3275924/java/oracle-plans-to-dump-risky-java-serialization.html jackson-databind jackson-databind里是过滤掉一些已知的类,参见SubTypeValidator.java jackson-databind的CVE issue列表 fastjson fastjson通过一个denyList来过滤掉一些危险类的package,参见ParserConfig.java fastjson在新版本里denyList改为通过hashcode来隐藏掉package信息,但通过这个DenyTest5可以知道还是过滤掉常见危险类的package fastjson在新版本里默认把autoType的功能禁止掉了 所以总结下来,要么白名单,要么黑名单。当然黑名单机制不能及时更新,业务方得不断升jar包,非常蛋疼。白名单是比较彻底的解决方案。 为什么protobuf没有序列化漏洞 这些序列化漏洞的根本原因是:没有控制序列化的类型范围 为什么在protobuf里并没有这些反序列化问题? protobuf在IDL里定义好了package范围 protobuf的代码都是自动生成的,怎么处理二进制数据都是固定的 protobuf把一切都框住了,少了灵活性,自然就少漏洞。 总结 应该重视反序列化漏洞,毕竟Oracle都不得不考虑把java序列化废弃了 序列化漏洞的根本原因是:没有控制序列化的类型范围 防止序列化漏洞,最好是使用白名单 protobuf通过IDL生成代码,严格控制了类型范围 protobuf不是完美的方案,但是作为跨语言的序列化事实方案之一,IDL生成代码比较麻烦也不是啥大问题 链接 https://github.com/protostuff/protostuff https://github.com/facebookarchive/swift http://openjdk.java.net/jeps/290 https://www.infoworld.com/article/3275924/java/oracle-plans-to-dump-risky-java-serialization.html

优秀的个人博客,低调大师

C++ 枚举类型的思考

C++ 中的枚举类型继承于 C 语言。就像其他从 C 语言继承过来的很多特性一样,C++ 枚举也有缺点,这其中最显著的莫过于作用域问题——在枚举类型中定义的常量,属于定义枚举的作用域,而不属于这个枚举类型。例如下面的示例: enum FileAccess { Read = 0x1, Write = 0x2, }; FileAccess access = ::Read; // 正确 FileAccess access = FileAccess::Read; // 错误 C++枚举的这个特点对于习惯面向对象和作用域概念的人来说是不可接受的。首先,FileAccess::Read 显然更加符合程序员的直觉,因为上面的枚举定义理应等价于如下的定义(实际上,.NET 中的枚举类型便是如此实现的): class FileAccess { static const int Read = 0x1; static const int Write = 0x2; }; 其次,这导致我们无法在同一个作用域中定义两个同样名称的枚举值。也就是说,以下的代码是编译错误: enum FileAccess { Read = 0x1, Write = 0x2, }; enum FileShare { Read = 0x1, // 重定义 Write = 0x2, // 重定义 }; 如果这一点没有让你恼怒过的话,你可能还没写过多少 C++ 代码 :-)。实际上,在最新的 C++0x 标准草案中有关于枚举作用域问题的提案,但最终的解决方案会是怎样的就无法未卜先知了,毕竟对于象 C++ 这样使用广泛的语言来说,任何特性的增删和修改都必须十分小心谨慎。 当然,我们可以使用一些迂回的方法来解决这个问题(C++ 总是能给我们很多惊喜和意外)。例如,我们可以把枚举值放在一个结构里,并使用运算符重载来逼近枚举的特性: struct FileAccess { enum __Enum { Read = 0x1, Write = 0x2 }; __Enum _value; // 枚举值 FileAccess(int value = 0) : _value((__Enum)value) {} FileAccess& operator=(int value) { this->_value = (__Enum)value; return *this; } operator int() const { return this->_value; } }; 我们现在可以按照希望的方式使用这个枚举类型: FileAccess access = FileAccess::Read; 并且,因为我们提供了到 int 类型的转换运算符,因此在需要 int 的地方都可以使用它,例如 switch 语句: switch (access) { case FileAccess::Read: break; case FileAccess::Write: break; } 当然我们不愿意每次都手工编写这样的结构。通过使用宏,我们可以很容易做到这一点: #define DECLARE_ENUM(E) \ struct E \ { \ public: \ E(int value = 0) : _value((__Enum)value) { \ } \ E& operator=(int value) { \ this->_value = (__Enum)value; \ return *this; \ } \ operator int() const { \ return this->_value; \ } \ \ enum __Enum { #define END_ENUM() \ }; \ \ private: \ __Enum _value; \ }; 我们现在可以按如下的方式定义前面的枚举,并且不比直接写 enum 复杂多少。 DECLARE_ENUM(FileAccess) Read = 0x1, Write = 0x2, END_ENUM() DECLARE_ENUM(FileShare) Read = 0x1, Write = 0x2, END_ENUM() ============================================================================== 本文转自被遗忘的博客园博客,原文链接:http://www.cnblogs.com/rollenholt/archive/2012/03/19/2405456.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

云计算热的深思考

自2015年下半年开始,全球云计算市场所爆发出的强劲增长势头令人惊艳。微软、亚马逊、谷歌等科技巨头的最新财报显示,云计算业务已成为稳定的增长点。微软方面,云服务已经超越了Windows业务成为其主要营收来源;亚马逊方面,云服务是其最赚钱的业务,第三季度营业收入8.61亿美元,同比增长超50%,利润率稳定在26%;谷歌方面,非广告营收的增长主要来自于云业务的贡献。国内企业中,阿里巴巴的最新财报显示,阿里云的业绩非常耀眼,营收达到14.93亿元,同比增长130%,连续第六个季度增幅领跑全球。 来自工信部的数据显示,2015年中国云计算产业规模约为1500亿元,年增长率超过30%,是全球增速最快的市场之一。在《国务院关于促进云计算创新发展培育信息产业新业态的意见》《云计算综合标准化体系建设指南》等政策利好刺激下,我国云计算产业进入了应用迅速普及阶段,在促进互联网和实体经济深度融合发展,以信息流带动技术流、资金流、人才流、物资流,调整产业结构、转变经济发展方式等方面,发挥了积极的作用。 近年来各地云计算中心蓬勃发展,据不完全统计,全国共有20多个省区市提出了要打造云计算产业园区。但一个值得警惕的倾向是:重设施、轻应用,不少云计算产业基地缺乏实质性的应用服务,只能靠出租硬盘空间为主业,甚至打起了价格战。发展云计算产业,不应仅仅停留于硬件建设层面;如果没有针对各个行业用户推出的精准化服务,空有设备而没有真正的应用落地,将导致产业虚火上升。 发展云计算产业,首先要因地制宜。拿呼和浩特来说,其自然条件就非常适宜。年平均气温8摄氏度,一年有6个月时间能够使用自然源进行数据中心设备冷却,有利于降低运营成本。同时电力资源丰富且保障充足,电价可享受每千瓦时0.26元的优惠,形成了极具竞争力的综合成本优势。 其次,要积极探索开展行业应用,推动云计算与大数据的深度融合。推动云计算为代表的新一代信息技术和现代制造业的深度融合,积极培育形成新业态、新模式。呼和浩特云计算产业园区已吸引了三大电信运营商、阿里巴巴、腾讯、百度、浪潮等一批知名云计算企业入驻,在智慧城市、电子商务、信息惠民、畜牧大宗商品、乳业、电力、电商物流等领域开展了大数据深度应用的实践探索。 再者,要加快突破核心技术,构建高水平云计算服务平台。“云计算+大数据+人工智能”三位一体的定位已经非常清晰,机器学习、深度学习等人工智能算法的云端化成为行业发展的必然趋势。如果说云计算的1.0主打分布式的计算资源,那么2.0就是出租人工智能驱动的计算资源,数据、算法、计算资源缺一不可。 尽管云计算产业在我国发展很快,但从产业规模看,我国占全球云计算市场的份额仍不到5%;从服务能力看,我国云计算企业规模普遍较小,提供的服务种类有限,一些关键行业尚没有成熟的云计算解决方案。10月8日,国家批复在内蒙古推进国家大数据综合试验区,内蒙古发展云计算大数据产业可谓正逢其时。只要先行者创新各种新技术、新应用、新模式,在现代制造业特别是工业云、智能制造、工业互联网和工业大数据等方面重点投入,发挥政府引导作用,相信会给云计算大数据产业健康有序发展提供更好的范本。 本文作者:佚名 来源:51CTO

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册