【CSDN 编者按】在本文作者看来,SOA带来的组件化使OTA(Over-the-Air Technology,空中下载技术)升级成为可能,也让独立第三方软件开发商进入的门槛大大降低。

作者 | 张航       责编 | 张红月

出品 | 《新程序员》编辑部

“软件定义汽车”最关键的环节是SOA(Service-Oriented Architecture,面向服务的架构)。基于硬件算力提升、车载以太网的发展,以及汽车网联化带来的影响,SOA在二十年后将被重新召唤。

张航,中科创达智能汽车事业群首席架构师兼工程VP。2003年获得武汉大学计算机专业硕士,曾经就职于IBM、NEC等国际知名企业。2008年加入中科创达至今,参与了多款智能手机、智能平板、IoT设备的研发项目,历任研发总监、架构师等职务。2015年加入智能汽车部门,专注于智能汽车操作系统的研发和技术预研。

软件定义汽车不是口号

“软件定义汽车”是近来很火的概念。2016年,前百度高级副总裁王劲提出“软件定义汽车(Software Defined Vehicle,SDV)”。在2019年达沃斯论坛上,大众CEODr. Herbert Diess宣布,大众要转型成为一家软件驱动的公司,并且发布《软件定义汽车》的文章。此后整个2020年,SDV这个词一直萦绕在汽车行业的各种会议和论坛上。但事实上,整个行业对于软件定义汽车的认识是不太一致的。

首先,在未来的汽车中,软件部分的价值会逐渐提升,这在行业内已基本达成共识。根据普华永道的预测,到2030年,汽车软件占汽车总价值的比例将会达到60%以上,开发成本增加83%以上。在智能座舱、自动驾驶、ADAS(Advanced Driving Assistance System,高级辅助驾驶系统)、能源管理等方面,软件部分的创新将占整体的90%以上。因此,整个2021年上半年,汽车行业内呈现着软件人才紧缺的现象,各个整车厂和零部件厂商都在大力筹建自己的软件研发团队。

然而,并非所有人都赞同“软件定义汽车”,有一种意见就认为,这不过是IT行业进入汽车领域的宣传,硬件和制造仍然是汽车行业赖以生存的基础,或者认为软件必须要基于电子电气架构的算力才能充分发挥作用,所谓软件定义汽车才能实现。

那么,到底谁对谁错?其实刨除“屁股决定脑袋”的言论,“软件定义汽车”这件事情正在发生。华为智能汽车解决方案BU CTO蔡建永曾说:“软件定义汽车,即软件将深度参与到汽车的定义、开发、验证、销售、服务等过程中,并不断改变和优化各个过程。实现体验持续优化、过程持续优化、价值持续创造。”应该说这个解释是目前为止比较客观、中肯和实际的。

换句话说,软件并不会取代硬件和制造环节,但软件会成为其他环节改进、发展和演进的方向标,包括电子电气架构(EEA)、汽车研发过程等都在发生着的变化。

例如,EEA的演进方向从分布式ECU(Electronic ControlUnit,电子控制单元)阶段,到域控制器融合,再到中央计算平台阶段。这个演进过程,一方面是为了提升电子电器元件的集成度,降低成本的同时节约空间;另一方面也是为了提升硬件的标准化程度,方便软件更新迭代,加快汽车驾乘体验的改进和迭代。因此,软件只是“定义”了汽车,但并不会“实现”汽车

另外,“软件定义汽车”不仅仅对于汽车的定义和开发阶段有影响,也会延伸到销售和服务阶段,甚至改变汽车的商业模式,如特斯拉的辅助驾驶包和自动驾驶包付费升级模式。同时,越来越多的车厂计划把收费模式延伸到销售以后,如资讯订阅、车主团购服务等。再比如,如果可以通过OTA升级软件就能实现召回,成本可以降低90%以上,整车厂就能承受更多的试错成本,从而改进用户体验。

汽车系统的发展趋势

在“软件定义汽车”的推动下,汽车电子电气系统的演进呈现两大新趋势:一方面是用户体验上的提升,包括对用户行为的感知能力提升和交互能力的智能化改进,如DMS(Driver Monitor System,驾驶员监测系统)、语音交互、炫酷的HMI(Human Machine Interface,人机界面)等(见图1);另一方面是整车异构系统趋向标准化、虚拟化和服务化,如EEA架构的集中化和软件架构的SOA化。大量ECU将被集成到中央计算平台上,变成一个独立的Service加子板上的一个外设。

图1 基于Kanzi引擎的HMI交互场景(来源:中科创达)

总体来说,前者更类似于消费类电子的发展趋势,尤其像手机。这也是为什么Android在智能座舱中的占有率逐年上升,大有一统江湖的趋势。而后者更像边缘计算乃至云端系统的技术演进趋势,如虚拟化、容器、SOA。两个趋势有共同的路线,如对于大算力、虚拟化、高吞吐量总线的要求,以及信息安全和网络安全的要求。但其中也有一些差异点,如对于功能安全、低延时、界面响应速度的要求等。

由于这些差异性,到目前为止整车系统的融合没法做到彻底,这也是为什么大部分车厂的EEA、架构要分三步走,因为智能座舱域和其他要求功能安全或实时性要求高的域控制器还无法完美融合。而比较激进的特斯拉,将这些异构系统整合到AutoPilot系统中,导致了其系统安全性、实时性等均受到影响。目前,绝大部分整车厂下一代车型的EEA虽然选择了中央计算平台的架构,但智能座舱部分要么是以外设子板的形式存在,要么还是独立的域控制器。

相对于硬件架构,软件,尤其是操作系统的集中化趋势比较明显。在中控娱乐系统领域,Android的优势愈加明显,除了国内几乎全线使用Android外,欧美的几大车厂都开始放弃原来的自有系统或GENIVI系统,转向Android。国内的斑马OS背靠少数几家车厂和阿里的生态,维持着一定的份额,丰田还在坚守自己发起的AGL(Automotive Grade Linux,面向整个汽车行业的开源平台)联盟,Windows、QNX等系统则基本退出这个领域了。不得不说,Android依靠手机市场培育出来的开发者生态,基本可以碾压其他OS,尤以中国市场为最。试想一下,某互联网企业开发出一款Android版的手机App,通过简单适配就可以移植到车机上,这个性价比可以接受。但假如需要投入大量人力、物力,去重新开发一个Linux版,却只能获得最多几十万用户,这个账肯定不划算。AGL就面临这个问题,它的生态环境不足以支撑OS继续下去,也许学学Windows和鸿蒙,兼容Android应用是条活下去的路。

座舱以外的系统我们一般会从内核和中间件层来分析。这些域用的都是实时操作系统(RTOS),如BlackBerry的QNX,Green Hills Software的INTEGRITY、RTLinux等。出于功能安全的要求,这些系统中大部分设计和实现都是“久经考验”的商业操作系统。例如,QNX就通过了ISO26262的ASIL-D级别认证(D级为最高等级要求)。当然RTLinux不属于“大部分”,因为Linux的数百万行代码,如果都按照ISO26262的要求过一遍,合格的最后剩不了几行,单就内存静态分配这一条就过不去。

而中间件层,针对自动驾驶域,目前有ROS2(RobotOperating System,机器人操作系统)、Autoware、Apollo等架构。由于自动驾驶对于大数据量(图像数据和雷达数据)的传输和低延时(10ms级)的要求,这些架构都专注于数据传输和实时性上,使自动驾驶域的感知、决策和控制部分能够更好地协作。

对于传统车身控制这部分,仍然是AUTOSAR(汽车开放系统架构)的天下,只不过慢慢从AUTOSAR Classic Platform(AUTOSAR CP)演变为AUTOSAR Adaptive Platform(AUTOSAR AP)。说起AUTOSAR,可以算是“软件定义汽车”的原始版本,研发人员用开发工具把汽车信号、硬件环境等配置写到配置文件,通过AUTOSAR的编译器,生成一堆代码和中间件模块,再自动编译成MCAL(Microcontroler Abstraction Layer,中间件模块),与BSW(Basic Software ,硬件支持模块)RTE(Runtime environment,运行环境)和App一起链接成ECU的固件(Firmware),可以说研发人员就是通过一堆参数,“定义”了一个汽车的部件——ECU。

然而,这个理念跟我们提到的“软件定义汽车”是背道而驰的。AUTOSAR体现的是软件决定论,也就是研发人员决定了定义,定义决定了汽车,这背后是工业时代技术人员的傲慢。而“软件定义汽车”是适者生存论,所谓的“定义”是动态的,会根据外部的反馈不断调整、改进,达到更优的状态,这背后是信息时代的新思维。

AUTOSAR AP也没有从根本上改变AUTOSAR,因此我个人的观点是:在目前域控制器融合阶段,智能驾驶和车身控制分开的情况下,自动驾驶系统和AUTOSAR系统会各司其职。到中央计算平台阶段,AUTOSAR的地位会逐渐不保,有可能会被SOA取代。

本文摘录自《新程序员002》

为什么是SOA?

既然提到了SOA,我们就展开来说说汽车系统中的SOA。SOA并非新概念,在2000年左右IT界就已经存在,那为什么在时隔20年之后又被提出来了?综合内外部因素,有以下几个原因。

硬件算力提升,使得SOA成为可能

因为传统ECU一般都是MCU(Microcontroller Unit,微控制单元)主控,算力不足,甚至都没有操作系统,不足以支撑SOA这种沉重的架构。随着汽车智能化和网联化,汽车芯片的算力大大提升,新的域控制器或中央计算平台都是基于SoC(System on a Chip,系统级芯片)的,算力已经超过手机,直逼PC,因此能够支撑SOA架构。

车载以太网的发展是个催化剂

原本大量ECU分布式的系统,通过不同的总线CAN(Controller Area Network,控制器局域网)、LIN(Local Interconnect Network,区域互联网络)、Flexray等和特定的通信协议栈连接到一起,连接复杂度随着ECU数量增加呈指数级上升。一方面,通过减少ECU的数量,集中到域控制器和中央计算器,这是一个方法;另一方面,车载以太网相关的技术,如TSN(Time Sensitive Network,时间敏感网络)/AVB(AudioVideo Bridging,数字音频传输网络)等技术,使得原本以太网上车的问题(延时高、丢包率高等)得到一定程度的解决,基于IP的通信会取代原有大部分的CAN、LIN总线,减少线束成本和空间。相应地,软件上需要配合这个变化,将这些ECU的功能集成到系统中,这就是SOA起到的作用。

在智能座舱概念刚刚兴起时,可以看到整个座舱域里充斥着各种RPC(Remote Procedure Call,远程过程调用)的方法,每个原本的ECU都在按照自己的方式搭建与其他ECU的连接。SOA的优势在于,它可以用统一的方式将原本ECU的功能定义成一个个Service,并且通过注册、发现的方式集成到系统中,让其他的组件可以调用。

汽车网联化带来的影响

随着车云连接,呈现的车、云、路、人一体化的趋势,对系统架构提出了新的要求,原本只是汽车内部的架构已经无法解决这个问题。例如,在车上播放音乐,以前只有CD、U盘时比较简单,本地实现两个播放器引擎就可以。但现在加入了大量的在线音乐服务提供商,还可以通过手机播、车机放,这样情况就会复杂很多,如果每一种音乐源都要重新开发一套软件,开发维护成本会倍增。

前面提到过,传统车厂和供应商还在用RPC解决问题。但既然车云一体了,为什么不试着用云的方式解决问题?

干脆把云端的SOA拿到终端来,大家一致搞服务化。这样,前面音乐源的问题,就可以按照如下方式来解决:

先定义好音乐源的服务接口,本地或在线音乐,均按照同样的方式来实现服务。

每个车型根据需求和定义,将需要的音乐源服务注册到系统中。

现在只需要一个统一的播放器,就可以自由切换音乐源和对应的服务。这样,音乐源管理的问题就被简单化了。当然,实际的使用场景要复杂得多,但越复杂的场景,越需要简单,因此SOA的用武之地会越来越多。

事实上,SOA的思想在很多OS内部已经深入渗透。例如,Android的核心就由几十个原生服务和Java服务构成,Android的Binder和Service Manager其实也实现了SOA的大部分功能。早期Windows上的COM和DCOM,甚至可以实

现远程服务架构。那么,它们和SOA的区别到底在哪里?

首先,我们看两者的相同点。Binder、COM的本质是RPC,而SOA的内核是基于RPC的(对于云端而言是ProtoBuf、RESTful、HTTPS等,对于车端而言是SOME/IP、DDS等)。

两者的核心和关注点都是服务接口定义,因此不论是SOA、Binder还是COM,都定义了自己的服务/接口描述语言。一个东西需要单独定义和开发一套语言来描述,足以说明它的重要性了,SOA架构及工具链如图2所示。

图2 SOA架构及工具链(来源:中科创达)

那么,不同点在哪里?RPC的核心问题是要解决跨进程乃至跨系统通信的问题,通信的可达性、稳定性和传输效率是关键点。而且RPC是点对点的,这是基于传统C/S模式衍生出来的,这使很多服务在设计时,仅考虑特定的Client情况,也就是说Client和Server对应于需要解决的问题,解决一个问题就需要一对C/S,两者相互依存。

而SOA虽然基于RPC,但它往前走了一步,对整个系统业务进行分析整理后,根据业务逻辑的分工划分出各个服务的定义,分别实现后,组合成一个系统。这就不再是两点之间的连接,而是一个网状架构。理论上,每个服务可以由不同的供应商来实现,也可以被不同供应商提供的组件来调用,这符合汽车行业的大分工原则,即每个部件都可能由不同的供应商来提供。理论上基于SOA的架构,不同的组件都是独立的服务,只要满足服务定义,经过严格测试,组件就可以无缝地集成到系统中。在这个前提下,服务定义的完备性、接口的稳定性、兼容性,都直接影响各个组件是否能无缝集成到系统中,性能和效率的优先级就得往后靠了。

SOA带来的组件化,使基于组件的OTA升级成为可能。这样在理论上,一次汽车的软件升级只需对必要的组件进行升级,既不需要升级整个ECU或域控制器,也无须重启整车系统,就不再需要停车一个多小时来升级了。有了SOA,加上OTA的加持,软件快速迭代就成为可能,因此SOA是软件定义汽车的重要一环。

此外,SOA使得独立第三方软件开发商的进入门槛大大降低。相信很多开车的读者也注意到了,目前中控娱乐系统上虽然用到很多Android的功能,但绝大多数没有应用商店,这点跟手机完全不同。如果哪个手机上没有应用商店,这款手机是卖不出去的。汽车之所以会出现这样的现象,主要是由于汽车软件行业传统的封闭性,导致软件在不同车型上的适配成本居高不下,甚至于同一车厂的不同车型之间的软件都不能通用,这对于第三方软件供应商而言是非常不划算的。

一款应用只能在一两个车型上使用,用户群太分散,不存在推广基础,因此车机上就没有应用商店。而SOA出现以后,部分整车厂已经看到SOA背后的标准化和跨平台的特点,这两个特点让开放平台成为可能,也就使得第三方软件开发商甚至个人开发者进入汽车软件开发领域的门槛大大降低,更有利于构建汽车开发生态。

更多的参与者加入进来,也可以更好地发挥聪明才智,进一步提升用户体验。目前有相当一部分车厂愿意向公众开放自己的SOA服务接口,希望形成开发者社区。但单个车厂的力量是不够的,相信未来会有一些标准化组织来主导这些接口的标准化,形成更大的生态。例如,可能会出现几个大的服务商店和公开标准,可以让车厂、开发者和消费者形成交易圈。这样车厂和开发者才能从中受益,让这个模式运转下去。

当然,这还只是理论上的,实际上想做到这点要复杂得多,技术上还需解决很多实际问题,如SOA固有的性能问题、各个组件之间的耦合程度、某些组件的特殊时序给系统带来的“蝴蝶效应”、部分服务升级期间系统如何正常运行和恢复、升级失败后的回滚机制等。

要解决这些问题,除了汽车业界在SOA的推进中不断完善服务定义,改进架构设计外,也需要SOA本身继续往前走,如进化到微服务架构、去中心化等更完善的服务化架构。当然这也需要更多的技术,如虚拟化、容器化、硬件标准化、网络标准化等的支持。因此,我的判断是:会有更多的云端技术下沉到车端,推进车端系统的演进,要想定义汽车,SOA只是一个开头。

我们的工程实践

前面说了很多概念,对于实际汽车系统的开发究竟有什么影响?我所在的公司是以操作系统技术著称的国内软件企业,我们目前正在开发的智能座舱系统也面临着“软件定义汽车”的冲击,这也直接导致我们的系统架构不得不做一些大的变化。如图3所示为目前基于高通SA8155平台的Android IVI系统架构设计。

图3 基于高通SA8155平台的Android IVI系统架构设计(来源:中科创达)

可以看到,整个系统被分成了三层,分别为BSP(Board Support Package,板级支持包)、Platform和HMI,这是一种按照从硬到软、迭代速度从慢到快进行分层的方式。最下层的硬件和BSP一旦出厂就不太可能更新了,因此这部分属于迭代最慢的,一般整车厂会交给硬件一级供应商去设计开发。

中间平台层是操作系统的主要核心,这部分是目前大部分整车厂都希望把控的核心部分。它的升级类似于手机固件,因为涉及整个系统的性能和稳定性,更新相对保守一些,一般更新周期为1~6个月,常见的是3个月。

最上层是应用,深度影响用户体验的软件大部分集中在这一层,既包括车厂自己开发的软件,也包括集成的第三方软件。按道理,这部分应用更新速度应该是最快的,类似于手机上的应用更新一样,可以做到一日数更。但由于目前车机开发环境的封闭,以及车厂缺少自己的App分发渠道(应用商店等),这些软件的开发和升级还是走FOTA渠道,以跟随系统一起更新为主,更新速度并没有达到预期。这就是目前大部分主机厂推崇的软硬分离模式,希望把软件的核心部分把握在自己手上,而将硬件设计和制造交给硬件供应商去做。

我们现在正在做的事情,就是利用组件化、服务化的方式,将整个系统的软件部分拆分整合,使之更容易快速迭代。例如,我们将平台层的部分核心服务打包成数个微服务,针对这几个微服务,从服务定义、服务实现、服务验证到服务部署形成DevOps闭环,能够支持服务级升级,不需要重启系统(需要OS支持)。如果OTA系统支持部件级升级的话,这些服务就可以在不停机的情况下实现无感更新。

另外,我们在服务接口定义上作了版本和兼容性定义,也使得更新后的兼容性得到一定程度的保护和确认,避免了接口不兼容或数据不兼容导致的问题。另外对于HMI层的一部分应用,我们结合了SOA和云原生的开发理念,在设计时按照云原生的要求,将服务设计为云端可运行的模式,这样应用可以透明地在云和车端的执行引擎上切换,充分利用云和车端的算力和存储能力。

一个具体的案例是场景引擎(见图4)。通过将汽车的各种开放能力定义成各项服务,允许场景引擎可以访问到其他车端服务(感知、地图、车身数据等),并通过SOA使得场景引擎能同时跑在车端和云端,可以实时根据配置向车主下发新的场景配置,来控制相关的车辆行为(如灯光、音乐、语音提示等)。

图4 基于SOA的场景引擎(来源:中科创达)

这里需要特别指出的是,要想快速迭代,除了软件架构的变化,软件开发流程的改革也必不可少。目前很多车厂都在尝试构建敏捷开发流程,来适应“软件定义汽车”的趋势。但受限于整个行业对于“敏捷”的理解水平不够,再加上汽车行业原本的流程限制,很多时候变成了所谓的“大瀑布、小敏捷”这样的夹生饭,或者仅仅是引入Scrum Meeting、Backlog这些概念的“伪敏捷”。而我认为,敏捷的核心是解决从需求到实现再到反馈的延迟问题,就目前汽车系统开发过程而言,主要的瓶颈在于需求、设计、编码、发布和部署的流转时间太长。因此,我们的敏捷转型中心集中在这几个环节的衔接上,采用工具链、架构调整、自动化测试等手段,争取达到单个组件1天内、全系统3天内完成从定义到发布的全迭代过程(目前我们还只能做到单个组件3天、全系统2周的迭代速度,还有不小的改进空间)。

总结

不管怎样,“软件定义汽车”这个概念正在重新定义汽车行业,同时在原本封闭的汽车行业里打开了几扇门,如新的软件架构、操作系统和软件开发方法,这些都意味着新的机会。因此,作为具有超过35年编程经验的资深程序员和汽车行业的从业人员,我衷心希望能有更多人加入到汽车软件这个行列中来,一起为了让汽车更智能、更好玩而努力。

本文摘自《新程序员002》软件定义汽车专题,本期专题从智能汽车软件开发的角度,重点分析端、云一体的汽车软件架构和时空同步的车路协同系统的发展现状和趋势,23位智能汽车行业大咖从软件定义汽车、自动驾驶、数字孪生等不同视角分析了云计算、人工智能、物联网等技术给汽车行业带来的影响和机会。

与智能汽车相见恨晚的SOA到底是什么?相关推荐

  1. 智能汽车专题报告之软件篇:迈向SOA软件架构

    智能汽车专题报告之软件篇:迈向SOA软件架构 参考链接:https://baijiahao.baidu.com/s?id=1699880894352710555&wfr=spider& ...

  2. 站上智能汽车产业高地,合肥到底是“赌”来的,还是另有蹊径?

    图片来自网络 [编者按]谁都知道,智能汽车是通向未来产业高地的必经之路,无数人为之疯狂. 对于这场有关未来的竞争,我们可以将其一分为二,微观上是市场层面,各个企业公司之间的竞争:宏观上是产业层面,各个 ...

  3. 软件定义汽车时代下,智能汽车软件架构逐步向 SOA 演进

    软件将成为智能汽车差异化的核心,汽车软件架构逐步向 SOA 演进.而相较于传统汽车,智能汽车能为车主创造丰富的.可感知的价值以及全新的驾驶体验,这是当前不同汽车形成差异化的关键,而软件则是汽车智能化的 ...

  4. 安卓如何调出软键盘_智能汽车到底如何交互?小鹏用全场景语音给出了答案

    车东西(公众号:chedongxi) 文 | 晓寒 智能汽车大潮汹涌而来. 新上市的车型,车内屏幕越来越大也越来越多.在特斯拉的带动下,中控台上的实体按键在最近几年迅速"被绞杀". ...

  5. 下一代汽车的核心竞争力到底是什么?

    来源:深城物联 全球芯片短缺的情势下,汽车芯片的关注度持续走高.除了硬件外,最近,业内对于车辆软件系统的讨论也越来越热烈.华为近日发布了首款智能电动车极狐阿尔法S,HI版本上首次搭载了自研鸿蒙OS智能 ...

  6. 关于第十六届全国大学生智能汽车竞赛总决赛的规则建议

    简 介: 本文收录了全国大学生智能车竞赛浙江赛区组委会对2021年第十六届全国大学智能车竞赛全国总决赛线上比赛建议. 关键词: 智能车竞赛,总决赛,线上比赛,建议 全国组委会:   因疫情影响,第十六 ...

  7. 10万,买一辆自驾无忧的智能汽车

    贾浩楠 允中 发自 凹非寺  量子位 报道 | 公众号 QbitAI "我看着你们,满怀羡慕." 这是2020刷屏宣传片<后浪>中,最令人印象深刻的台词. 其中说道,知 ...

  8. 巅峰对话:畅想大数据时代的车联网与智能汽车

    ZD至顶网CIO与应用频道 01月20日 北京消息:2016年1月20日,数据猿作为独家全程直播与专访媒体,受邀参加"全球大数据峰会 Global Big Data Conference 简 ...

  9. 未来我们需要一辆什么样的智能汽车?

    "从130年前发明传统汽车以来,动力增加了130倍,但汽车交通安全事故的问题一直没有解决.2007年1月9日第一台苹果手机的发布,重新定义手机为智能化通讯技术工具,现在要重新定义汽车的时代了 ...

最新文章

  1. 关于 href=javascript:; 到底做了什么
  2. 钣金缺口lisp_UG用钣金模块的放样创建天圆地方,还能学钣金展开,必看
  3. git - 基础 - 01 - git reset --hard 回滚以后,看不到之前的分支版本怎么解决:
  4. vue项目实践教程2:使用vux设计登录注册,并讲解vue路由,切换页面标题等内容
  5. Java 使用Collections.reverse对list集合进行降序排序
  6. hive 直接访问mysql_hive 直接插入mysql
  7. 伦敦大学学院计算机残疾,伦敦大学学院残疾、设计和创新理学硕士
  8. Python 算法交易实验30 退而结网7-交易策略思考
  9. Activiti6常见错误汇总
  10. kali安装QQ音乐
  11. 大厂面试为什么总考算法?如何避开算法面试?
  12. JQuery 如何使用插件如何安装插件(详细讲解)
  13. python获取小数部分
  14. 路由控制配置 peer as- number命令解析
  15. go 学习笔记之咬文嚼字带你弄清楚 defer 延迟函数
  16. alanwang[GDOU] 直接插入排序法简单演示
  17. 看雪CTF.TSRC 2018 团队赛 第二题 半加器 writeup
  18. 地理信息系统(Geographic Information System或 Geo-Information system,GIS)
  19. linux里sh命令是做什么的?详解!
  20. 简单模拟鼠标键盘操作

热门文章

  1. Windows平台录音类封装:AudioRecordWindows
  2. 在windows下使用docker做本机linux环境系统测试
  3. 图像的基本运算——scale, rotation, translation
  4. 艾宾浩斯曲线真的管用吗?
  5. 计算机网络习题:第三单元
  6. cad.net 利用win32api实现不重复打开dwg路径的文件夹(资源管理器)
  7. php 极光定时推送消息,极光短信- 短信定时发送 API - 极光文档
  8. electron-rebuild 编译遇到的奇葩问题
  9. Redis单线程和多线程
  10. 扎克伯格----转自Jessica巨人