• 把握新时代,英飞凌以eSIM全力驱动物联网创新

                        出品?21ic中国电子网 蔡璐 网站:21ic.com 众所周知,SIM卡是移动通信中不可或缺的组成部分。但是,随着物联网时代的到来,智能终端的设备类型和应用场景越来越多,这种传统的插拔式SIM卡已经无法满足物联网各种极端条件下的通信要求了。在此背景下,eSIM技术应运而生,许多厂商都推出了全新一代的eSIM解决方案。 那么,eSIM具有哪些优势?这一技术又是如何推动物联网发展的?作为厂商,应该如何提升物联网应用能力?带着这些问题,21ic中国电子网记者采访了英飞凌科技数字安全解决方案事业部大中华区物联网安全产品线区域市场经理刘彤女士。 拥抱eSIM技术,引领新时代发展 或许大众消费者对eSIM还不太了解,下面先给大家科普一下什么是eSIM? eSIM是Embedded-SIM的缩写,即嵌入式SIM卡。简单来说,就是将传统的SIM卡直接嵌入到设备芯片上,而不是作为独立的可移除零部件加入设备中,用户无需插入物理SIM卡。这一做法在硬件上减少了卡槽空间,让产品的抗震性、耐高温和可靠性更强,因此eSIM卡具备低成本、更小体积、高稳定性、一号多终端、使用便捷与安全等诸多优势。 据刘彤介绍,作为全球最大的eSIM供应商,英飞凌在过去的几年里,针对物联网碎片化、场景化、定制化等特点,推出了全面而完整的解决方案组合,能够满足不同应用的需求,这里最值得一提的就是OPTIGA? Connect eSIM解决方案。 该解决方案是一款面向移动消费终端的5G eSIM一站式解决方案,基于英飞凌成熟的SLC37安全芯片,支持主要移动运营商的配置文件,并且具备远程SIM卡配置功能,可提供最大至1.2 MB的可用内存,供用户存储运营商的配置文件、数据及其它应用。 图:英飞凌科技数字安全解决方案事业部 大中华区物联网安全产品线区域市场经理刘彤 在谈及产品亮点时,刘彤骄傲地说:“我们的OPTIGA? Connect eSIM解决方案具有两大核心优势,首先在符合GSMA最新规范的同时,还支持最新的5G规范的产品,并且通过了业界最高标准CC EAL4+的安全认证。当然,封装也是非常小的,这是基本性的优势。”据悉,该解决方案超小型封装尺寸仅为2.9 mm x 2.5 mm x 0.4 mm,有助于实现崭新的设计,特别适用于印刷电路板空间非常敏感的终端。 “其次就是易用性,可以提供端到端硬件和软件统包的一站式解决方案,并且在IOT的解决方案预置初始码号。这是我们充分跟客户沟通,理解了市场上用户的需求和痛点,帮助客户切实解决的问题,这也是我们最大的优势。”刘彤谈道。 符合GSMA安全需求并通过CC EAL4+的测试,意味着这一解决方案配备了坚固耐用且值得信赖的安全保障,因而能够确保敏感数据和密钥的安全,防止欺诈;同时,全面支持从3G到5G的所有GSMA标准,可以安全地面向所签约的运营商网络进行登网鉴权。英飞凌通过将硬件和软件整合到一个易于集成的系统中,帮助制造商高效地开发产品设计,降低eSIM集成工作量,加快将产品推向市场。 市场增速明显,物联网将成主战场 如果说SIM是移动互联时代的物种,那么eSIM就是专门为万物互联时代量身打造的嵌入式集成芯片。在刘彤看来,物联网无疑是eSIM的重要应用市场之一。 对此,刘彤给出了进一步解释:“从物联网领域来看,这一应用可以细分成三大类,首先是车联网,比如车规级eSIM用于前装T-box,为车主提供方便的导航、紧急呼叫、OTA下载等功能。随着5G的发展,V2X车路协同等应用对于智能化、网联化提出了更高的要求。打个比方,将来的汽车可以想象成是四个轮子的智能手机。” “其次是工业物联网,比如能源管理、水电气三表、资产追踪等引用。第三是消费级物联网,比如可穿戴市场,今年疫情以来,大众对于健康越来越重视,很多智能手表都推出了健康监控功能(所谓手腕上的医生),还有运动手表的销量也越来越多,很多人跑步健身的时候都会带着有通话功能的运动手表,而不是手机,另外儿童手表也是重要的应用。” 随着物联网的风口越来越近,未来百亿级别物联设备的安全连接都要以eSIM作为基础。根据英国市场研究机构ABI Research此前发布的数据显示,2011-2014年,eSIM出货量分别达到460万、700万、1000万和1700万,呈现加速增长态势;与此同时,eSIM随着M2M设备的配售率也在逐年上升,2011-2014年分别为13%、17%、22%和28%。预计2020年,eSIM智能手机出货量将突破2.25亿大关。不难看出,eSIM技术在智能终端设备上的应用日渐增多。 另外,ABI Research还预测,到2024年的时候,内置eSIM的消费电子设备将达到6.44亿,其中智能手机约5亿;而在M2M、物联网领域,eSIM设备也有望达到2.32亿(年复合增长率18%),其中超过1亿来自汽车。可以预见,随着5G的到来,物联网行业面临的功耗高、带宽速度慢,以及成本高等阻碍也将得到有效解决。未来,eSIM卡将随着5G和物联网行业迎来爆发期。 深化战略合作,实现共赢新局面 鉴于eSIM巨大的市场潜力,英飞凌在推广eSIM类产品的大规模落地方面采取了一系列措施。 在采访中,刘彤表示:“我们看好eSIM在全球发展前景,同时中国在5G和物联网领域都处于世界领先地位,我们更加看好eSIM在中国的市场前景。目前,英飞凌的eSIM解决方案在中国已有落地,在主流车厂里面,大部分高端汽车前装T-BOX都会用到我们的车规级eSIM芯片,还有一些IoT设备、智能可穿戴设备,以及智能手机产品等也有采用英飞凌的eSIM芯片。” 此外,为了支持全球网络连接,英飞凌也一直在与全球大大小小的运营商进行深入合作。“比如,我们和印度运营商——塔塔通信进行合作。塔塔通信是全球领先的电信解决方案供应商,它也是非常看好eSIM市场,近年来不仅投资建立了MOVE? eSIM Hub平台,还投入了大量资源和人力到这个领域。”刘彤介绍说。 据悉,英飞凌的解决方案预置了塔塔通信的MOVE? eSIM辅助程序,可以支持制造商在全球范围内无缝、安全、可靠地采集、传输和管理物联网数据。目前,英飞凌OPTIGA? Connect eSIM解决方案已在全球200多个国家和地区实现了预集成式网络覆盖。 此外,由于塔塔通信与全球640多个移动网络运营商(MNO)建立了合作关系,因此制造商无需与不同国家的移动网络运营商签订数以百计的本地连接协议,而是可以直接通过与塔塔通信的单一的全球连接协议实现设备联网。这极大简化了产品管理降低成本,并大幅加快了将产品推向市场的步伐。 总之,随着物联网设备的逐步兴起,越来越多的设备制造商、运营商、物联网企业和科技企业正在加入到eSIM生态中来。尤其是在5G时代,无论消费级应用,还是物联网应用,都迎来了全方位的爆发,因此eSIM更是大有用武之地。作为全球领先的半导体公司,英飞凌将以eSIM全力驱动物联网创新。 ?近期热度新闻 【1】剧透!围绕生态和体验,华为HMS亮出多款“杀手锏” 【2】周立功的公司也要上市了?拟募资约8.9亿 【3】AMD王炸!NVIDIA就这么被碾压了? 干货技能好文 【1】初学不识“电容”意,看完这篇,电容高手非你莫属! 【2】必看!100个示波器基础知识问答 【3】 超全面!layout与PCB的29个基本关系 优质资源推荐 【1】终于整理齐了,电子工程师“设计锦囊”,你值得拥有! 【2】半导体行业的人都在关注这几个公众号 【3】 电子工程师自我“修炼宝典” 21ic独家整理! 你和大牛工程师之间到底差了啥? 加入技术交流群,与高手面对面? 添加管理员微信 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-16 关键词: 物联网 移动通信

                      • 开关电源IC内部结构是什么样的?一文剖析!

                        作为一名电源研发工程师,自然经常与各种芯片打交道,可能有的工程师对芯片的内部并不是很了解,不少同学在应用新的芯片时直接翻到Datasheet的应用页面,按照推荐设计搭建外围完事。如此一来即使应用没有问题,却也忽略了更多的技术细节,对于自身的技术成长并没有积累到更好的经验。 今天以一颗DC/DC降压电源芯片LM2675为例,尽量详细讲解下一颗芯片的内部设计原理和结构,IC行业的同学随便看看就好,欢迎指教。 LM2675-5.0的典型应用电路: 图1 打开LM2675的DataSheet,首先看看框图: 图2 图2包含了电源芯片的内部全部单元模块。BUCK结构我们已经很理解了,这个芯片的主要功能是实现对MOS管的驱动,并通过FB脚检测输出状态来形成环路控制PWM驱动功率MOS管,实现稳压或者恒流输出。这是一个非同步模式电源,即续流器件为外部二极管,而不是内部MOS管。 下面咱们一起来分析各个功能是怎么实现的。 基准电压 类似于板级电路设计的基准电源,芯片内部基准电压为芯片其他电路提供稳定的参考电压。这个基准电压要求高精度、稳定性好、温漂小。芯片内部的参考电压又被称为带隙基准电压,因为这个电压值和硅的带隙电压相近,因此被称为带隙基准。这个值为1.2V左右,如图3的一种结构: 图3 这里要回到课本讲公式,PN结的电流和电压公式: 可以看出是指数关系,Is是反向饱和漏电流(即PN结因为少子漂移造成的漏电流)。这个电流和PN结的面积成正比,即Is->S。 如此就可以推导出: Vbe=VT*ln(Ic/Is)? 回到图3,由运放分析VX=VY,那么就是: I1*R1+Vbe1=Vbe2 这样可得: I1=△Vbe/R1 而因为M3和M4的栅极电压相同,因此电流I1=I2,所以推导出公式: I1=I2=VT*ln(N/R1) N是Q1、Q2的PN结面积之比。 这样我们最后得到基准: Vref=I2*R2+Vbe2 I1是正温度系数的,而Vbe是负温度系数的,再通过N值调节一下,可实现很好的温度补偿,得到稳定的基准电压。 N一般业界按照"8"设计,要想实现零温度系数,根据公式推算出: Vref=Vbe2+17.2*VT 所以大概在1.2V左右。目前在低压领域可以实现小于1V的基准,而且除了温度系数还有电源纹波抑制PSRR等问题,限于水平没法深入了。 最后的简图见图4,运放的设计当然也非常讲究。 图4 图5温度特性仿真。 图5 振荡器OSC和PWM 我们知道开关电源的基本原理是利用PWM方波来驱动功率MOS管,那么自然需要产生振荡的模块。原理很简单,就是利用电容的充放电形成锯齿波和比较器来生成占空比可调的方波。 图6 详细的电路设计图见图7: 图7 这里有个技术难点是在电流模式下的斜坡补偿,针对的是占空比大于50%时为了稳定斜坡,额外增加了补偿斜坡。笔者也是粗浅了解,有兴趣同学可详细学习。 误差放大器 误差放大器的作用是为了保证输出恒流或者恒压,对反馈电压进行采样处理。从而来调节驱动MOS管的PWM,如图8: 图8 驱动电路 最后的驱动部分结构很简单,就是很大面积的MOS管,电流能力强。 图9 其他模块电路 这里的其他模块电路是为了保证芯片能够正常和可靠的工作,虽然不是原理的核心,却实实在在的在芯片的设计中占据重要位置。 具体说来有几种功能: 1)启动模块 启动模块的作用自然是来启动芯片工作的,因为上电瞬间有可能所有晶体管电流为0并维持不变,这样没法工作。启动电路的作用就是相当于“点个火”,然后再关闭。如图10: 图10 上电瞬间,S3自然是打开的,然后S2打开可以打开M4、Q1等,就打开了M1、M2,右边恒流源电路正常工作,S1也打开了,就把S2给关闭了,完成启动。如果没有S1、S2、S3,瞬间所有晶体管电流为0。 2)过压保护模块OVP 很好理解,输入电压太高时,通过开关管来关断输出,避免损坏,通过比较器可以设置一个保护点。(图11) 图11 3)过温保护模块OTP 温度保护是为了防止芯片异常高温损坏,原理比较简单,利用晶体管的温度特性然后通过比较器设置保护点来关断输出。(图12) 图12 4)过流保护模块OCP 在譬如输出短路的情况下,通过检测输出电流来反馈控制输出管的状态,可以关断或者限流。如图13的电流采样,利用晶体管的电流和面积成正比来采样,一般采样管Q2的面积会是输出管面积的千分之一,然后通过电压比较器来控制MOS管的驱动。 图13 还有一些其他辅助模块设计。 恒流源和电流镜 在IC内部,如何来设置每一个晶体管的工作状态? 答案是通过偏置电流。 恒流源电路可以说是所有电路的基石,带隙基准也是因此产生的,然后通过电流镜来为每一个功能模块提供电流,电流镜就是通过晶体管的面积来设置需要的电流大小,类似镜像。 图14 结 语 以上大概就是一颗DC/DC电源芯片LM2675的内部全部结构,也算是把以前的皮毛知识复习了一下。 当然,这只是原理上的基本架构,具体设计时还要考虑非常多的参数特性,需要作大量的分析和仿真,而且必须要对半导体工艺参数有很深的理解,因为制造工艺决定了晶体管的很多参数和性能,一不小心出来的芯片就有缺陷甚至根本没法应用。整个芯片设计也是一个比较复杂的系统工程,要求很好的理论知识和实践经验。 最后,学而时习之,不亦说乎! 本文系网络转载,版权归原作者所有。如有问题,请联系我们,谢谢! 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-16 关键词: 开关电源 ic

                      • 知识贴!为什么LED灯越用越暗?为什么会闪烁?

                        开始今天的话题之前,咱们不能“不务正业”,先看一下LED日光灯的制作过程: 现在LED灯的制作首先要经过严谨的电脑编程制作,制作好灯板,再进入装配车间的流水线,具体咱们就不再展开了。 大家都有这么一个生活经验 刚买回来的LED灯,总是特别亮, 但是过一段时间后很多灯会变得越来越暗, 为什么LED灯具会有这样的一个过程呢? 今天就带大家一探究竟! 要了解为什么你家的LED灯会越来越暗 我们就得先了解一个专业名词 LED光衰 LED光衰 LED光衰是指LED经过一段时间的点亮之后,其光强比初始光强会降低,且不能恢复,即降低的部分称为LED的光衰。 /光衰曲线图/ LED灯越用越暗是因为LED灯会有光衰现象。 LED灯产品的光衰就是光在传输中的讯号减弱,而现阶段全球LED大厂做出的LED产品光衰程度都不同,大功率LED同样存在光衰,这和温度有直接的关系,主要是由芯片、萤光粉和封装技术决定的。目前,市场上的白光LED其光衰是向民用照明进军的首要问题之一。 光衰一般指它的光通量,在对感光鼓表面充电时,随着电荷在感光鼓表面的积累,电位也不断升高,最后达到"饱和"电位,就是最高电位。表面电位会随着时间的推移而下降,一般工作时的电位都低于这个电位,这个电位随时间自然降低的过程,称之为"暗衰"过程。 感光鼓经扫描曝光时,暗区(指未受光照射部分的光导体表面)电位仍处在暗衰过程;亮区(指受光照射部分的光导体表面)光导层内载流子密度迅速增加,电导率急速上升,形成光导电压,电荷迅速消失,光导体表面电位也迅速下降。称之为"光衰"。 LED灯越用越暗,是一种非常常见的现象。除了光衰,能够让LED灯变暗的原因,不外乎以下两点。 01 驱动器损坏 LED灯珠要求在直流低电压(20V以下)工作,但我们平时的市电是交流高电压(交流220V)。把市电变成灯珠需要的电,就需要一个装置,叫做“LED恒流驱动电源”。 理论上来讲,只要驱动器的参数与灯珠板相匹配,就可以持续供电、正常使用。驱动器内部比较复杂,任何一个装置(比如电容、整流器等等)发生故障,都有可能引起输出电压的改变,进而引起灯具发暗。 ? 驱动器损坏是LED灯具中最常见的一种故障,通常更换驱动器后,都可以解决。 02 LED烧毁 LED本身是由一个一个的灯珠组合而成,如果其中一个或一部分不亮了,则势必会使得整个灯具发暗。灯珠一般是先串联再并联——所以某一个灯珠烧毁,就有可能导致一批灯珠都不亮了。 烧毁后的灯珠表面有明显的黑点,找到它,用一根电线接在它的背面,将它短路;或者更换一个新灯珠,都可以解决问题。 ? LED偶尔烧毁一个,可能是碰巧了。如果频繁烧毁,则要考虑驱动器问题——驱动器故障的另外一个表现,就是烧毁灯珠。 LED灯为什么会闪烁?LED灯闪烁是什么原因。。。 LED灯的驱动器里面都有一个电容,可以把电容理解成一个容量很小的充电电池:当电容内通过电流时,电容会持续充电——充满电以后,电容会一次性将储存的电能全部释放。 LED灯闪烁,就属于后一种情况:电容充电的过程中,灯是熄灭的——由于电容内部电流较小,导致充电速度很慢,所以用肉眼是可以看到电灯熄灭的。当电容充满电后,一次性释放电能,会点亮电灯。但是由于储存的电能较少,电灯很快就会熄灭——不停的重复充电、放电,肉眼看到的,就是灯闪烁。 电灯正常使用时看不到闪烁,是因为通过电容的电流较大,充电速度极快。 那么,什么情况会导致电容内部流过较小的电流呢?首先是因为电容的质量不好——优质的电容,储存电量很多,线路中的微小电流不足以在电容内储能。一般的启动器只有二十元左右,优质的电容成本恐怕也不止二十元。 除此以外,我们还可以从微小电流的来源入手。 可能性1:开关控制零线 开关控制零线,代表了火线直接接在电灯(电容)上了。而火线上具有高电位,如果此时的线路中存在低电位,就会形成电位差——电位差的另一个名字,叫做电压。只不过此时的电位差相比于220V,要小很多。电压加在电容两端,就会产生微弱电流。 单控开关的正确的接线 双控的正确接法 所以,火线直接接入电灯,势必导致LED灯闪烁。这属于施工问题,除了改变零火线方向,没有其它办法。 可能性2:零线带电 电灯(电容)两端都接的是零电位的零线,就万事大吉了吗?也不尽然!零线很容易带电的——特别是电灯的零线。主要是因为电灯开关太不靠谱了。 现在的电灯开关,内部结构的质量非常堪忧。零火线接线柱距离太近、绝缘性不合格等,都有可能引起电灯的零线带电。不信可以拆开自己家已经接好的开关,用电笔测一下——理论上来讲,当开关关闭时,只有火线接线柱能够点亮电笔。但是实际使用时,接了零线(灯线)的接线柱十有八九也可以点亮电笔。 只不过大部分开关,即使零线带电,所带的电压也比较低,不足以在线路中产生电流。但如果绝缘性再差一点,产生的电流稍大了,就会给电容充电。 还有一点:开关上带指示灯的时候,关灯时指示灯会亮起,此时需要产生微弱电流——这部分电流会流经电容,并被电容储存起来。这些情况,更换质量更好的、没有指示灯的开关后,即可解决。 可能性3:感应电 如果电容周围的电线较多,其它电线在工作时,就会使电容附近产生感应电——一句话解释感应电的产生原因:两个导体平行放置,形成了新的电容。 大多数人面对这种情况都束手无策,此时的解决方法有两个:1)更换电灯,换成荧光灯或白炽灯。2)在LED灯的启动器上,串联一个220V继电器线圈。用线圈消耗掉线路产生的感应电。 来源:直观学机械 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-16 关键词: LED 照明系统

                      • 星间链路”为什么重要?

                        星间链路,是指卫星与卫星之间的链路,当然也可以扩展为航天器与航天器之间的链路。星间链路具有星间通信、数据传输、星间测距和星间测控等功能。 星间链路 不同的空间系统,星间链路的作用是不同的。通信卫星星座的星间链路可以减小星地跳数和通信延迟;侦查编队系统的星间链路可以增大虚拟相机口径以提高分辨率;导航卫星星座的星间链路可以支持自主运行以提高定位精度;中继卫星系统的星间链路可以增加用户星的测控弧段。 星间链路使多颗卫星构成有机整体,形成星座系统,扩展单星工作的能力。在导航星座系统应用之前,星间链路早在通信星座、中继卫星以及卫星编队飞行中已经得到应用。 中继卫星系统 美国1983-1995年发射了由7颗跟踪与数据中继卫星 (TDRS) A~G组成的美国第一代中继卫星系统,卫星装载两副4.9m单址抛物面天线,为S及Ku频段共用,用于TDRS和用户星之间交换高速数据,最大返向传输速率为300Mb/s。 1997-2002年,美国发射第二代中继卫星,即TDRS-H、I、J,其上星间链路的功能有所改进:增强了S频段多址能力,传输速率可达800Mb/s或更高。自2007年开始,美国在研发第三代跟踪与数据中继卫星,中继卫星与用户卫星采用S、Ku/Ka频段进行星间测控通信。 美国的铱星系统由66颗卫星构成,是当前世界上大型星座系统中唯一实现Ka频段星间链路的系统。铱星系统轨道高度为780km左右,共有6个极地轨道,每个轨道11颗卫星。星间通信采用Ka频段相控阵天线。每颗铱星同时建立4条星间链路,同轨道内部正向和后向,左右异轨道面侧向链路各一条。 星间最大数据传输速率为25Mb/s,工作频段为22.55~23.55GHz,星间采用半双工通信方式。铱星系统是极轨星座,相邻轨道间的卫星相对距离的变化,相对速度、方位角、俯仰角的变化量和变化率都比较小,星间拓扑简单,采用固定连接的拓扑结构。 区別于通信卫星,导航卫星需要持续收集更新各颗卫星的测量数指以支持精密定轨计算。在卫星导航系统日常运行中,地面站通过收集境内卫星的星地观测数据进行解算定轨,并实施星历的更新。 而对于境外卫星,由于无法建立起直接与地面站相连的星地链路,所以无法实现对境外卫星的定轨。星间链路架起了一座连接境外卫星与境内卫星测量和数传的桥梁,为境外卫星观测和数据回传提供了实现手段。 同时,星间链路搭建的无线电通道也便于卫星测控和运控数据传输,使原先必须等待卫星入境才能进行的操作变成随时可行的远程操作。更进一步的发展,是将简化的地面定轨算法配置在卫星计算机上,处理星间链路测量值,使卫星脱离地面站而自主生成卫星导航电文,提高星座的自主运行能力,简化地面的运行管理。 因此,星间链路的建立,能大幅提升导航卫星星座的管控能力和自主运行能力,意义重大,已经为各大卫星导航系统广泛研究和采用。 导航星座中实现星间链路 美国GPS系统是最先在导航星座中实现星间链路的系统。自Block IIR卫星开始,GPS卫星安装了具有自主导航功能的星间链路收发设备,实现了星间通信和星间测距功能,进而实现了全球导航卫星星座自主导航的功能。 GPS的Block IIR和Black IIF系列导航卫星安装了UHF频段(250~290MHz)的星间链路收发设备,Block IIR卫星在无地面控制系统支持的情况下,卫星采用时分多址(TDMA)方式实现卫星之间双向测距和数据交换,通过星载滤波器处理星间测量数据,自主生成卫星星历和时钟修正参数,自主维持星座基本构型。 在180天内,保持用户距离误差小于6m,导航定位精度不会有明显下降。并且能够监测导航卫星信号的完好性,使其可用性、连续性和可靠性得到增强。 GPS III开展了全新的设计,具有高速传输能力,采用具有方向性的星间链路技术和全球点波束增强技术。GPS IIIA在继续保持UHF频段的星间链路,而在GPS IIIB上增加实施V频段星间链路的方案,大幅提高星间传输速率、星间抗干扰能力,星间测距精度等性能,也增强了自主运行的能力。 我国在北斗一号和北斗二号卫星中均没有设计星间链路,在北斗三号全球卫星导航系统中规划配置了星间链路。北斗三号星间链路是一个复杂的星间网络,具有天线指向控制、星间网络拓扑、星间通信协议和星间测距精度要求高等特点。 整个星间链路总体技术涉及飞行器总体设计、结构/机构、轨道/定轨、天线/微波、通信/电子、计算机/网络、数学和系统仿真等多个字科领域。在发射的北斗三号卫星上已经成功应用了Ka频段相控阵体制的星间链路方案。 来源:雷达通信电子战 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-16 关键词: 卫星 移动通信

                      • 祝贺!天通一号02星成功发射,覆盖一带一路广泛地区

                        据新华社报道,11 月 12 日 23 时 59 分,我国在西昌卫星发射中心用长征三号乙运载火箭,成功将天通一号 02 星送入预定轨道,发射任务获得圆满成功。 天通一号卫星移动通信系统是我国自主研制建设的卫星移动通信系统,由空间段、地面段和用户终端组成。天通一号 02 星由中国空间技术研究院抓总研制,发射入轨后将与地面移动通信系统共同构成天地一体化移动通信网络,为中国及周边、中东、非洲等相关地区,以及太平洋、印度洋大部分海域用户,提供全天候、全天时、稳定可靠的话音、短消息和数据等移动通信服务。 这次任务是长征系列运载火箭的第 352 次飞行。 21ic家了解到,卫星移动通信同地面的蜂窝移动通信不同,它具有广域覆盖、全天候通信的特点,不管是荒无人烟的大漠戈壁,还是茫茫的大海上,都可以利用卫星电话实现实时通信。此次发射的天通一号02星入轨后,将与天通一号01星组网运行,共同构成空间段。其可以在01 星覆盖祖国国土(包括海洋国土)的基础上扩大一带一路区域国家的使用覆盖范围。 天通一号卫星移动通信系统是我国自主研制建设的卫星移动通信系统,摆脱了长期对国外卫星移动通信服务的依赖,填补了国内自主卫星移动通信系统的空白,2020 年 1 月 11 日,天通系统正式面向社会提供服务。据悉,三颗天通卫星就可以覆盖完整的地球面积,期待天通一号卫星移动全球通信系统早日建成。 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-16 关键词: 卫星 移动通信

                      • 刨根问底,Kafka消息中间件到底会不会丢消息

                        大型互联网公司一般都会要求消息传递最大限度的不丢失,比如用户服务给代金券服务发送一个消息,如果消息丢失会造成用户未收到应得的代金券,最终用户会投诉。 为避免上面类似情况的发生,除了做好补偿措施,更应该在系设计的时候充分考虑各种异常,设计一个稳定、高可用的消息系统。 认识Kafka 看一下维基百科的定义 Kafka是分布式发布-订阅消息系统。它最初由LinkedIn公司开发,之后成为Apache项目的一部分。 Kafka是一个分布式的,可划分的,冗余备份的持久性的日志服务。它主要用于处理活跃的流式数据。 kafka架构 Kafka的整体架构非常简单,是显式分布式架构,主要由producer、broker(kafka)和consumer组成。 Kafka架构(精简版) Producer(生产者)可以将数据发布到所选择的topic(主题)中。生产者负责将记录分配到topic的哪一个 partition(分区)中。可以使用循环的方式来简单地实现负载均衡,也可以根据某些语义分区函数(如记录中的key)来完成。 Consumer(消费者)使用一个consumer group(消费组)名称来进行标识,发布到topic中的每条记录被分配给订阅消费组中的一个消费者实例。消费者实例可以分布在多个进程中或者多个机器上。 Kafka到底会不会丢失消息? 在讨论kafka是否丢消息前先来了解一下什么是消息传递语义。 消息传递语义 message delivery semantic 也就是消息传递语义,简单说就是消息传递过程中消息传递的保证性。主要分为三种: at most once:最多一次。消息可能丢失也可能被处理,但最多只会被处理一次。 at least once:至少一次。消息不会丢失,但可能被处理多次。可能重复,不会丢失。 exactly once:精确传递一次。消息被处理且只会被处理一次。不丢失不重复就一次。 理想情况下肯定是希望系统的消息传递是严格exactly once,也就是保证不丢失、只会被处理一次,但是很难做到。 回到主角Kafka,Kafka有三次消息传递的过程: 生产者发消息给Kafka Broker。 Kafka Broker 消息同步和持久化 Kafka Broker 将消息传递给消费者。 在这三步中每一步都有可能会丢失消息,下面详细分析为什么会丢消息,如何最大限度避免丢失消息。 生产者丢失消息 先介绍一下生产者发送消息的一般流程(部分流程与具体配置项强相关,这里先忽略): 生产者是与leader直接交互,所以先从集群获取topic对应分区的leader元数据; 获取到leader分区元数据后直接将消息发给过去; Kafka Broker对应的leader分区收到消息后写入文件持久化; Follower拉取Leader消息与Leader的数据保持一致; Follower消息拉取完毕需要给Leader回复ACK确认消息; Kafka Leader和Follower分区同步完,Leader分区会给生产者回复ACK确认消息。 生产者发送数据流程 生产者采用push模式将数据发布到broker,每条消息追加到分区中,顺序写入磁盘。消息写入Leader后,Follower是主动与Leader进行同步。 Kafka消息发送有两种方式:同步(sync)和异步(async),默认是同步方式,可通过producer.type属性进行配置。 Kafka通过配置request.required.acks属性来确认消息的生产: 0表示不进行消息接收是否成功的确认;不能保证消息是否发送成功,生成环境基本不会用。 1表示当Leader接收成功时确认;只要Leader存活就可以保证不丢失,保证了吞吐量。 -1或者all表示Leader和Follower都接收成功时确认;可以最大限度保证消息不丢失,但是吞吐量低。 kafka producer 的参数acks 的默认值为1,所以默认的producer级别是at least once,并不能exactly once。 敲黑板了,这里可能会丢消息的! 如果acks配置为0,发生网络抖动消息丢了,生产者不校验ACK自然就不知道丢了。 如果acks配置为1保证leader不丢,但是如果leader挂了,恰好选了一个没有ACK的follower,那也丢了。 all:保证leader和follower不丢,但是如果网络拥塞,没有收到ACK,会有重复发的问题。 Kafka Broker丢失消息 Kafka Broker 接收到数据后会将数据进行持久化存储,你以为是下面这样的: 消息持久化,无cache 没想到是这样的: 消息持久化,有cache 操作系统本身有一层缓存,叫做 Page Cache,当往磁盘文件写入的时候,系统会先将数据流写入缓存中,至于什么时候将缓存的数据写入文件中是由操作系统自行决定。 Kafka提供了一个参数 producer.type 来控制是不是主动flush,如果Kafka写入到mmap之后就立即 flush 然后再返回 Producer 叫同步 (sync);写入mmap之后立即返回 Producer 不调用 flush 叫异步 (async)。 敲黑板了,这里可能会丢消息的! Kafka通过多分区多副本机制中已经能最大限度保证数据不会丢失,如果数据已经写入系统 cache 中但是还没来得及刷入磁盘,此时突然机器宕机或者掉电那就丢了,当然这种情况很极端。 消费者丢失消息 消费者通过pull模式主动的去 kafka 集群拉取消息,与producer相同的是,消费者在拉取消息的时候也是找leader分区去拉取。 多个消费者可以组成一个消费者组(consumer group),每个消费者组都有一个组id。同一个消费组者的消费者可以消费同一topic下不同分区的数据,但是不会出现多个消费者消费同一分区的数据。 消费者群组消费消息 消费者消费的进度通过offset保存在kafka集群的__consumer_offsets这个topic中。 消费消息的时候主要分为两个阶段: 1、标识消息已被消费,commit offset坐标; 2、处理消息。 敲黑板了,这里可能会丢消息的! 场景一:先commit再处理消息。如果在处理消息的时候异常了,但是offset 已经提交了,这条消息对于该消费者来说就是丢失了,再也不会消费到了。 场景二:先处理消息再commit。如果在commit之前发生异常,下次还会消费到该消息,重复消费的问题可以通过业务保证消息幂等性来解决。 总结 那么问题来了,kafka到底会不会丢消息?答案是:会! Kafka可能会在三个阶段丢失消息: (1)生产者发送数据; (2)Kafka Broker 存储数据; (3)消费者消费数据; 在生产环境中严格做到exactly once其实是难的,同时也会牺牲效率和吞吐量,最佳实践是业务侧做好补偿机制,万一出现消息丢失可以兜底。 - END - 特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下: 长按订阅更多精彩▼如有收获,点个在看,诚挚感谢 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-16 关键词: 架构 嵌入式

                      • 破4!《我想进大厂》之Java基础夺命连环16问

                        说说进程和线程的区别? 进程是程序的一次执行,是系统进行资源分配和调度的独立单位,他的作用是是程序能够并发执行提高资源利用率和吞吐率。 由于进程是资源分配和调度的基本单位,因为进程的创建、销毁、切换产生大量的时间和空间的开销,进程的数量不能太多,而线程是比进程更小的能独立运行的基本单位,他是进程的一个实体,可以减少程序并发执行时的时间和空间开销,使得操作系统具有更好的并发性。 线程基本不拥有系统资源,只有一些运行时必不可少的资源,比如程序计数器、寄存器和栈,进程则占有堆、栈。 知道synchronized原理吗? synchronized是java提供的原子性内置锁,这种内置的并且使用者看不到的锁也被称为监视器锁,使用synchronized之后,会在编译之后在同步的代码块前后加上monitorenter和monitorexit字节码指令,他依赖操作系统底层互斥锁实现。他的作用主要就是实现原子性操作和解决共享变量的内存可见性问题。 执行monitorenter指令时会尝试获取对象锁,如果对象没有被锁定或者已经获得了锁,锁的计数器+1。此时其他竞争锁的线程则会进入等待队列中。 执行monitorexit指令时则会把计数器-1,当计数器值为0时,则锁释放,处于等待队列中的线程再继续竞争锁。 synchronized是排它锁,当一个线程获得锁之后,其他线程必须等待该线程释放锁后才能获得锁,而且由于Java中的线程和操作系统原生线程是一一对应的,线程被阻塞或者唤醒时时会从用户态切换到内核态,这种转换非常消耗性能。 从内存语义来说,加锁的过程会清除工作内存中的共享变量,再从主内存读取,而释放锁的过程则是将工作内存中的共享变量写回主内存。 实际上大部分时候我认为说到monitorenter就行了,但是为了更清楚的描述,还是再具体一点。 如果再深入到源码来说,synchronized实际上有两个队列waitSet和entryList。 当多个线程进入同步代码块时,首先进入entryList 有一个线程获取到monitor锁后,就赋值给当前线程,并且计数器+1 如果线程调用wait方法,将释放锁,当前线程置为null,计数器-1,同时进入waitSet等待被唤醒,调用notify或者notifyAll之后又会进入entryList竞争锁 如果线程执行完毕,同样释放锁,计数器-1,当前线程置为null 那锁的优化机制了解吗? 从JDK1.6版本之后,synchronized本身也在不断优化锁的机制,有些情况下他并不会是一个很重量级的锁了。优化机制包括自适应锁、自旋锁、锁消除、锁粗化、轻量级锁和偏向锁。 锁的状态从低到高依次为无锁->偏向锁->轻量级锁->重量级锁,升级的过程就是从低到高,降级在一定条件也是有可能发生的。 自旋锁:由于大部分时候,锁被占用的时间很短,共享变量的锁定时间也很短,所有没有必要挂起线程,用户态和内核态的来回上下文切换严重影响性能。自旋的概念就是让线程执行一个忙循环,可以理解为就是啥也不干,防止从用户态转入内核态,自旋锁可以通过设置-XX:+UseSpining来开启,自旋的默认次数是10次,可以使用-XX:PreBlockSpin设置。 自适应锁:自适应锁就是自适应的自旋锁,自旋的时间不是固定时间,而是由前一次在同一个锁上的自旋时间和锁的持有者状态来决定。 锁消除:锁消除指的是JVM检测到一些同步的代码块,完全不存在数据竞争的场景,也就是不需要加锁,就会进行锁消除。 锁粗化:锁粗化指的是有很多操作都是对同一个对象进行加锁,就会把锁的同步范围扩展到整个操作序列之外。 偏向锁:当线程访问同步块获取锁时,会在对象头和栈帧中的锁记录里存储偏向锁的线程ID,之后这个线程再次进入同步块时都不需要CAS来加锁和解锁了,偏向锁会永远偏向第一个获得锁的线程,如果后续没有其他线程获得过这个锁,持有锁的线程就永远不需要进行同步,反之,当有其他线程竞争偏向锁时,持有偏向锁的线程就会释放偏向锁。可以用过设置-XX:+UseBiasedLocking开启偏向锁。 轻量级锁:JVM的对象的对象头中包含有一些锁的标志位,代码进入同步块的时候,JVM将会使用CAS方式来尝试获取锁,如果更新成功则会把对象头中的状态位标记为轻量级锁,如果更新失败,当前线程就尝试自旋来获得锁。 整个锁升级的过程非常复杂,我尽力去除一些无用的环节,简单来描述整个升级的机制。 简单点说,偏向锁就是通过对象头的偏向线程ID来对比,甚至都不需要CAS了,而轻量级锁主要就是通过CAS修改对象头锁记录和自旋来实现,重量级锁则是除了拥有锁的线程其他全部阻塞。 那对象头具体都包含哪些内容? 在我们常用的Hotspot虚拟机中,对象在内存中布局实际包含3个部分: 对象头 实例数据 对齐填充 而对象头包含两部分内容,Mark Word中的内容会随着锁标志位而发生变化,所以只说存储结构就好了。 对象自身运行时所需的数据,也被称为Mark Word,也就是用于轻量级锁和偏向锁的关键点。具体的内容包含对象的hashcode、分代年龄、轻量级锁指针、重量级锁指针、GC标记、偏向锁线程ID、偏向锁时间戳。 存储类型指针,也就是指向类的元数据的指针,通过这个指针才能确定对象是属于哪个类的实例。 如果是数组的话,则还包含了数组的长度 对于加锁,那再说下ReentrantLock原理?他和synchronized有什么区别? 相比于synchronized,ReentrantLock需要显式的获取锁和释放锁,相对现在基本都是用JDK7和JDK8的版本,ReentrantLock的效率和synchronized区别基本可以持平了。他们的主要区别有以下几点: 等待可中断,当持有锁的线程长时间不释放锁的时候,等待中的线程可以选择放弃等待,转而处理其他的任务。 公平锁:synchronized和ReentrantLock默认都是非公平锁,但是ReentrantLock可以通过构造函数传参改变。只不过使用公平锁的话会导致性能急剧下降。 绑定多个条件:ReentrantLock可以同时绑定多个Condition条件对象。 ReentrantLock基于AQS(AbstractQueuedSynchronizer 抽象队列同步器)实现。别说了,我知道问题了,AQS原理我来讲。 AQS内部维护一个state状态位,尝试加锁的时候通过CAS(CompareAndSwap)修改值,如果成功设置为1,并且把当前线程ID赋值,则代表加锁成功,一旦获取到锁,其他的线程将会被阻塞进入阻塞队列自旋,获得锁的线程释放锁的时候将会唤醒阻塞队列中的线程,释放锁的时候则会把state重新置为0,同时当前线程ID置为空。 CAS的原理呢? CAS叫做CompareAndSwap,比较并交换,主要是通过处理器的指令来保证操作的原子性,它包含三个操作数: 变量内存地址,V表示 旧的预期值,A表示 准备设置的新值,B表示 当执行CAS指令时,只有当V等于A时,才会用B去更新V的值,否则就不会执行更新操作。 那么CAS有什么缺点吗? CAS的缺点主要有3点: ABA问题:ABA的问题指的是在CAS更新的过程中,当读取到的值是A,然后准备赋值的时候仍然是A,但是实际上有可能A的值被改成了B,然后又被改回了A,这个CAS更新的漏洞就叫做ABA。只是ABA的问题大部分场景下都不影响并发的最终效果。 Java中有AtomicStampedReference来解决这个问题,他加入了预期标志和更新后标志两个字段,更新时不光检查值,还要检查当前的标志是否等于预期标志,全部相等的话才会更新。 循环时间长开销大:自旋CAS的方式如果长时间不成功,会给CPU带来很大的开销。 只能保证一个共享变量的原子操作:只对一个共享变量操作可以保证原子性,但是多个则不行,多个可以通过AtomicReference来处理或者使用锁synchronized实现。 好,说说HashMap原理吧? HashMap主要由数组和链表组成,他不是线程安全的。核心的点就是put插入数据的过程,get查询数据以及扩容的方式。JDK1.7和1.8的主要区别在于头插和尾插方式的修改,头插容易导致HashMap链表死循环,并且1.8之后加入红黑树对性能有提升。 put插入数据流程 往map插入元素的时候首先通过对key hash然后与数组长度-1进行与运算((n-1)&hash),都是2的次幂所以等同于取模,但是位运算的效率更高。找到数组中的位置之后,如果数组中没有元素直接存入,反之则判断key是否相同,key相同就覆盖,否则就会插入到链表的尾部,如果链表的长度超过8,则会转换成红黑树,最后判断数组长度是否超过默认的长度*负载因子也就是12,超过则进行扩容。 get查询数据 查询数据相对来说就比较简单了,首先计算出hash值,然后去数组查询,是红黑树就去红黑树查,链表就遍历链表查询就可以了。 resize扩容过程 扩容的过程就是对key重新计算hash,然后把数据拷贝到新的数组。 那多线程环境怎么使用Map呢?ConcurrentHashmap了解过吗? 多线程环境可以使用Collections.synchronizedMap同步加锁的方式,还可以使用HashTable,但是同步的方式显然性能不达标,而ConurrentHashMap更适合高并发场景使用。 ConcurrentHashmap在JDK1.7和1.8的版本改动比较大,1.7使用Segment+HashEntry分段锁的方式实现,1.8则抛弃了Segment,改为使用CAS+synchronized+Node实现,同样也加入了红黑树,避免链表过长导致性能的问题。 1.7分段锁 从结构上说,1.7版本的ConcurrentHashMap采用分段锁机制,里面包含一个Segment数组,Segment继承与ReentrantLock,Segment则包含HashEntry的数组,HashEntry本身就是一个链表的结构,具有保存key、value的能力能指向下一个节点的指针。 实际上就是相当于每个Segment都是一个HashMap,默认的Segment长度是16,也就是支持16个线程的并发写,Segment之间相互不会受到影响。 put流程 其实发现整个流程和HashMap非常类似,只不过是先定位到具体的Segment,然后通过ReentrantLock去操作而已,后面的流程我就简化了,因为和HashMap基本上是一样的。 计算hash,定位到segment,segment如果是空就先初始化 使用ReentrantLock加锁,如果获取锁失败则尝试自旋,自旋超过次数就阻塞获取,保证一定获取锁成功 遍历HashEntry,就是和HashMap一样,数组中key和hash一样就直接替换,不存在就再插入链表,链表同样 get流程 get也很简单,key通过hash定位到segment,再遍历链表定位到具体的元素上,需要注意的是value是volatile的,所以get是不需要加锁的。 1.8CAS+synchronized 1.8抛弃分段锁,转为用CAS+synchronized来实现,同样HashEntry改为Node,也加入了红黑树的实现。主要还是看put的流程。 put流程 首先计算hash,遍历node数组,如果node是空的话,就通过CAS+自旋的方式初始化 如果当前数组位置是空则直接通过CAS自旋写入数据 如果hash==MOVED,说明需要扩容,执行扩容 如果都不满足,就使用synchronized写入数据,写入数据同样判断链表、红黑树,链表写入和HashMap的方式一样,key hash一样就覆盖,反之就尾插法,链表长度超过8就转换成红黑树 get查询 get很简单,通过key计算hash,如果key hash相同就返回,如果是红黑树按照红黑树获取,都不是就遍历链表获取。 volatile原理知道吗? 相比synchronized的加锁方式来解决共享变量的内存可见性问题,volatile就是更轻量的选择,他没有上下文切换的额外开销成本。使用volatile声明的变量,可以确保值被更新的时候对其他线程立刻可见。volatile使用内存屏障来保证不会发生指令重排,解决了内存可见性的问题。 我们知道,线程都是从主内存中读取共享变量到工作内存来操作,完成之后再把结果写会主内存,但是这样就会带来可见性问题。举个例子,假设现在我们是两级缓存的双核CPU架构,包含L1、L2两级缓存。 线程A首先获取变量X的值,由于最初两级缓存都是空,所以直接从主内存中读取X,假设X初始值为0,线程A读取之后把X值都修改为1,同时写回主内存。这时候缓存和主内存的情况如下图。 线程B也同样读取变量X的值,由于L2缓存已经有缓存X=1,所以直接从L2缓存读取,之后线程B把X修改为2,同时写回L2和主内存。这时候的X值入下图所示。 那么线程A如果再想获取变量X的值,因为L1缓存已经有x=1了,所以这时候变量内存不可见问题就产生了,B修改为2的值对A来说没有感知。 image-20201111171451466 那么,如果X变量用volatile修饰的话,当线程A再次读取变量X的话,CPU就会根据缓存一致性协议强制线程A重新从主内存加载最新的值到自己的工作内存,而不是直接用缓存中的值。 再来说内存屏障的问题,volatile修饰之后会加入不同的内存屏障来保证可见性的问题能正确执行。这里写的屏障基于书中提供的内容,但是实际上由于CPU架构不同,重排序的策略不同,提供的内存屏障也不一样,比如x86平台上,只有StoreLoad一种内存屏障。 StoreStore屏障,保证上面的普通写不和volatile写发生重排序 StoreLoad屏障,保证volatile写与后面可能的volatile读写不发生重排序 LoadLoad屏障,禁止volatile读与后面的普通读重排序 LoadStore屏障,禁止volatile读和后面的普通写重排序 那么说说你对JMM内存模型的理解?为什么需要JMM? 本身随着CPU和内存的发展速度差异的问题,导致CPU的速度远快于内存,所以现在的CPU加入了高速缓存,高速缓存一般可以分为L1、L2、L3三级缓存。基于上面的例子我们知道了这导致了缓存一致性的问题,所以加入了缓存一致性协议,同时导致了内存可见性的问题,而编译器和CPU的重排序导致了原子性和有序性的问题,JMM内存模型正是对多线程操作下的一系列规范约束,因为不可能让陈雇员的代码去兼容所有的CPU,通过JMM我们才屏蔽了不同硬件和操作系统内存的访问差异,这样保证了Java程序在不同的平台下达到一致的内存访问效果,同时也是保证在高效并发的时候程序能够正确执行。 原子性:Java内存模型通过read、load、assign、use、store、write来保证原子性操作,此外还有lock和unlock,直接对应着synchronized关键字的monitorenter和monitorexit字节码指令。 可见性:可见性的问题在上面的回答已经说过,Java保证可见性可以认为通过volatile、synchronized、final来实现。 有序性:由于处理器和编译器的重排序导致的有序性问题,Java通过volatile、synchronized来保证。 happen-before规则 虽然指令重排提高了并发的性能,但是Java虚拟机会对指令重排做出一些规则限制,并不能让所有的指令都随意的改变执行位置,主要有以下几点: 单线程每个操作,happen-before于该线程中任意后续操作 volatile写happen-before与后续对这个变量的读 synchronized解锁happen-before后续对这个锁的加锁 final变量的写happen-before于final域对象的读,happen-before后续对final变量的读 传递性规则,A先于B,B先于C,那么A一定先于C发生 说了半天,到底工作内存和主内存是什么? 主内存可以认为就是物理内存,Java内存模型中实际就是虚拟机内存的一部分。而工作内存就是CPU缓存,他有可能是寄存器也有可能是L1\L2\L3缓存,都是有可能的。 说说ThreadLocal原理? ThreadLocal可以理解为线程本地变量,他会在每个线程都创建一个副本,那么在线程之间访问内部副本变量就行了,做到了线程之间互相隔离,相比于synchronized的做法是用空间来换时间。 ThreadLocal有一个静态内部类ThreadLocalMap,ThreadLocalMap又包含了一个Entry数组,Entry本身是一个弱引用,他的key是指向ThreadLocal的弱引用,Entry具备了保存key value键值对的能力。 弱引用的目的是为了防止内存泄露,如果是强引用那么ThreadLocal对象除非线程结束否则始终无法被回收,弱引用则会在下一次GC的时候被回收。 但是这样还是会存在内存泄露的问题,假如key和ThreadLocal对象被回收之后,entry中就存在key为null,但是value有值的entry对象,但是永远没办法被访问到,同样除非线程结束运行。 但是只要ThreadLocal使用恰当,在使用完之后调用remove方法删除Entry对象,实际上是不会出现这个问题的。 那引用类型有哪些?有什么区别? 引用类型主要分为强软弱虚四种: 强引用指的就是代码中普遍存在的赋值方式,比如A a = new A()这种。强引用关联的对象,永远不会被GC回收。 软引用可以用SoftReference来描述,指的是那些有用但是不是必须要的对象。系统在发生内存溢出前会对这类引用的对象进行回收。 弱引用可以用WeakReference来描述,他的强度比软引用更低一点,弱引用的对象下一次GC的时候一定会被回收,而不管内存是否足够。 虚引用也被称作幻影引用,是最弱的引用关系,可以用PhantomReference来描述,他必须和ReferenceQueue一起使用,同样的当发生GC的时候,虚引用也会被回收。可以用虚引用来管理堆外内存。 线程池原理知道吗? 首先线程池有几个核心的参数概念: 最大线程数maximumPoolSize 核心线程数corePoolSize 活跃时间keepAliveTime 阻塞队列workQueue 拒绝策略RejectedExecutionHandler 当提交一个新任务到线程池时,具体的执行流程如下: 当我们提交任务,线程池会根据corePoolSize大小创建若干任务数量线程执行任务 当任务的数量超过corePoolSize数量,后续的任务将会进入阻塞队列阻塞排队 当阻塞队列也满了之后,那么将会继续创建(maximumPoolSize-corePoolSize)个数量的线程来执行任务,如果任务处理完成,maximumPoolSize-corePoolSize额外创建的线程等待keepAliveTime之后被自动销毁 如果达到maximumPoolSize,阻塞队列还是满的状态,那么将根据不同的拒绝策略对应处理 拒绝策略有哪些? 主要有4种拒绝策略: AbortPolicy:直接丢弃任务,抛出异常,这是默认策略 CallerRunsPolicy:只用调用者所在的线程来处理任务 DiscardOldestPolicy:丢弃等待队列中最近的任务,并执行当前任务 DiscardPolicy:直接丢弃任务,也不抛出异常 特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下: 长按订阅更多精彩▼如有收获,点个在看,诚挚感谢 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-16 关键词: 嵌入式 java

                      • 实战篇:一个核心系统3万多行代码的重构之旅

                        经典著作《重构》这本书中有这么一段话: 一开始,我所做的重构都停留在细枝末节上。随着代码趋向简洁,我发现自己可以看到一些设计层面的东西了,这些是我以前理解不到的,如果没有重构,我达不到这种高度。 重构,着实是一件让程序员兴奋的事情。 今年年初,我们团队完成了一个复杂项目的重构工作,它属于广告系统最核心的引擎部分,大概有 300 多个文件,3 万多行代码。 从技术方案设计到最终全量上线仅仅花了 1 个月左右的时间,而且没有产生事故。 这应该是我 8 年程序生涯中,经历过的最大型的同时最成功的一次重构项目:速度足够快、计划比较周全、质量过关。 01 先聊聊这个系统的历史包袱 我们的广告引擎在这次重构前大概经历了1年半时间的迭代,初期针对的是搜索场景,业务单一,流程清晰。 2019年开始,公司的广告业务开始快速扩张,收入几乎是指数级的增长。在这个过程中,我们的广告引擎面临了两个挑战: 1、业务场景开始变得复杂,除了搜索广告,还需要支持信息流推荐以及相似推荐场景。 2、广告流量开始快速增加,除了满足功能性需求,还需要兼顾好性能。 经过梳理,整个引擎有大部分逻辑是可以公用的,因此我们定义了一个主体框架,同时将可扩展部分进行了抽象。这样,各个场景能够根据自身业务的特殊性实现某些公共接口即可。另外,从性能角度考虑,我们牺牲了一些代码可读性,把某些逻辑并行化了。 随着业务的发展,搜索场景开始进入快速迭代期,新增策略越来越多,我们的主体框架也是在这个时候逐渐变得不灵活。 如果动主体框架,搜索以外的场景都需要跟着重构。 在业务的快速发展期,工期根本不允许,因此我们只能在现有框架上进行补丁式的开发。 这样,带来了两个很明显的问题: 1、为了兼容搜索的特殊逻辑,我们需要在其他场景中增加各种 if 判断来绕过这些逻辑。 2、广告策略越来越多,累计了几十个,当框架失去清晰的结构后,有些策略的实现开始变得定制化,缺少层次化的划分和可插拔式的抽象设计。 在这样的背景下,随着改动的积累,代码开始偏离了设计的初衷,技术债务越来越重。但是,我们又始终找不到合适的时机进行重构。 转机出现在 2019 年年底,由于广告业务的特殊性,流量开始自然走低,另外产品运营团队将重心放在了第 2 年的工作规划上,因此给了我们非常好的窗口期开始此次重构。 我们将工期定成了 1 个月,最终仅比预期晚上线了一天,虽然出现了两个线上问题,但是在灰度期都及时发现和修复了,并没有造成线上事故。 总体来说,这是一次难度颇大并且比较成功的重构项目,下面详细说一下我从这个项目中吸取到的宝贵经验。 02 重构前,我们做了哪些准备工作? 这次重构的代码量很大,3 万多行,而且是广告系统最核心的引擎部分。启动前,我们能预期到下面这些困难: 1、业务侧的阻力:广告是极其以业务为导向的,本次重构虽然能带来长期研发效率的提升,但是没法直接提升业务收益,而且开发周期不会太短,如何才能得到业务同学的支持? 2、技术侧的顾虑 :重构一旦引起线上事故,公司是有处罚制度的,如何让大家轻装上阵?同时,重构过程中如果还有非常重的业务迭代穿插,交付时间没人敢保证,质量也很难得到控制。 针对这两方的顾虑,我认为下面这几项工作起到了很关键的作用。 ▍让所有人看到痛点 前面提到:随着业务迭代,我们广告引擎的主体框架已经变得模糊不清,另外几十个广告策略散落在不同的业务场景中,配置凌乱。 针对这两个痛点,我们提前1个月启动了现有业务的梳理,走读旧代码、同时翻阅以前的需求文档,最终我们将不同场景的核心流程以及广告策略归类成了一张清晰的表格。 正是这一张表格,让技术和产品第一次很清晰地看到了我们引擎部分的全貌,体会到了业务的复杂度以及当前技术上的瓶颈。 ▍明确重构的目标和价值 让所有人感受到痛点后,我们规划了本次重构的两个核心目标: 1、主体框架的重构:将主流程模块化,重新定义上下层协议,确保接口清晰;各层级内部也需要做好抽象,具备良好的扩展性。 2、策略灵活可配置:将广告策略按照业务意图进行归类抽象,策略的执行条件动态可配置,同时策略可任意插拔。 此外,我们将这两个核心目标完成后可带来的预期收益进行了细化: 1、技术收益:代码结构更清晰,更容易理解和维护;可扩展性增强,引擎的开发效率将进一步提升。 2、业务收益:策略能做到更细粒度的配置和扩展,对业务支持更友好;研发提效后能进一步加快业务的迭代速度。 将重构的价值同步给大家后,进一步提升了所有人的兴奋度,让大家有了更强的动力参与进来。 ▍整体节奏的把控 整体节奏的把控也是非常重要的一环,能让所有人对这件事情有一个时间上的预期。 首先,我们将工期定成了 1 个月,一方面考虑了业务侧可以接受的最大周期,技术上也希望速战速决;另一方面,春节即将来临,我们必须赶在公司封网前上线,同时预留出1-2周的 buffer 以防意外情况发生。 此外,我们和业务侧达成了一致:重构期间,引擎部分的非紧急需求一律不接,这样可最大限度地减少并行开发和代码冲突,让团队精力更集中。 03 执行过程中有哪些可分享的经验? 这次重构能够实施得如此顺利,有 4 点我认为很有价值的经验跟大家分享下。 1. 高质量的技术设计方案 这一点得益于日常的要求,针对开发周期超过3天的项目我们都会进行技术方案设计,本次重构当然也不例外。 框架部分的整体架构、模块之间的协议设计、以及策略的可扩展性设计是本次技术方案的重点,团队前后讨论了不下3次。 在大方案定稿后,团队进一步对数据库、接口字段、缓存结构、日志埋点等公共部分进行了细化,因为涉及到多人协作开发,团队约定以文档作为沟通界面,文档始终保持和代码同步。 在这样的高要求下,团队产出了 5000 多字的技术方案文档,合计 36 页,这些为整体质量的保障打下了很好的基础。 2. 预重构出框架性代码 这一个 PR 非常关键,是我们从技术方案落地到代码最重要的一步。我们把重构后的包结构、模块划分、各层之间的API定义、不同广告策略的抽象进行了梳理,先忽略实现的细节。 这样主体代码基本成型,能很清楚地描绘出我们理想中的框架。然后,我们组织了多次集中代码审查,最终形成了统一意见。 这一步能很好地避免过早陷入实现细节,导致主体框架关注不够、代码不稳固,后期再返工反而会拖累效率。 3. 频繁沟通和成对代码 Review 机制 进入到细节实现阶段后,很重要的一点是:对现有逻辑的理解。引擎代码经过一年半的迭代,历史上被很多人开发过,但是本次只有 3 个同学参与重构。 整个过程中,我们遇到任何代码逻辑不明确的地方,都是反复沟通和求证,不主观猜想,这一份谨慎其实很关键。 另外在代码审查上,我们按模块分配了对这块业务比较熟悉的同学来负责,成对搭配,机制灵活。 4. 有效的测试方案 重构未动,测试先行。这个原则是《重构》一书中重点强调的,也是我们本次技术方案讨论的重点,我这里单独拎出来详细展开下。 首先,我们前期便约定好:不动任何老代码,完全建新的 package 进行重构。这样方便比对重构前后的结果,同时进行线上灰度实验。 测试方案上,以下 4 点值得借鉴: 1、端到端测试:本次重构不涉及功能性的调整,因此外层API的行为是不会有任何变化的,这样端到端的测试方法最为有效,这个是研发和QA测试最主要的手段。 2、冒烟测试:QA同学提供冒烟 Case,由研发同学进行冒烟,研发提测前必须保证所有冒烟 Case 执行通过。这一点在大部分互联网公司都不常见,但是对于大型项目绝对有效。 3、沙箱环境双流程验证:前面提到我们重构前后的代码都保留了,因此可以通过脚本抓取线上环境的入参作为case,然后用自动化的方式对 API 的返回字段进行逐一比对。 4、线上环境灰度实验:灰度对于重构非常重要,我们利用已有的ABTest平台,逐步放开灰度流量,从5%、到10%、到30%、最后到100%,制定了很谨慎的放量节奏,然后通过日志以及业务指标监控进行验证。 写在最后 回顾整个重构的过程,总结成下面 7 个关键点: 1、把握好重构时机 2、前期梳理很重要,先找到痛点 3、明确出目标和价值,让大家兴奋起来 4、不宜长线作战,不宜和业务并行 5、需要高质量的技术方案 6、重构未动,测试先行 7、小心求证,为每行代码负责 当然,最关键的因素还是人,大型项目重构极其考验团队的协作能力,如果每个人都很靠谱,重构就已经成功了一半。 特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下: 长按订阅更多精彩▼如有收获,点个在看,诚挚感谢 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-16 关键词: 嵌入式 代码

                      • 神了!UART/I2C/SPI/1-wire四大通信接口这么比喻秒懂!

                        1、 裘千丈轻功水上漂之UART 射雕英雄传中的裘千丈说,UART就是我的轻功水上漂过河。想从河上过(通信),提前布暗桩,行走时步伐按桩距固定(波特率提前确定),步幅太大或太小都会落水。为了不被二弟裘千仞识破,可以安排侍卫在对岸监视通知,没风险才开始表演(流控)。为了保证踩点准确,隔一段距离定个特殊标记的粗木桩。 UART 通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通信双方接三根线,RX、TX和GND,TX用于发送数据,RX用于接受数据,双方收发交叉对接,支持全双工方式。 因为没有时钟控制,什么时机开始发数据,且保证对方正确接收? 如A发数据到B,平时空闲时A.TX 和 B.RX.保持1,当A.TX先发0作为起始位,告诉B请注意,我要发数据了。然后就开始发数据,数据位可配置,通常是5位,6位,7位,8位,一帧数据发完后,A.TX给个高电平告诉B.RX我发完了一帧。如果开启校验位,在发停止位之前发送个校验位,一般都不需要校验位了,短距离有线传输出错的概率非常小。如果还有数据,则重复前面的操作。 一般软件配置串口,有波特率,数据位、停止位、校验位、流控。分别表示传输速度,一帧数据的长度,以及发完告知停止,发完是否校验,是否进行发送控制。看起来参数很多,针对个人经验,一般都是固定8位数据位,1位停止位、无校验、无流控,只是配置波特率。 UART没有时钟控制数据捕获时机,依靠通信前就定义波特率,双方按定义的频率读写数据位,正如裘千丈的水上漂,一旦暗桩安装固定,就得按固定的步长行走,否则就会出错落水。 UART在水上漂项目可以,但是传输效率有限,一般高到921600,如果再高可能出现误码,继续加高,就是高空飞行,最后裘千丈就是期望在高空也行走自如,想攀上黄蓉乘坐的大雕逃命,不慎坠落,死于飞行事故。 2、叫你一声你敢答应吗之I2C 作为太上老君看银炉的童子,银角大王最懂I2C,万千人中我叫你一声,你答应了就倒霉(从机地址正确才能通信)。 IIC(Inter Integrated Circuit)两根线,一条时钟线SCL和一条数据线SDA,所以是半双工通信,主从模式,支持一对多,一个银角大王可以对付一群猴子,每个猴子名字不同(从设备的I2C地址不同),点名叫到谁,谁就被紫金葫芦带走。 假设主机A给从机B发数据(A.SCL接B.SCL,A.SDA接B.SDA),根据应用,A可以同时接B,C,D。空闲时SDA和SCL上的电平都为高电平。 起始和停止起始条件S:当SCL高电平时,SDA由高电平向低电平转换;停止条件P:当SCL高电平时,SDA由低电平向高电平转换。起始和停止条件一般由主机产生,总线在起始条件后处于busy的状态,在停止条件的某段时间后,总线才再次处于空闲状态。 空闲时SDA和SCL上的电平都为高电平。A先把SDA拉低,等SDA变为低电平后再把SCL拉低(以上两个动作构成了I2C的起始位),此时SDA就可以发送数据了,与此同时,SCL发送一定周期的脉冲,SDA发送数据和SCL发送脉冲的要符合的关系是:SDA必须在SCL是高电平时保持有效,在SCL是低电平时发送下一位(SCL会在上升沿对SDA进行采样)。 传输与响应一次传8位数据,8位数据传输结束后A释放SDA,SCL再发一个脉冲(这是第九个脉冲),触发B将SDA置为低电平表示确认(该低电平称为ACK)。最后SCL先变为高电平,SDA再变为高电平(以上两个动作称为结束标志),如果B没有将SDA置为0 ,则A停止发送下一帧数据.。 整体时序I2C总线上的每个设备都有唯一地址,数据包传输时先发送地址位,接着才是数据。一个地址字节由7个地址位(可以挂128个设备)和1个指示位组成(7位寻址模式),0表示写,1表示读。一般芯片手册I2C地址都是7位地址,有些与某个引脚的电平相关,主机控制最后读写位。 实际项目一般都是采用I2C库,有的库要求传入的是8位的写的地址,有的是7位,由接口函数再区分读写补位。当然,最愚蠢的办法是从0到255定时循环读某个寄存器地址,读到正确值时的地址就是正确的从机地址。 一般情况下使用I2C库,除了配置从机地址,其他的起始、结束等时序等其实不太关注,只需要配置时钟频率,一般看从机最大支持多少,以及主机的系统时钟,太高会偶尔出现错误,再没有时间要求的情况下,时钟越低越稳定。 3、慕容复斗转星移之SPI 天龙八部的慕容复:虽然我不如乔峰可以使出降龙十八掌,但是他对我出手,我也以彼之道还施彼身,对方输出时也会被反噬,互相伤害,他停止时钟我也无可奈何。正如SPI,主机开启了时钟发数据,从机也在同时输出,时钟停,大家都收手。 SPI 串行外设接口(Serial Peripheral Interface)主从模式,一种高速的,全双工同步的通信总线。标准SPI是4条线。SDI(数据输入)、SDO(数据输出)、SCLK(时钟)、CS(片选,有些也称为SS)。 SDO/MOSI – 主设备数据输出,从设备数据输入 ,master output slave input;SDI/MISO – 主设备数据输入,从设备数据输出,master input slave output;SCLK – 时钟信号,由主设备产生;CS/SS – 从设备使能信号,由主设备控制。当有多个从设备的时候,主设备通过片选引脚选择其中一个从设备进行通信。(I2C是通过软件协议实现多选一,SPI是通过硬件实现)。 当主机控制CS,开启时钟闸门,主从双方就可以开始放数据位或者取数据位进行交互了,但是在什么时机开始,就有标准了。根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置。   CPOL:时钟极性选择,为0时SPI总线空闲为低电平,为1时SPI总线空闲为高电平    CPHA:时钟相位选择,为0时在SCK第一个跳变沿采样,为1时在SCK第二个跳变沿采样 mode CPOL CPHA 0 0 0 1 0 1 2 1 0 3 1 1 这样就有四种模式。以模式1为例,空闲时为低,第一次时钟跳变采样,也就是上升沿读数采样,对着下降沿放数据。如果实在分不清,还有愚蠢的办法,四种模式全部尝试一次,就可知道正确模式。 SPI传输数据没有位数限制,只要定义收 发高位在前还是低位在前,可以持续高速传输。 正如前面,若是乔峰收手,慕容复就没法使出降龙十八掌的效果,但是他可以当面骂乔峰是契丹狗,乔峰一怒之下就发功,慕容复就奸计得逞。这契丹狗三字翻译为软件术语就是触发中断,从机发中断告知主机我有事来找我;主机定时查询也可实现,只是使用情况更少。 4、裘千尺的吐枣核绝技与1-wire 裘千丈的三妹裘千尺被囚地下,她以口喷射枣核钉打在枣树,树的摇晃就会掉下枣子充饥。这枣核钉是单向操作,用力过猛,枣核透过枣树,用力太轻或者射偏了,枣树没有反应,这样枣核用完了就悲剧了。可见这绝技,看起来简便,实则背后隐藏了精确控制,对时机、位置控制要完美,如1-wire通信,单线控制,时钟精准。 1-wire总线接口简单,一根线就可以,一般内部开漏输出,外部硬件上拉。 1-wire使用一条线来传送的四种信令组成,包括复位脉冲和在线应答脉冲的复位序列、写 0 时隙、写 1 时隙、读时隙。除在线应答脉冲以外,所有其它信号都由总线主机发出,并且发送的所有数据和命令都是字节的低位在前。主机与从机的数据通信是通过时隙完成的,在每个时隙只能传送一位数据。通过写时隙可把数据从主机传送给从机,通过读时隙可把数据由从器件传送给主机,将完成一位传输的时间称为一个时隙。 一般操作流程参考外设芯片手册,主要是不同平台的延时处理,需要软件实现1us延时的接口,否则数据通信异常。 5、秘籍功法 四种接口,每个都有合适的应用场景,对硬件端口的占用、对软件的控制要求、通信效率也不相同。尤其前3种属于常用协议,一般都支持硬件接口,厂家也一般提供hal库,对软件开发人员的要求逐渐降低。这也导致代码应用很溜,实际底层原理略微欠缺,一旦通信异常或者有特殊需求就无从下手。如使用GPIO模拟出UART,使用SPI实现AT功能。 武林人士一般都追求失传的武林秘籍,正如软件开发人员,有问题总是寄希望与其他人的经验总结,或者厂家的技术支持或源码,而不是创造新的功法。笑傲江湖的岳不群本是华山派掌门,精通紫霞神功,武功属于一流,但是没继续专研自家内功,为了辟邪剑谱自宫了,软件开发人员想重蹈覆辙么? 不论剑宗、气宗,先把功能跑通再反推代码原理和实现流程,还是先理清时序和原理再编码实现功能,短期内剑宗效率高,加工资快;气宗则可能被淘汰,尤其在势利的小公司,不注重新人培养。如果合二为一,项目紧急则拿来就用,空闲时专研总结,取长补短,则是完美开发人员的素质。 软件开发没有秘笈功法,全靠个人学习总结。 -END- |?整理文章为传播相关技术,版权归原作者所有?| |?如有侵权,请联系删除?| 【1】国内MCU能替代国外产品吗?MCU的未来又将如何? 【2】35岁真的是程序员的坎儿吗? 【3】不同编程语言能耗不同?看这27种语言对比! 【4】超长干货为你解析:从串口驱动到Linux驱动模型,嵌入式必会! 【5】本文把TCP/IP讲绝了! 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-16 关键词: 通信技术 uart

                      • 雷军:如果程序人生的话,这条路太漫长

                        这篇文章是在雷总个人博客看到的,里面聊到了他作为程序员的一些经历、初衷以及思考。写的不错,便转来给大家看看。 如果程序人生的话,这条路太漫长 我并非天生喜欢写程序,上高中时也没有想过程序员的生活。 我学电脑非常偶然,小时好友上大学时选择了计算机系,为了和这个朋友有更多的共同语言,我也选择了计算机系,开始步入程序人生的道路。 当我学会一些后,发现自己特别喜欢写程序。我是八七年上的武汉大学计算机系,大一下学期才有专业课。当我有资格上机的时候,发现电脑世界太美妙,就一头扎进去。 当时用的是 Motorola 68000 (相当 于 Intel 8088), 540K 的内存,运行的 UNIX 操作系统,八个人一起用。 大二学PC,又过了一学期,开始出现在老师的实验室,帮忙干活,当时就写了现在很多人用的 RI (RAMinit, 清内存的小工具, 看来我还是最早一批写 Shareware 的人)。 又过了一个学期,开始和校外的公司接触。大二暑假,也就是1989年8月,和一个朋友组建了 Yellow Rose 软件小组,写了我第一个商品软件 BITLOK 0.99。后来自己创业办过公司,也写过一些其他的软件。 大学毕业后,分到研究所,不太适应那里的气氛,就在1992年初加入金山软件,开始了职业程序员的生涯。后来成了金山软件研发部门的主管,但我一直都是一线的程序员。 程序员活在自己想象的王国里 我刚接触电脑就发现电脑的妙处,电脑远没有人那么复杂。如果你的程序写得好,你就可以和电脑处好关系,就可以指挥电脑干你想干的事。 这个时候你是十足的主宰。每每你坐在电脑面前,你就是在你的王国里巡行,这样的日子简直就是天堂般的日子。 电脑里的世界很大,编程人是活在自己想象的王国里。你可以想象到电脑里细微到每一个字节、每一个比特的东西。 我爱编程这个工作,可以肯定我会干上一辈子 不少人认为程序员最多干到三十五岁就可以收山换环境了,脑子也差不多该歇歇了,体力也不支了。并认为写程序是年轻人的事情,到了一定岁数,估计没什么人再当程序员了。 当我刚有一点本事的时候,我也和大家一样觉得编程辛苦,也想三十岁后干别的。当我年长一点后就发现了自己的无知。 一个人大学毕业就二十一二岁,有点水平的时候可能二十五,接着就是过日子诸多事情。一切搞掂的时候,也许就是三十五岁。如果这样的话,我们就不用选择程序人生的道路。 电脑进入中国时间并不短,但真正大规模开始用,还是八五年 PC 开始的,因此国内真正写电脑程序的人最长也就写了十几年(不知道是否还有这样的人)。 由于电脑应用在国内时间比较短,国内开发的主力是三十五岁以下的年轻人为主。但这不表示程序员如同红粉佳人般的容易衰老。美国主力工程师以三十四十多岁的人为主。 开始的时候,我们觉得我们没有什么不能做的(现在还能听到这样的豪言壮语),而且更要命的是好象我们特别聪明,特别适合开发软件,比老外强得多。 当我们真正接触那些杰出的开发人员的时候,发现他们太厉害了,都有十多年的开发经验。虽然也有很多年轻人做了很多好东西,但决大多数的产品出自这些有丰富开发经验的程序员的手。 刚毕业的时候,编程不仅仅是爱好,而且也成了一辈子的工作。整天不知道写些什么东西,觉得特别没劲,找不到感觉,特别灰心。 后来,才明白, 只有全身心地投入,程序才会有感觉。 写程序的活特别费脑子,也特别累,但我喜欢,可以肯定我会干上一辈子,虽然我没有打算一生只干这一件事。用一生来编程序是一件既容易又困难的事。 如果碌碌无为,为交差写点程序,这样的日子太好混了。但如果想全身心地写程序,写十年就不是一件容易的事。 现在我不少朋友都洗手了,有时我也想“用什么电脑呀,Windows 外的世界不是也很大吗?”。 面对电脑的时候,立刻顿悟:写程序还是自己最擅长的事,也是最喜欢的事。 高级程序员不是追求的目标 有的人学习编程技术,是把高级程序员做为追求的目标,甚至是终身的奋斗目标。后来参与了真正的商品化软件开发后,反而困惑了,茫然了。 一个人只要有韧性和灵性,有机会接触并学习电脑的编程技术,就会成为一个不错的程序员。刚开始写程序,这时候学得多的人写的好,到了后来,大家都上了一个层次,谁写的好只取决于这个人是否细心、有韧性、有灵性。掌握多一点或少一点,很快就能补上。 成为一个高级程序员并不是件困难的事。 当我上学的时候,高级程序员也曾是我的目标,我希望我的技术能得到别人的承认。后来发现无论多么高级的程序员都没用,关键是你是否能够出想法出产品,你的劳动是否能被社会承认,能为社会创造财富。成为高级程序员绝对不是追求的目标。 编程不仅仅是技术,还是艺术 有人认为编程是一种熟练工种,也有人把编程说成是艺术创作。这两种意见争论比较激烈。 我们换个工种来看,石匠应该是熟练工种,属于工人,更和艺术似乎沾不上边。但正是这些石匠,给我们留下多少文物古迹,如乐山大佛、莫高窟等等。应该说这些石匠给我们留下了无穷的文化财产。 现代软件工业已具相当规模,很多软件的完成需要的是大兵团作战。一名普通程序员接受编写某一模块的任务后,往往只是写代码,发挥的余地很小。 在大项目中,很多程序员只能了解到和自己所编模块相关的很局部的细节,另外还受到开发环境的限制,真的很难体会到自己在从事”艺术”创造,更多的时候是感到自己在从事重体力劳动。 有的时候还担心自己苦苦参与的这个项目究竟有没有意义,是不是在同类产品中有竞争力,会不会开发出来以后就因为硬件的发展,操作系统的换代而过时…… 我认为编程的工作和石匠比较相似,有技术活,更多的是体力活。不管怎么说,写出一个好软件不是一件容易的事。 这两种想法都有片面性,编程应该说两种属性都有。编程不仅仅是技术,也还是艺术。编程是技术活,才有可能大规模进行,才会有软件工程和软件工厂。也正是编程是艺术,才会有如此多的好产品,让大家如痴如醉。 著名程序编程指北点评表示,雷总是中国最早的一批程序员,极具极客精神。他把写程序当作一生的追求,完全没有去考虑程序员是吃青春饭的问题,全身心的投入到代码王国。 在他眼里编程不仅仅是谋生的一个技能,更是一种艺术。这也许就是极客程序员和普通程序员的区别吧。 希望诸君共勉,未来能在核心工业软件摆脱美国制裁上贡献属于自己的一行代码! -END- 直接来源 | 编程指北 作者 | 雷军 原文 |?http://leijun.blog.techweb.com.cn/archives/10 |?整理文章为传播相关技术,版权归原作者所有?| |?如有侵权,请联系删除?| 【1】国内MCU能替代国外产品吗?MCU的未来又将如何? 【2】35岁真的是程序员的坎儿吗? 【3】不同编程语言能耗不同?看这27种语言对比! 【4】超长干货为你解析:从串口驱动到Linux驱动模型,嵌入式必会! 【5】本文把TCP/IP讲绝了! 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-16 关键词: 互联网 程序员

                      • 小白如何自学单片机?

                        很多刚开始学习单片机的小伙伴最苦恼的就是如何入门,不知道从哪一部分开始、在哪里查找学习资源、按照怎样的学习步骤进行学习,而且摸索学习步骤的过程在浪费时间的同时也会降低学习兴趣。为了帮助大家解决这种情况,小编将单片机达人的学习经验进行了整理,以文章的形式分享给大家。 一、基础理论知识 要掌握理论知识,第一步还是要通读一遍教材,这样我们才能站在巨人的肩膀上。《电工基础》、《电路分析》、《模拟电路》、《数字电路》、《电子制作》等电子技术基础知识一定要先通读。 (1)电场与磁场:库仑定律、高斯定理、环路定律、电磁感应定律。 (2)直流电路:电路基本元件、欧姆定律、基尔霍夫定律、叠加原理、戴维南定理。 (3)正弦交流电路:正弦量三要素、有效值、复阻抗、单相和三相电路计算、功率及功率因数、串联与并联谐振、安全用电常识。 (4)RC和RL电路暂态过程:三要素分析法。 (5)变压器与电动机:变压器的电压、电流和阻抗变换、三相异步电动机的使用、常用继电-接触器控制电路。 (6)半导体及二极管及整流、滤波、稳压电路。 (7)三极管及单管放大电路、信号处理电路、信号发生电路、功率放大电路、直流稳压电源等。 (8)电子产品工艺流程、电子产品的结构和装配、调试和检修。 (9)线性集成运算放大器和运算电路及理想运放组成的比例、加减和积分运算电路。 (10)数字基础及逻辑函数化简、集成逻辑门电路、组合逻辑电路和RS、D、JK触发器,时序逻辑电路。 (11)多谐振荡器、单稳态触发器、施密特触发器的结构、工作原理、参数计算和应用。 (12)数模和模数转换等相关内容。 二、常用软件 (1)Protel99se、AltiumDesigner9等PCB电路设计软件。 (2)Multisim11、Proteus7.8等电子电路原理仿真设计软件。 (3)Keil、Progisp20等单片机应用程序开发平台相关设计软件。 三、资料检索 很多时候遇到问题,要查找资料的时候却不知道去哪里找,这里小编给大家推荐三个网站:GitHub,StackOverflow,中国知网。 GitHub 程序员都会用到的一个代码托管网站,熟悉的人就不用我多说了。在上面可以搜索到很多很好的开源项目。 StackOverflow 英文网站,英文水平要好。上面可以搜索到很多技术细节上的问题,回答大多都会比较靠谱,有点类似知乎,但问题主要是IT相关的。 中国知网 如果你想做一个项目但是还不知道应该从哪里入手或遇到了技术上的阻碍,就可以在这里搜一搜,期刊和论文的一般会有转载,有助于你系统了解相关的知识。如果是在校大学生,使用校园网应该是可以免费下载文档的。如果不是,可以上某宝租账号下载。 四、实践 实践是检验真理的唯一标准。对一个学单片机的新手来说,如果按教科书式的学法,上来就是一大堆指令和名词,结果学了半天还是搞不清这些指令的作用,也许用不了几天就会觉得枯燥乏味以至于半途而废。 所以学习与实践结合是一个很好的方法,边学习、边演练,循序渐进,这样用不了几次就能将所用到的指令理解、吃透、扎根于脑海,甚至让这些指令“根深蒂固”。 -END- |?整理文章为传播相关技术,版权归原作者所有?| |?如有侵权,请联系删除?| 【1】国内MCU能替代国外产品吗?MCU的未来又将如何? 【2】35岁真的是程序员的坎儿吗? 【3】不同编程语言能耗不同?看这27种语言对比! 【4】超长干货为你解析:从串口驱动到Linux驱动模型,嵌入式必会! 【5】本文把TCP/IP讲绝了! 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-16 关键词: 嵌入式 单片机

                      • 手把手教你升级Keil MDK的ARM编译器

                        作者?|?strongerHuang 微信公众号 | strongerHuang 今天在我的技术交流群里,有朋友问了这么一个问题:怎么才能用更高的编译器呀? 这位朋友给了一张图: 从上图可以看得出来,这位朋友使用的Keil MDK并不是最新版本。目前(2020-11) 最新MDK版本为V5.32 ,默认编译器版本为V6.14.1: 如果我想使用V6.15版本编译器该怎么操作呢?那么下面就来讲讲:怎样将Keil MDK的编译器升级为最新的编译器(更换为指定版本的编译器): 下载ARM编译器 安装ARM编译器 Keil 配置编译器 额外说明 strongerHuang 1 下载ARM编译器 这里不一定是使用最新的编译,我们也可以使用老版本的,目前官方提供了历史版本供大家下载。 通过浏览器自带下载器可能比较慢,推荐使用迅雷,很多都有镜像,速度相对快点。 strongerHuang 2 安装ARM编译器 安装之前需要提醒一点,根据你Keil MDK版本不同,支持的编译器可能存在兼容问题。比如MDK是V4版本,建议下载32位版本。 我这里以ARM编译器Windows 64位为例,安装过程比较傻瓜式,基本一路“next”即可。 这里建议修改一下路径: 安装完成之后,会有相关的说明文档,可以看下: strongerHuang 3 Keil?配置编译器 Keil MDK里面有很多配置选项,这里推荐大家阅读我的《 Keil系列教程 》。 1.打开工程管理,进入“Folders/Extensions”选项栏 可以通过菜单:Project -> Manage -> Project items进入。 也可以通过工具栏工程管理快捷图标: 2.修改(新增)编译器 3.工程选择编译器 新增编译器之后,就可以在工程配置中选择新增的编译器了: 此时就可以和往常一样正常使用了。 strongerHuang 4 额外说明 1.编译器注册 不管是Keil MDK,还是ARM编译器都是收费的工具,就会牵涉到注册的问题,如果按照上面的步骤直接使用ARM新增的编译,可能会出现如下错误: 意思就是没有进行注册,此时就需要花钱购买正版了。。。 不想花钱购买正版的同学自己想办法了,下面方法不要说是我给大家的哈: 正确注册之后,就会没问题: 2.工程选项配置的变化 如果我们选择了不同的编译器,可能你Keil MDK的工程选项就会发生变化: 当然,这个变化与你MDK版本还是有一定关系(不同版本可能不同)。 最后,大家想要阅读更多关于 Keil MDK的内容,后台回复"Keil"?即可查看。 ------------ END ------------ 推荐阅读: C语言实现面向对象的原理 程序员进阶需要掌握的几大排序算法 Embedded Studio中使用ST-Link调试教程 注

                        时间:2020-11-16 关键词: 计算机 编译器

                      • 分享一个通过STM32的bin文件逆向分析代码的工具

                        转载:芯片之家 来源 |?阿莫论坛,作者 | ilovepp 首先你要有一个bin文件(bin文件的获取方法不在此展开介绍,今后有机会可以专门开一个贴聊一聊)。本次实验用到的bin文件 stm32_xwrtos.bin.zip?(6 KB) 是用ST官方CMSIS和外设库编译的跑在stm32f103c8t6上的bin文件,比较具有代表性。 烧录文件下载 工具准备: 安装开源跨平台逆向神器r2: r2可运行在Windows、Linux、Mac等所有主流操作系统上(r2有多牛逼不在此展开介绍,今后有机会可以专门开一个贴聊一聊)。 实验步骤: 1)输入r2 -a arm -b 16 -m 0x08000000 stm32_xwrtos.bin 进入r2的控制台后,输入e asm.cpu=cortex。这一步是告诉r2以0x08000000为基址加载stm32_xwrtos.bin文件,并设置指令集为cortex系列的thumb。 2)输入aaaa,运行自动化分析。 3)输入pxw 268 @0x08000000 以小端四字节形式打印从0x08000000开始的268(268对应中断向量表大小)个字节,同时打开ST官方的启动文件startup_stm32f10x_md.s并找到.isr_vector段进行对照。 4)接着上一步,输入fs notes,创建并切换到一个名为notes(可以是任意其他名字)的符号记事本;按照f flag=address的形式,对照.isr_vector段,向符号记事本中录入感兴趣的符号地址对应关系。注意如果address是函数地址则需要减1(因为thumb指令的要求,具体原因此处不展开);最后输入af @flag形式的命令强制进行函数分析。 5) 输入pdf @Reset_Handler,对Reset_Handler函数进行反汇编 输入 VV 切换到流程图视图 通过阅读汇编代码,可以得到以下信息: 1.??data段的地址区间为0x20000000-0x20000028 bss段的地址区间为0x20000028-0x2000043C 2.??Reset_Handler用0x08002cbc开始的0x28字节初始化data段,用0填充bss段 3. 调用fcn.08001cc8函数 4. 调用fcn.08001734函数 6)输入pdf @fcn.08001cc8进行反汇编 发现对外设寄存器地址0x40021000的引用 通过查询数据手册,可判断fcn.08001cc8函数应为系统初始化化函数SystemInit(),它初始化了时钟。 7)根据经验判断fcn.0800173函数即为main函数 本篇主要作用是带大家熟悉和习惯r2的基本使用,以及对逆向有个感性认识。后面有机会再给大家讲述在逆向的基础上介绍stm32上的栈溢出漏洞的挖掘与利用。 再次感谢ilovepp兄分享的精彩文章! ------------ END ------------ 推荐阅读: C语言实现面向对象的原理 程序员进阶需要掌握的几大排序算法 Embedded Studio中使用ST-Link调试教程 注

                        时间:2020-11-16 关键词: 嵌入式 代码

                      • 龙飞船一飞冲天,载人龙飞船开启正式商业运营

                        龙飞船一飞冲天,载人龙飞船开启正式商业运营

                        众所周知,NASA官员周二正式批准SpaceX的载人龙飞船向国际空间站进行宇航员的定期轮换任务。美国当地时间15日,4名航天员将乘坐SpaceX公司的载人“龙”飞船进入轨道,美国国家航空航天局(NASA)希望这将是SpaceX公司保证国际空间站人员天地往返飞行的良好开始。标志着载人龙飞船的正式商业运营。 3位NASA航天员——迈克尔·霍普金斯、维克多·格洛弗和香农·沃克将与日本航天员野口聪一共同参加这次飞行。周日的发射时间也将取决于天气情况。 不过,根据美国军方第45太空联队的最新预测,周日出现有利条件的概率似乎比周六更低。 此次发射之前,载人“龙”飞船在5月首次进行历史性的载人飞行任务,但那次飞行仍被认为是一次“验证”任务,由两名资深的NASA航天员和前军方试飞员驾驶。美国哥伦比亚广播公司14日称,为了达到“正式运行”状态,NASA必须让SpaceX的载人“龙”和“猎鹰9号”火箭达到载人级别。这是一个非常耗时耗力的过程,最终通过两次测试飞行得以完成:一次是无人飞行,另一次是将两名航天员送到国际空间站。 多年来,俄罗斯的“联盟”号飞船一直是空间站工作人员的运载工具。SpaceX公司改变了这一局面。NASA表示,“机组1号”在上次飞行经验的基础上进行了“多次升级改造”。本次飞行任务将是载人龙飞船首次正式乘员任务。之前载人龙飞船先后执行过一次不载人与ISS对接的Demo-1任务和载两名宇航员与ISS对接的Demo-2任务。 虽然 SpaceX 公司将于周末开始其首次正式机组人员飞行,但波音公司仍在继续解决去年其 Starliner 太空舱无人驾驶测试飞行时遇到的软件问题。下一次没有宇航员参与的Starliner飞行器试飞将于明年1月起飞,随后将在明年晚些时候进行一次三人机组的演示任务。如果载人龙飞船在周日如期升空,Crew-1的宇航员将在8个半小时后与空间站对接。 至于更多详细信息,我们拭目以待。不如让我们一起期待一下。

                        时间:2020-11-16 关键词: spacex 龙飞船 载人飞行

                      • 千呼万唤始出来!三星Galaxy A12跑分曝光网络

                        千呼万唤始出来!三星Galaxy A12跑分曝光网络

                        11月4日 突然发现一个问题,在国内似乎没有销售三星的中低端手机或是入门级机型,不知道大家注意到没有,众所周知三星的A系列机型就是主攻入门级市场的中低端机型,但是在国内并没有销售渠道,三星入门级机型 Galaxy A12 现已出现在了 。Geekbench 上,同时揭示了该机将搭载联发科 Helio P35 芯片组和 3GB 的运存。其他方面,虽然NFC网站没有标注三星A12手机的参数信息,但是之前的爆料称该机将具备64GB内存,比A11手机多了一倍。 手机采用后置三摄设计,配别的是LCD屏幕,背部还有一个物理指纹识别传感器。三星A12手机运行基于Android 10系统定制的OneUI系统。 该机型型号为 SM-A125F。跑分信息显示,该机搭载了频率为 2.3GHz 的联发科技 Helio P35(MT6765)芯片组,并配备 3GB RAM,运行 Android 10 的操作系统。 IT之家了解到,该智能手机的单核得分为 169,多核得分为 1001,证明了该机可提供足够的入门级性能。关于这款手机其他方面的消息甚少,不过有爆料者称它将提供 32GB 和 64GB 存储版本可选。 值得一提的是,该机型并非三星旗下最低级的机型,此前有还有一款三星 Galaxy A11,搭载高通骁龙 450 芯片,提供 2+32/3+64GB 的存储可选,采用 6.4 英寸HD+ 屏幕,同样 Android 10 操作系统,后置 13MP + 5MP + 2MP 三摄,前置 8MP 镜头,内置 4000mAh 电池,支持 15W 快充。三星 Galaxy A12预计将在该机基础上进行一定优化升级而来。 遗憾的是,该网站没有透露更多关于该机的参数和外观信息。不过作为三星A11的迭代机型,相信会比前者有很多升级。。至于更多详细信息,我们拭目以待。不如让我们一起期待一下。由于该机仍在开发中,因此后续会有更多的配置信息曝光出来,21ic会持续跟进。

                        时间:2020-11-16 关键词: 三星 跑分

                      首页  上一页  1 2 3 4 5 6 7 8 9 10 下一页 尾页
                      发布文章
                      亚洲 日韩 国产 有码 不卡