激光雷达与域控制器在自动驾驶中的关键角色
自动驾驶激光雷达与域控制器
参考文献链接
https://mp.weixin.qq.com/s/aY4ZPNBMjfQIklq2foWzyw
https://mp.weixin.qq.com/s/DDJdr9JR67HzfOp05USDQA
https://mp.weixin.qq.com/s/3kffmLpuHdMMKOXRYhrgQQ
激光雷达技术及核心元器件
从四个维度深度剖析激光雷达核心技术
激光雷达(LiDAR)的产业化热潮来源于自动驾驶汽车的强烈需求。在美国汽车工程师学会(SAE)定义的L3级及以上的自动驾驶汽车之中,作为3D视觉传感器的激光雷达彰显了其重要地位,为自动驾驶的安全性提供了有力保障。因此,激光雷达成为了产业界和资本界追逐的“宠儿”,投资和并购消息层出不穷。很多老牌整车厂和互联网巨头都展开了车载激光雷达的“军备竞赛”。近期,MEMS激光雷达技术发展最为活跃,并且吸引了大多数投资,同时宝马宣布将于2021年推出集成MEMS激光雷达的自动驾驶汽车。
不同自动驾驶等级对传感器的需求分析
(数据来源:Yole)
伴随着自动驾驶热度上升,激光雷达相关新闻铺天盖地袭来。但是这项在自动驾驶领域尚不成熟的3D视觉技术,不仅公开技术资料稀缺,而且企业和媒体关于各种激光雷达的分类和称谓表达五花八门,例如:机械式、固态、全固态、混合固态;又如:MEMS(微机电系统)、OPA(光学相控阵)、Flash(闪光);亦如:FMCW(调频连续波)、脉冲波;还如:飞行时间法、三角测距法等。这些称谓常常让圈内圈外的人士感到困惑。不用担心,麦姆斯咨询为答疑解惑,本报告从“测距原理、光源、光束操纵、探测器”四个维度对激光雷达核心技术及分类进行了分析,力求让读者对激光雷达错综复杂的技术脉络有清晰的认知。
当在交流“直接/间接飞行时间法、三角测距法”等概念时,这实际上是激光雷达的“测距原理”维度;而谈及“机械式、MEMS、OPA、Flash”等关键词时,这属于激光雷达的“光束操纵”维度;无论是905nm还是1550nm的波长,还是边发射激光器(EEL)或垂直腔面发射激光器(VCESL),这是从激光雷达的“光源”维度交流问题;而涉及PIN、APD(雪崩光电二极管)/SPAD(单光子雪崩二极管)、SiPM(硅光电培增管),或是单点、线阵、面阵,则是从激光雷达的“探测器”维度分析技术。
掌握不同类型激光雷达技术路线及“硬核”
按照光束操纵方式分类,激光雷达主要分为机械式激光雷达、MEMS激光雷达、OPA激光雷达和Flash激光雷达。观察目前产业发展情况,MEMS和Flash技术更受到激光雷达厂商的青睐,有望逐步取代机械式激光雷达。本报告详细分析了上述四种激光雷达的工作原理、优劣势;并对各种激光雷达技术的“硬核”——核心元器件的原理、工艺难度和主要供应商进行了深度剖析,包括MEMS微镜、OPA芯片、ToF(飞行时间)图像传感器、激光器(EEL/VCSEL)、光电探测器(APD/SPAD/SiPM)等;最后还梳理了各种激光雷达的国内外典型厂商。
MEMS微镜作为MEMS激光雷达的核心元器件,毫米级尺寸大大减少了激光雷达的体积,帮助系统摆脱了笨重的马达等机械式装置;同时,MEMS微镜的引入大大减少激光器和探测器数量,极大地降低整体成本;在投影显示领域商用化应用多年的经历及近期在汽车领域的努力,让业界对MEMS微镜的成熟度更为认可。但是,MEMS微镜尺寸的缩小又限制了MEMS激光雷达的光学口径、扫描角度,视场角也会变小;如何通过车规也是MEMS微镜面临的巨大挑战。
OPA激光雷达无需任何机械部件就可以实现对光束的操纵,曾一度被业界看好。但核心元器件——OPA芯片的纳米加工难度非常高。以Quanergy为代表的OPA激光雷达厂商不断修正其产品的量产时间和最远测距范围。那么OPA芯片的实现方式有哪些?面临哪些方面的问题?将在本报告中找到答案。
Flash激光雷达被视为最终的主流技术路线。Flash激光雷达技术利用激光器同时照亮整个场景,如何提高接收端每个像素可接收的能量,从而实现远距离探测,这对线阵/面阵探测器技术提出了极高要求。本报告对线性雪崩二极管(LMAPD)阵列、盖革模式雪崩二极管(GMAPD)阵列、硅光电倍增管(SiPM)、ToF图像传感器等阵列探测器的工作原理、关键参数进行了详细分析,并梳理了国内外相关厂商信息。
FMCW激光雷达另辟蹊径:测距又测速
调频连续波(FMCW)激光雷达采用基于光源频率调制的间接飞行时间法,通过比较任意时刻反射信号频率与此时刻发射信号频率的之差方法来得到目标的距离信息。该激光雷达类型与上述四种激光雷达(按照光束操纵方式分类)不一样,是从光源波形角度进行分类的。FMCW激光雷达的光源信号调制主要包括三角波调制、锯齿波调制、正弦波调制等方式。由于正弦波调制检测物体时需要调节信号频偏,大多应用于只有一个探测目标的情况,比如高度计。如果希望FMCW激光雷达检测多个目标的距离和速度等信息,通常采用三角波调制。
FMCW激光雷达的光源信号采用三角波调制时,通过测量fB1和fB2就可确定与反射目标的距离及其径向速度
FMCW激光雷达采用相干测量技术。相干测量又称光外差探测。激光器发出的光经分束器后分为两束,一束作为本振光,另一束在调制后经光学系统照射到目标物体上,反射回来的光(信号光),与本振光在光电探测器上混频。相干测量具有转换增益高、获得光信号全部信息(振幅、频率、相位)、对背景光滤波性能高、可探测微弱信号等优势。在相干测量中,为了获得最佳的信噪比,需要足够高的本振光功率,这对激光器的要求非常高,平衡光电探测器也不可或缺。平衡光电探测器利用在同一探测系统中放置两组探测器件,分别将本振光和信号光输入到光电二极管中,将光信号转化为电信号,然后经过减法器运算,输出外差信号。通过本报告,会对FMCW激光雷达技术及核心元器件(平衡光电探测器)有更深入的认识。
报告目录:
‐ 缩写列表
‐ 自动驾驶概述
‐ 激光雷达综述
* 定义
* 发展历史
* 产业链
* 四个维度
* 测距原理
* 光束操纵
* 光源
* 探测器
* 主要指标
‐ 机械式激光雷达技术及应用
* 工作原理
* 优劣势分析
* 难点分析
* 主要国际厂商
* 主要国内厂商
‐ MEMS激光雷达技术及应用
* 工作原理
* 优劣势分析
* 实现和构成
* 核心元器件:MEMS微振镜
* 主要国际厂商
* 主要国内厂商
‐ OPA激光雷达技术及应用
* 工作原理
* 优劣势分析
* 核心元器件:OPA芯片
* 主要国际厂商
* 主要国内厂商
‐ Flash激光雷达技术及应用
* 工作原理
* 优劣势分析
* 核心元器件:激光器
* 核心元器件:探测器
* 主要国际厂商
* 主要国内厂商
‐ FMCW激光雷达技术及应用
* 工作原理
* 优劣势分析
* 核心元器件:平衡光电探测器
* 主要国际厂商
* 主要国内厂商
MEMS激光雷达
三菱电机(Mitsubishi Electric)新款MEMS激光雷达(LiDAR)可以准确探测车辆和行人,确保安全可靠的自动驾驶。
据麦姆斯咨询报道,日本三菱电机近日宣布开发出一款紧凑型MEMS激光雷达(LiDAR)解决方案,能够实现超宽的水平扫描视场,准确探测自动驾驶系统前方物体的形状和距离。这款激光雷达解决方案使用双轴(水平和垂直)MEMS微镜向物体发射激光束,并扫描反射光,从而生成车辆和行人的3D图像。三菱电机希望利用这款紧凑型低成本激光雷达解决方案推动更安全的自动驾驶。
关键特性
1)大尺寸双轴电磁MEMS扫描微镜,独特的轻巧设计使扫描角度更广
激光雷达在发射激光束之后,需要尽可能多地收集反射光,以便获取最精确的3D图像,尤其是车辆和行人的3D图像。因此,激光雷达系统需要大表面积的反射镜,以最大程度地收集反射光。另外,精确监控车辆周围更广泛的区域,也需要更大的扫描角度。
三菱电机这款新产品在轻巧的设计中集成了业界最大尺寸的电磁式MEMS扫描微镜(尺寸为7mm x 5mm),能够实现水平和垂直双轴扫描。除了尺寸优势,这款MEMS微镜的独特结构有助于其在不牺牲器件刚性的前提下减轻重量。凭借轻巧的设计和高电磁产生的驱动力,可以使扫瞄镜实现水平±15度的大范围运动。当前的垂直扫描范围为±3.4度,三菱电机计划通过改善MEMS悬梁结构将其提高到±6.0度以上。其MEMS微镜可以采用半导体工艺在硅基板上大批量生产。此外,与采用电机进行机械驱动扫描的反射镜相比,MEMS微镜使用的零件更少,有助于提高激光雷达整体解决方案的耐久性。
2)优化的设计缩小了产品尺寸,并能够在更宽广的范围内获取3D图像
三菱电机优化了电磁MEMS扫描微镜和光学组件(包括多个激光光源、光电探测器和透镜)的排布,以抑制光学暗角,以及内部组件对激光束的影响。
优化的设计和光学发射/接收机制可实现超宽的水平扫描角度,从而增强了对前方来车、过马路的行人、交通信号灯、交通标志和路边障碍物的扫描能力。随着进一步的改进,三菱电机的目标是使垂直扫描角度超过25度,从而即使在近处也能检测到车辆和行人。
得益于信号处理电路、电源电路和光发送/接收机制的优化布局,这款激光雷达主体的体积仅为900立方厘米。展望未来,三菱电机的目标是开发体积仅为350立方厘米或更小的超微激光雷达设备。
自研域控制器
前段时间九章智驾发布的《“放弃自研域控制器”,缘何成为一些L4级自动驾驶公司的共同选择?》引起了行业的广泛讨论。其中,有一些人并不认同此文的核心观点,认为,是否自研域控制器与公司定位有关,确有许多算法公司不打算做硬件,“但如果定位做行业领导者,为了优化用户体验和更快地商业化落地,当然要做硬件”。
其实,就在前段时间,小马智行发布了其自研的域控制器,并可提供给商用车客户和乘用车客户前装量产使用。
与一些L4自动驾驶公司进军前装乘用车量产时选择聚焦做算法和软件不同,小马是第一家选择从自研域控制器入手的L4公司。
虽然做前装量产的算法和软件也有工程问题要解决,但相较于软件,硬件开发和生产则更依赖过往的量产工程经验,而这也是一些国际Tier 1和一直聚焦做前装量产的域控公司的“主场”优势所在。一家L4自动驾驶公司,公然“挑战”这些公司的“主场优势”,提出要做前装量产域控制器,也让很多行业内人士疑惑和不解。
因为在进入域控制器市场时,将面对的是德赛西威、经纬恒润、福瑞泰克这些量产工程经验丰富的玩家。
在当今大环境下,多数初创公司都“轻装上阵”,为什么小马智行会选择进入域控制器这么“重资产”的行业?面对域控制器市场上的既有玩家,小马智行将如何克服工程能力的短板,又需要具备什么样的优势,才能在激烈竞争中占有一席之地?
带着这些疑惑,九章智驾和小马智行的相关专家进行了深度交流,整理出下文,以飨读者。
一、小马为什么要自研域控制器?
之所以会选择做“自研域控制器”这么“重”的事情,和公司的定位有关:如果公司定位是做自动驾驶算法和软件,自然会本能地回避这些事情;但如果公司定位成为自动驾驶整体解决方案提供商,为了让自动驾驶更快地商业化落地,那么,做一些硬件开发也就顺理成章。
小马智行上海研发中心规划与控制负责人Y介绍说:“虽然小马智行给外界的印象是偏软件和算法的公司,但其实从一开始,小马智行就坚持软硬一体,坚持部分核心硬件自研,无论是做Robotaxi还是做面向规模量产的产品,都是软硬件同步研发。因为始终认为,软件需要硬件的配合才能更好地发挥作用。”
域控制器并不是小马智行唯一自研的硬件。据了解,之前小马智行就自研了红绿灯识别摄像头和定位系统硬件NBOX,也针对性地做了可靠性验证。
“软硬件紧密结合、互相配合,才能达到最理想的状态。”该负责人Y表示。
在算力平台上也是如此。
目前国内公司要想使用Orin X,除了几家自研域控的新*车企外,其他玩家大多都依赖英伟达在国内的授权合作方。
在和业内专家交流时得知,英伟达的国内授权合作方,在设计域控制器时,一般都会按照英伟达给的参考设计,很少做修改。
究其原因,一方面,要在参考设计的基础上做针对性的优化设计,需要对软件有深刻的理解,而这些授权合作方是缺少这方面know-how的;另一方面,也怕改了之后,万一出问题没有人可以“背锅”。而按照参考设计去做,即使出问题,也可以推脱为是英伟达参考设计的问题。
据小马智行电子电气架构负责人C介绍:“小马智行有超过1400万公里自动驾驶的里程数据,对智能驾驶的理解非常深,经历过几次计算平台的硬件迭代后,归纳总结出域控制器应该怎么设计,也清楚如何优化才能更好地适配智能驾驶软件。所以小马智行自研的域控制器,无论是从性能、安全、成本还是体积上,都更适合智能驾驶应用场景。”
“在小马智行看来,英伟达提供的Orin X的参考设计,其实还是有不少可以优化的地方。小马智行有针对性地做了大量删减,一方面能够减少一些元器件的数量,降低物料成本,另一方面,减少元器件对降低功耗也有好处。”
“除了基于参考设计做删减外,更重要的是,小马智行也发现参考设计并不能完全满足智能驾驶的功能需求,还需要做一些额外软硬件设计来完善其性能。例如,从智能驾驶的需求角度出发,需要对每一路摄像头进行独立控制,包括曝光时间、帧率等。一方面可以避免时间戳插值查找引入的误差,在激光雷达进行采样的时候,触发器同时触发摄像头进行曝光,从硬件上实现时间同步的效果;另一方面独立控制每路相机可以避免不必要的大量数据同时涌入,也可以根据场景调整帧率,最终达到平衡算力需求和降低带宽压力的效果。”
“这只是诸多设计优化的一个例子,更为重要的是,以上所有的这些删减和优化,均得到了英伟达总部工程团队的认可。”
二、相比其他域控厂商,小马自研域控制器的优势
随着L2+/L2++等功能成为近期前装量产功能的攻坚重点和市场热点,尤其是城区NOA等即将推向前装量产,由于城区NOA和Robotaxi的场景相似性,在该场景下有深厚的经验和算法积累的L4公司就展现出了优势。
2016年成立的小马智行,其L4算法已经打磨了五六年,硬件也从最开始的跑Demo时用的工控机,演进到最新发布搭载英伟达Orin X的ADC (Autonomous driving controller)。
为了更好地实现自动驾驶,小马智行不仅自研了自动驾驶算法,也全栈自研了底软、中间件和自动驾驶开发工具链。在数据、算法和算力平台的不断迭代中,对场景、算法、算力的理解也不断演进。
和其他域控厂商相比,这些全栈自研软硬件的积累,让小马智行在设计域控架构时,变得更有底气。
2.1
自研中间件
中间件是应用层算法和硬件底软的“隔离层”,其很大程度上影响了软硬件系统的稳定性和效率。对中间件的深刻理解,有助于更好地优化软硬件设计,对于自研域控制器也有助力。
在中间件领域,与一些L4自动驾驶公司使用ROS或Cyber RT,或者像一些车企一样使用DDS不同,小马智行从一开始就自研中间件,小马智行电子电气架构负责人C说:“因为很了解ROS存在的问题。所以从L4自动驾驶需求出发,像特斯拉一样,基于Linux做了很多裁剪,开发出了自己的中间件,也自研了消息通信系统和机制,从而可实现类似于DDS那样的保证通信实时性等功能,使其可以满足自动驾驶量产的需求。”
“除了能满足通信需求外,在任务调度方面,自研的中间件也可以更加匹配自动驾驶的需求。”
在2022年3月的GTC Digital Spring活动中,小马智行的工程师分享中提到,为了提高传感器数据处理流水线的效率和可靠性,做了很多的软硬件的优化。
其中提到了在数据传输过程中,为了减少CPU和GPU的无效消耗,经过了数次软硬件迭代后,小马智行使用发布-订阅模式,通过模块间的零拷贝消息传递来共享信息。下图为数据量最大的摄像头数据,被下游的许多模块使用进行深度学习推理的链路。
小马智行支持 GPU 的零拷贝发布-订阅信息传递,摘自2022 GTC Digital Spring
据C介绍,要提升实时性,仅仅优化中间件是不够的,小马智行和英伟达一起在Linux的内核层(Kernel)做了大量的优化开发,从而可以把实时性做得更好。下图中为2022 GTC Digital Spring中英伟达的工程师和小马智行一起做的实时性优化的成果,其中蓝色方框部分为小马智行的贡献。
英伟达和小马智行为提升实时性做的共同开发,摘自2022 GTC Digital Spring
2.2
更深的算法积累
对算法和硬件更好的理解,能够有助于提升对算力的利用率,反过来,对算法有更深的理解和积累,同样也能有助于设计出能更好地匹配算法的域控制器。
虽然城区NOA和Robotaxi的场景很相似,但是技术架构是否相同呢?视觉感知能力的积累是否足够呢?这些问题的回答,直接影响了L4公司对算法的理解和积累,能否复用到面向前装量产的域控制器设计上。
2.2.1
技术架构
技术架构分软件架构和硬件架构。
L4的软件技术架构,可以直接应用在城区NOA这样的高阶智能驾驶上吗?
对于这个问题,小马智行给的答案是——可以。
小马智行上海研发中心规划控制负责人Y介绍说:“Robotaxi和城区NOA的场景很相似,几乎不需要太多的适配,软件技术架构是一样的,甚至很多代码都可以直接复用。”
“从成立开始,小马智行做的研发,积累的知识、数据、代码、算法等,其实很大程度上都可以直接在量产项目上复用。相当于为了准备这个量产项目,小马智行已经有了5年的积累,这也是小马智行的竞争力所在。”
在硬件技术架构上,L4公司的方案和前装量产的方案也逐渐趋同,都用上了大算力SoC,也都装上了半固态激光雷达。
小马智行近期公布了其最新的前装量产传感器方案:只装了一颗前向长距离半固态激光雷达,更多用于提升前向的感知召回率与安全性。在定位和感知模块更多依赖摄像头与毫米波雷达融合,不依赖激光雷达,甚至小马智行也可以提供基于纯视觉的前装量产方案。
小马智行量产传感器方案布局
此外,相比于传统的独立的P-box分布式架构,小马智行也可以提供集成GNSS和IMU的域控设计方案,向*式电子电气架构更进一步,一方面节省了独立的计算单元的成本,另一方面也减少了自动驾驶域控通信接口和线束的复杂度。考虑到适配整车架构的多样性,集成定位传感器的方案可以按需选配。
2.2.2
视觉感知能力的积累
有些人认为,与前装量产以视觉作为主传感器不同,一些L4公司的算法架构还是以激光雷达为主传感器,在视觉感知能力上的积累不如某些前装量产公司,在进入前装量产时可能会不适应。
不过小马智行虽然是L4公司,视觉方面的积累也很深厚。
据小马智行的资深感知工程师Z介绍说:“小马智行一直很重视视觉,在最近特别火的BEV(Bird’s Eye View,鸟瞰图)领域,也有很多的尝试和探索。BEV帮助解决了很多问题,尤其是BEV在跨摄像头融合的优秀表现,能很好地解决近距离cut-in场景,也能大幅提升在高速上被不同的摄像头截断的大车的感知准确率。”
在BEV空间转换时,划分网格需要权衡大小、远近目标。“在BEV网格划分时,小马智行设置了比较近的感知距离,因为认为,更重要的还是近处场景,比如cut-in、拥堵路况、高速上下匝道等。远处的场景,即使稍微有偏差,也不会有很大风险,所以设置了60米的探测距离,在高速上也起到了很好的效果。”
在BEV网络的训练和优化方面,Z介绍道,“由于L4和前装量产的摄像头布局类似,所以很多L4的数据可以直接复用。”
“在训练BEV网络时,与业内一些公司使用云端大模型对视觉数据进行3D重建来生成真值的做法不同,因为有大量带激光雷达点云的真实路测数据,点云感知模型非常成熟,可以直接输出动态目标物的大小、形状、位置、朝向、速度等结果,高精地图里也有车道线、路沿等静态目标物信息,所以直接拿点云感知模型生成的输出结果和高精地图里的静态信息作为真值,来训练BEV模型。由于用于训练的真值的精度高,BEV感知模型的精度自然也就比较高。”
“再通过数据挖掘,对Corner Case持续训练迭代,不断提升BEV模型的泛化能力。”
“当然,训练完之后,BEV模型还要做一些不影响感知精度的量化、剪枝等降低模型复杂度的处理,才能部署到车端。”
小马智行感知网络架构
BEV网络可以“脑补”出被遮挡区域的目标,对于这部分“脑补”出的输出结果,不同公司的处理方式也有不同,Z介绍说:“首先,会在感知端将被遮挡区域标示出来,输出给到下游的规控模块,让规控模块判断是否需要针对遮挡区域出现的一些意外情况(如鬼探头等)进行提前应对(如提前减速、绕行等);另一方面,对BEV‘脑补’出的被遮挡区域的动态目标物,会一直保持跟踪(Tracking),并视置信度高低来决定是否将跟踪的结果告知下游的规控模块,从而让规控模块可以提前做准备。”
此外,据Z介绍,小马智行也在尝试“伪激光雷达”,即通过点云数据作为真值,训练神经网络,利用图像生成稠密点云,也被称为“视觉雷达”。伪激光雷达的作用,一方面,能够解决对道路上那些尚未被纳入模型库的异形物体的检测能力,以提升安全性;另一方面,对于没有安装激光雷达的前装量产车辆,伪激光雷达生成的点云数据可以作为真值,来迭代车端的BEV网络。
另外,小马智行已经开始尝试将BEV的应用范围拓展到定位模块,如用BEV输出的车道线和地标箭头等去匹配高精度地图的相应元素,来对车端做一些横纵向的位置纠正。
2.3
更多高质量数据
众所周知,自动驾驶是由数据驱动的。而数据来自于场景,可以这么说,数据直接决定了对自动驾驶场景理解的深刻程度。对场景的深刻理解,也有助于设计更适合自动驾驶场景的域控制器。
至今为止,小马智行已经在北京亦庄、广州南沙、上海等多地开展路测和Robotaxi的运行,累计积累了1400万公里的路测数据,其中有20万公里是无人化测试里程。
真正对自动驾驶有价值的数据,不仅数量要足够多,质量也要足够高。
高质量的数据,一方面指的是高精度的数据,即数据要包括激光雷达点云、图像等数据,尤其是点云数据,可以为摄像头数据提供高精度的训练真值;另一方面指的是场景要多元化,自动驾驶系统能够遇到更多的Corner Case。在这两方面,相比于大多数做前装量产的域控制器厂商,小马智行有明显优势。
在高数据质量方面,小马智行的路测车辆均配置激光雷达,可以提供高精度的点云。
在场景多元化方面,据小马智行上海研发中心规划控制负责人Y介绍:“首先,依赖于Robotaxi和干线卡车这两个产品,小马智行1400万的测试里程中,覆盖了城区和高速公路两大场景。
“其次,小马智行的测试场景既覆盖了北上广深一线城市,也包括了一些二线城市。在不同的城市多地路测,能覆盖因地域和文化不同,引起地不同的Corner Case,来提升自动驾驶系统的泛化能力。小马智行之前曾分析发现,不同城市的司机,驾驶习惯也是有明显差别的,如果没路测过是不了解这个情况的。而其他做前装量产的域控厂商,数据往往局限于高速场景,城区场景的数据相对较少。”
如下为小马智行前段时间公布的一镜到底的路测视频,视频中展现了搭载小马智行最新单Orin X 254 Tops算力的域控制器系统以及搭载量产传感器及软件的车辆,经过高速路和城区道路的表现。
2.4
高效的数据闭环工具链
要想真正实现自动驾驶,不仅需要大量的高质量数据,更重要的是把这些数据利用起来,即需要有高效的数据闭环工具链。
只有足够高效的工具链,才能高效地迭代算法。而只有迭代出最新的算法,才能了解最新的算法对域控制器的需求,才能设计出最适合最新算法的域控制器。
自动驾驶能力 = 自动驾驶数据 x 数据闭环效率
为了更好地进行算法迭代,小马智行也全栈自研了数据闭环工具链。很多L4公司都是全栈自研的,小马智行也不例外,在这方面,比某些量产经验丰富的Tier 1要更有优势。
据介绍,如果客户有需求,小马可以将工具链跟算法模块打包交付。
下面为笔者根据与小马智行数据闭环工具链工程师W的沟通,整理的小马智行数据闭环工具链的特点。
小马智行数据闭环工具链特点
2.5
灵活的合作方式
小马智行全栈自研的域控+底软+中间件+算法+工具链,相对于其他域控厂商而言,具有什么优势呢?
小马智行EE架构负责人C说:“如果要兼容其他家的模块,如第三方中间件等,除了相应地适配成本外,还可能因为适配的第三方中间件在某些技术上能力不足,在最终性能表现上会打一些折扣。”
“但是如果客户全部采用自研模块的话,这些模块已经过充分验证,一方面,软硬件适配成本会比较低,另一方面,性能天花板更高,小马智行L4的算法,依托自研的各个模块,经过充分验证展现了出色的性能。”
不过,虽然小马智行软硬件全栈自研,客户全盘采用也有很多优势,但这并不代表小马智行只支持“捆绑式”的合作,事实上,小马智行对合作方式是非常开放,也非常灵活的。
据介绍,小马智行全栈自研的内部模块化程度也是非常高的,可以实现软硬件解耦,包括中间件,甚至算法各模块之间也一定程度是解耦的。在此基础上,小马智行既支持某几部分打包在一起提供,也支持其中某一部分单独对外提供(如中间件或域控+底软)。
小马智行对外合作方式不仅开放,也很灵活。现在有很多车企软硬件分拆定点,单独选定芯片类型、指定某第三方公司作为中间件供应商,甚至还有将算法模块分拆定点等现象,当被问及这种情况下小马智行是否可以支持适配时,小马智行EE架构负责人C表示,对于客户的定制化需求,小马智行也是全力配合的。如果选定芯片不是Orin X,小马智行可以支持对算法迁移;如果已经选定中间件供应商,小马智行也可以支持适配;也可以单独将某个算法模块提供并与上下游适配。如果客户要求中间件要符合AutoSAR,小马智行也可以支持基于AutoSAR 开发中间件。
此外,不同于一些传统Tier 1在底层软件上依赖第三方基础软件供应商而造成灵活度较低,小马方面称,在底软软件上自研且完全掌控,如果客户有一些特殊需求,如在信息安全上有定制化需求,小马智行可以很灵活地进行支持。
“虽然知道软硬件集成一起交付的话,能达到的水平会更高,只交付某一部分并和其他合作伙伴‘拼接’交付,性能上会很不一样。但是理解客户对供应链安全等方面的考虑,会有分拆定点的需求,也愿意积极配合。总之,合作方式非常灵活。”C说道。
三、回应外界的质疑
3.1
如何解决工程问题
就像文章开头提到的,做前装量产的硬件,需要深厚的工程能力的积累,而这也正是以算法能力见长的L4公司的短板。
小马智行将如何应对这个挑战呢?
小马智行EE架构负责人C介绍说:“其实小马智行也积累了不少工程能力,为了能够真正地实现自动驾驶,小马智行从一开始就坚持两个理念:”
“第一,不盲目堆算力。一开始改装Robotaxi的时候,虽然小马智行也用工控机,但是相比于友商工控机的配置,配置要低得多,因为知道,算力即成本,而成本对自动驾驶量产是至关重要的。”
“第二,高集成度。在改装Robotaxi的时候,不同于友商把后备箱全部堆满,把工控机做得足够小,小到可以放在后备箱下面原先放备胎的位置,而可以不占用正常后备箱放行李的空间,这一点也比友商做得要好。”
“为了坚持这两个理念,小马智行花了很多努力,解决如何降低算力、提高集成度这些工程难题,在这个过程也积累了不少工程能力。”
“也正因为不盲目堆算力,再加上积累的工程能力,当小马智行从X86架构的工控机迁移到Orin X嵌入式平台时,上层的一些算法,可以很大程度上复用,甚至许多代码都是不变的。”
在迁移过程中,其实也遇到了很多问题,需要从软硬件各个层面一起解决。
据C介绍:“当初刚进行代码迁移时,一开始运行,结果时延一下提升了五六倍。为了降低时延,只能在应用层算法、中间件和底层软件这几方面分别做优化。”
“既然能从X86架构成功迁移到Orin X上,如果客户有适配其他算力平台的需求,小马智行也可以从容应对。”
进入前装量产阶段,功耗、成本、功能安全和可靠性是域控制器厂商们绕不开的几大问题。对于一个新入局的玩家,要想站得住脚,就更不能在这几个客户最关心的指标上有“短板”。
这里面每一个问题,都像时延问题一样,只有更好地了解自动驾驶使用场景,更深刻地理解自动驾驶软硬件系统,软硬件协同,才能更好地解决。
3.1.1
优化功耗
关于功耗,C介绍说:“功耗是系统性的,既包括芯片的功耗,也包括周边外设和电路的功耗。先说外设电路,根据一直以来积累的对自动驾驶软硬件的深刻理解,基于英伟达的参考设计做了大量的优化,删减了很多不必要的设计——这些器件的减少是能够带来不少功耗降低的,加起来有十几瓦甚至几十瓦了。”
“再说Orin X的功耗,可以分为静态功耗和动态功耗。静态功耗是由芯片本身是参数决定的,改变不了;但动态功耗是可以有很多优化空间的。”
“动态功耗的几个决定因素为电压、频率和负载率,要想降低动态功耗,要么降电压、要么降负载率、要么 降频率。对于车规级产品,电压一般不会降低,小马智行和英伟达一起在降低频率和负载率上面下了很多功夫。”
“在降低负载率方面,比如说实现某个功能的算法,本来要用掉90%的GPU算力,通过一些配置和软硬件共同优化,可以只占用50% GPU就可以了,从而可以降低负载率。”
“在降低频率方面,像Orin X这样的大算力SoC,有12核ARM CPU,当算力需求不大时,可以让这些核的运行频率下降或者直接让其休眠,从而可以大幅降低功耗。在一些极端工况如哨兵模式下,只需要开启相关摄像头,最多把周边环境拍下来传给用户的手机端,不需要让Orin X的性能全部发挥出来,只需要在较低计算资源下,让更其能满足功能需求即可,这就需要小马智行和英伟达一起共同努力,通过优化频率频率,从而降低其动态功耗。”
3.1.3
功能安全
功能安全也是车企们非常重视的,那么在域控上,小马智行能达到什么功能安全等级呢?
C介绍道:“Orin X的功能安全等级一般可以做到ASIL B,也可以做成QM。单纯芯片层级是不能满足自动驾驶的功能安全等级的,所以一般在系统上,会基于ASIL B的Orin X,配置满足ASIL D的MCU,从而可以使整个域控系统最高达到ASIL D的功能安全等级。”
“这个MCU会负责Orin X上系统的监控诊断和报警,并具备功能冗余,即当主系统软硬件故障时,MCU可以进入最小安全风险条件,运行感知、定位、规划控制的算法,实现车道线内无碰撞停车。”
“最终系统功能安全等级,还是取决于客户的实际需求。如果整车电子电气架构中已经有了冗余控制器或其他冗余方案,或者对功能安全等级要求不高而对成本比较敏感,小马智行也可以基于Orin X和ASIL D的MCU,实现ASIL B域控系统级功能安全等级;对于双Orin X版本,小马智行还在参考设计的基础上做了大幅优化,以2 x Orin X+ 1 x MCU 的方案实现ASIL B的系统级功能安全,且该方案也得到了英伟达官方的许可。省掉的MCU既可以降低设计的复杂度,也能够减少系统体积和成本,尤其在当下缺芯的大背景下,一些MCU动辄几十倍的价格涨幅才能拿到现货,省掉一个MCU,对上游的供应链管理无疑是大有好处的。”
据介绍,小马智行已经通过了功能安全的专家评审,过段时间就能拿到ISO26262的功能安全认证,也正在准备ISO 21434道路车辆网络安全管理体系的认证工作。
3.1.4
可靠性
当说到车规级的时候,尤其是电子系统,其实指的是,电子元器件能够满足AEC-Q100系列的认证,而零件总成和系统试验认证,各家车企针对不同位置、不同功能的试验标准和要求也是不一样的。
那么,小马智行的域控制器到底通过了哪些测试验证呢?
C表示,所选的电子器件都要通过AEC-Q100系列的试验,这些非系统级的元器件由芯片厂商提供或由代工厂负责完成,小马智行更多负责一些系统级的试验验证。
以下为小马智行的ADC域控制器通过的试验验证项目和测试规范。
域控制器测试项目及测试规范
不过其中有些测试标准用到了大众汽车和通用汽车的企业标准(如VW80000和GMW3172),而没有采用GB或者ISO的标准,这是为什么呢?
“一方面,GB/ISO和企标在测试项目上是有蛮高的重合度的,另一方面,企标,尤其是像通用汽车和大众汽车这种国际车企巨头,在具体测试标准和要求上面,比GB/ISO的要求更严格,业内的认可度也非常高。”
“按照更严格的企标要求来做测试,这样客户就不担心测试标准问题了。域控的A样和B样已在北上广深多地路测超半年,自动驾驶软硬件均运行正常。”
据介绍,为了更快地进行迭代,小马智行也斥资自建了试验室,如在上海自建了可靠性试验室,在广州深圳自建了高速信号测试试验室,这样可以保证有充分的测试资源,在项目早期就可以及时发现并解决域控制器的关键设计风险。
3.1.2
控制成本
要控制成本,首先是从设计上降低物料成本,其次要控制生产成本,还要降低物料的采购成本。
对此,C介绍说:“在设计上,就像之前提到的,基于这么多年来积累的对自动驾驶软硬件的思考,小马智行基于英伟达参考设计做了大量设计优化,节省了一些器件,从而在设计上能降低一些成本。”
“在生产上,小马智行和一家著名的EMS集成商(代工厂)深度合作,由这家合作伙伴来负责域控制器的生产,在生产成本控制方面非常有经验。”
“在采购物料成本控制上,一方面,在一些关键芯片,比如英伟达的Orin X、英飞凌的MCU等,依靠小马智行和这些芯片厂商长期开发合作中积累的合作关系,小马智行直接和原厂签订合同,拿到相当不错的供货周期和报价,再委托代工厂代为采供;另一方面,一些非关键元器件则由负责生产的代工厂负责采购,因为本身出货量能够保证,元器件采购成本也是蛮低的。”
“结合以上几点原因,目前从客户的反馈来看,小马智行的域控制器成本还是非常有竞争力的。”
3.2
如何解决生产和质量管控问题
上文中也提到,在域控的生产上,小马智行是与代工厂深度合作进行生产的。
据C介绍,从前期的设计阶段,代工厂就开始介入,从生产工艺角度提一些建议,并且双方一起制定DFEMA(设计潜在失效模式及后果分析)和PFEMA(过程潜在失效模式及后果分析)。
在生产阶段,小马智行也是深度参与。在前期产线设计阶段,生产工艺制定和生产控制计划是由双方共同制定,尤其是下线检测的流程和要求、下线后的检测,如抽检还是全检,如何抽检,抽检样品如何做老化试验等,小马智行都会全程深度参与并提出要求,甚至下线检测的检测台架和测试程序,都是小马智行提供给代工厂使用的。量产过程中的防错工艺等,则更多还是依赖经验更为丰富的代工厂。
在生产过程中,从物料的来料到生产下线的全过程,小马智行都是能够实时监控的,确保整个过程中完全可控。
为了更好地进行质量管控,小马智行内部有独立的质量团队,对软硬件的交付质量全程负责,并直接汇报给最高层。
此外,小马智行和代工厂也都通过了ISO9001和ISO/TS16949的体系认证,所有的质量管控措施都落实到APQP(先期产品质量策划与控制计划)里进行实施和跟踪。
3.3
如何解决供应链管理和保供问题
在缺芯的大背景下,供应链管理和保供能力成了车企在选择供应商时不得不考虑的因素。
为了更好地监控生产过程,小马智行和代工厂的MES(制造执行系统)系统打通,小马智行可以实时监控来料、生产和发运状态,第一时间发现问题并预警。
同时,小马智行内部也有独立的供应链团队,来管理战略性的物料,比如英伟达的Orin X芯片或者MCU芯片。
在这方面,因为小马智行和英伟达长期且深度的合作关系,英伟达官方对小马智行提供了非常好的支持。
笔者在和一些使用Orin X的车企专家交流时,听到了很多关于英伟达“官方支持力度不足”的抱怨,导致出了问题只能自己摸索解决,很影响开发效率。
在这方面,因为小马智行和英伟达长期且深度的合作关系,英伟达官方对小马智行提供了非常好的支持。
据小马智行电子电气架构负责人C介绍:“小马智行和英伟达的合作,不仅在域控领域,还包括GPU、数据中心,还有CUDA和Tensor RT等方面。”
“在数据中心方面,小马智行做的一些前沿的预研研究,比如训练、回归测试等方面,英伟达也是给了很大力度的支持。”
“此前小马智行给Tensor RT提交的一些修改,也逐渐在后续的Tensor RT 8等版本上看到了。”
“在域控领域,英伟达美国总部有个10人左右的团队来支持小马智行的工作,每周开两次会,硬件和底层软件各一次。小马智行的问题和想法,不论是小马智行自己的问题,还是客户遇到的问题,都能够得到很快的响应。”
“在关键芯片上,小马智行直接和芯片原厂签订供货合同,可以确保供货周期,非关键零件,则由代工厂进行采购和备货;同时,在设计上也采取了‘Plan B’的设计预留方案,即万一某芯片缺货严重,则可以直接切换到某个‘Plan B’芯片上去,而前期在设计上就做好了切换‘Plan B’的设计预留。小马智行在这方面的工程能力的积累,也能够助力供应链管理,可以保证万一某个芯片缺货时,也不影响域控整体的生产和供货。”
未尽之语
在跟传统的域控制器玩家竞争时,小马智行胜算几何?这也是一开始笔者的疑问,毕竟传统玩家的经验优势更为明显。
但在写完这篇文章后,笔者想明白了一个道理:是鞋决定脚,还是脚决定鞋?
当鞋子刚出现时,肯定是卖方市场,因为市面上的鞋很少,脚也没得选。就算穿得不舒服,也只能凑合穿,也就是“鞋决定脚”;但是随着市场发展,卖鞋的商家越来越多,最终就会变成买方市场——谁更了解脚,才能做出最舒服的鞋,才能卖得更好,也就是“脚决定鞋”。
同样的道理,不管是L4公司,还是传统域控厂商,只有足够了解智能驾驶的使用场景和智能驾驶算法及软件,才能更好地设计硬件;也只有对智能驾驶有了深刻的理解,才能打造更适合智能驾驶的域控制器。
参考资料
1. 加速小马智行自动驾驶汽车传感器数据处理流水线https://zhuanlan.zhihu.com/p/521019988
2. Accelerating In-Vehicle GPU Computing, from Sensing to Inference https://www.nvidia.cn/on-demand/session/gtcspring22-s41879/
参考文献链接
https://mp.weixin.qq.com/s/aY4ZPNBMjfQIklq2foWzyw
https://mp.weixin.qq.com/s/DDJdr9JR67HzfOp05USDQA
https://mp.weixin.qq.com/s/3kffmLpuHdMMKOXRYhrgQQ
推荐阅读
-
自动驾驶系列 - 从速度感应到车身控制:轮速仪在自动驾驶中的应用 - 5.核心关键指标
-
编码在DevOps设计与规划中的关键角色
-
【摩尔线程+Colossal-AI强强联手】MusaBert登上CLUE榜单TOP10:技术细节揭秘 - 技术实力:摩尔线程凭借"软硬兼备"的技术底蕴,让MusaBert得以从底层优化到顶层。其内置多功能GPU配备AI加速和并行计算模块,提供了全面的AI与科学计算支持,为AI推理和低资源条件下的大模型训练等场景带来了高效、经济且环保的算力。 - 算法层面亮点:依托Colossal-AI AI大模型开发系统,MusaBert在训练过程中展现出了卓越的并行性能与易用性,特别在预处理阶段对DataLoader进行了优化,适应低资源环境高效处理海量数据。同时,通过精细的建模优化、领域内数据增强以及Adan优化器等手段,挖掘和展示了预训练语言模型出色的语义理解潜力。基于MusaBert,摩尔线程自主研发的MusaSim通过对比学习方法微调,结合百万对标注数据,MusaSim在多个任务如语义相似度、意图识别和情绪分析中均表现出色。 - 数据资源丰富:MusaBert除了自家高质量语义相似数据外,还融合了悟道开源200GB数据、CLUE社区80GB数据,以及浪潮公司提供的1TB高质量数据,保证模型即便在较小规模下仍具备良好性能。 当前,MusaBert已成功应用于摩尔线程的智能客服与数字人项目,并广泛服务于语义相似度、情绪识别、阅读理解与声韵识别等领域。为了降低大模型开发和应用难度,MusaBert及其相关高质量模型代码已在Colossal-AI仓库开源,可快速训练优质中文BERT模型。同时,通过摩尔线程与潞晨科技的深度合作,仅需一张多功能GPU单卡便能高效训练MusaBert或更大规模的GPT2模型,显著降低预训练成本,进一步推动双方在低资源大模型训练领域的共享目标。 MusaBert荣登CLUE榜单TOP10,象征着摩尔线程与潞晨科技联合研发团队在中文预训练研究领域的领先地位。展望未来,双方将携手探索更大规模的自然语言模型研究,充分运用上游数据资源,产出更为强大的模型并开源。持续强化在摩尔线程多功能GPU上的大模型训练能力,特别是在消费级显卡等低资源环境下,致力于降低使用大模型训练的门槛与成本,推动人工智能更加普惠。而潞晨科技作为重要合作伙伴,将继续发挥关键作用。
-
在MyBatis中处理Oracle关键字错误的实例与解决方案
-
在Spring MVC架构中,各个部件的角色与功能划分详解及其优化改进建议
-
TypeScript实战笔记:详解类与泛型的运用实例,学习如何在TypeScript中玩转泛型,及其在提升代码灵活性与安全性的角色 - 青训营教程
-
理解工作流:自动化业务流程管理与Activiti实践" **简述** 工作流(Workflow)是一种利用电脑技术自动化管理业务流程的方式,让不同参与者按既定路径执行任务,确保文档、信息或任务在预设规则下顺利传递,最终达成期望的业务目标。 **核心概念** - **工作流自动化**: 计算机驱动业务流程处理与执行,如在参与者间自动传递文档和任务。 - **目标与应用**: 管理工作流程确保按时、由合适的人执行,同时允许人工介入以增强灵活性。 - **工作流框架示例**: Activiti、JBPM、OSWorkflow 和 Workflow,它们背后通常依赖数据库支持。 - **关键组件**: ProcessEngine 在 Activiti 中扮演核心角色,负责流程实例创建、数据管理和流程监控。 **相关领域** - **业务流程管理 (BPM)**: 一种系统性方法论,聚焦于构建并优化端到端卓越业务流程以提升企业业绩,在EMBA、MBA等商业课程中得到关注。 - **业务流程建模与标记语言 (BPMN)**: 用于绘制业务流程图的工具,探讨其在不同场景下的应用精确度、标准化价值以及未来发展愿景。 **辅助术语** - 流对象 (Flow Objects): BPMN 中用于描述流程中活动、决策、序列和其他元素的具体实现单元。
-
` 自动填充为 `cp test.txt`
- 文件和目录名补全:输入文件名首字母后按 Tab,如 `vi ed
` 显示可用的编辑器列表 - 查看命令帮助: - 使用 `man` 命令配合具体命令名获取详尽帮助,如 `man ls` 或者 `man grep --help`"> 在 Linux 中操作指令指南 - 基本构造与种类 - 指令组成: 1. **主指令 + 选项 + 参数**: 如 `ls -l /home`,`main-action option object` - 内置指令:系统预装的 shell 功能,如 `cd`, `pwd` - 外部指令:独立可执行文件,直接用文件名当作命令,如 `rm`, `mv` - **选项与参数**: - 选项:定制命令行为, `-l` 或 `--long-help` - 短选项:简写形式,例如 `-v` 和 `-V` 可能合并使用 - 长选项:详细描述的选项,如 `--version` 或 `--human-readable` - 参数:命令作用的目标,如 `ls` 对 `/home` 目录的操作 - **指令应用**: - 不同指令需要不同的参数 - 选项可带或不带参数,比如 `grep -i "keyword"` (忽略大小写搜索) - 参数间通常用空格分隔,如 `cp file1 file2 file3` - **中断与完成提示**: - 终止当前指令:按下 Ctrl+C - **自动完成**: - 输入部分命令关键词后,按 Tab 键补全命令,如 `cp ta
` 自动填充为 `cp test.txt` - 文件和目录名补全:输入文件名首字母后按 Tab,如 `vi ed ` 显示可用的编辑器列表 - 查看命令帮助: - 使用 `man` 命令配合具体命令名获取详尽帮助,如 `man ls` 或者 `man grep --help` -
Softmax 函数与 Log-Likelihood 损失详解:理解二者在概率评估中的角色
-
SSM三大框架基础面试题-一、Spring篇 什么是Spring框架? Spring是一种轻量级框架,提高开发人员的开发效率以及系统的可维护性。 我们一般说的Spring框架就是Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发。这些模块是核心容器、数据访问/集成、Web、AOP(面向切面编程)、工具、消息和测试模块。比如Core Container中的Core组件是Spring所有组件的核心,Beans组件和Context组件是实现IOC和DI的基础,AOP组件用来实现面向切面编程。 Spring的6个特征: 核心技术:依赖注入(DI),AOP,事件(Events),资源,i18n,验证,数据绑定,类型转换,SpEL。 测试:模拟对象,TestContext框架,Spring MVC测试,WebTestClient。 数据访问:事务,DAO支持,JDBC,ORM,编组XML。 Web支持:Spring MVC和Spring WebFlux Web框架。 集成:远程处理,JMS,JCA,JMX,电子邮件,任务,调度,缓存。 语言:Kotlin,Groovy,动态语言。 列举一些重要的Spring模块? Spring Core:核心,可以说Spring其他所有的功能都依赖于该类库。主要提供IOC和DI功能。 Spring Aspects:该模块为与AspectJ的集成提供支持。 Spring AOP:提供面向切面的编程实现。 Spring JDBC:Java数据库连接。 Spring JMS:Java消息服务。 Spring ORM:用于支持Hibernate等ORM工具。 Spring Web:为创建Web应用程序提供支持。 Spring Test:提供了对JUnit和TestNG测试的支持。 谈谈自己对于Spring IOC和AOP的理解 IOC(Inversion Of Controll,控制反转)是一种设计思想: 在程序中手动创建对象的控制权,交由给Spring框架来管理。IOC在其他语言中也有应用,并非Spring特有。IOC容器实际上就是一个Map(key, value),Map中存放的是各种对象。 将对象之间的相互依赖关系交给IOC容器来管理,并由IOC容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。IOC容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。在实际项目中一个Service类可能由几百甚至上千个类作为它的底层,假如我们需要实例化这个Service,可能要每次都搞清楚这个Service所有底层类的构造函数,这可能会把人逼疯。如果利用IOC的话,你只需要配置好,然后在需要的地方引用就行了,大大增加了项目的可维护性且降低了开发难度。 Spring中的bean的作用域有哪些? 1.singleton:该bean实例为单例 2.prototype:每次请求都会创建一个新的bean实例(多例)。 3.request:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。 4.session:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP session内有效。 5.global-session:全局session作用域,仅仅在基于Portlet的Web应用中才有意义,Spring5中已经没有了。Portlet是能够生成语义代码(例如HTML)片段的小型Java Web插件。它们基于Portlet容器,可以像Servlet一样处理HTTP请求。但是与Servlet不同,每个Portlet都有不同的会话。 Spring中的单例bean的线程安全问题了解吗? 概念用于理解:大部分时候我们并没有在系统中使用多线程,所以很少有人会关注这个问题。单例bean存在线程问题,主要是因为当多个线程操作同一个对象的时候,对这个对象的非静态成员变量的写操作会存在线程安全问题。 有两种常见的解决方案(用于回答的点): 1.在bean对象中尽量避免定义可变的成员变量(不太现实)。 2.在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal(线程本地化对象)中(推荐的一种方式)。 ThreadLocal解决多线程变量共享问题(参考博客):https://segmentfault.com/a/1190000009236777 Spring中Bean的生命周期: 1.Bean容器找到配置文件中Spring Bean的定义。 2.Bean容器利用Java Reflection API创建一个Bean的实例。 3.如果涉及到一些属性值,利用set方法设置一些属性值。 4.如果Bean实现了BeanNameAware接口,调用setBeanName方法,传入Bean的名字。 5.如果Bean实现了BeanClassLoaderAware接口,调用setBeanClassLoader方法,传入ClassLoader对象的实例。 6.如果Bean实现了BeanFactoryAware接口,调用setBeanClassFacotory方法,传入ClassLoader对象的实例。 7.与上面的类似,如果实现了其他*Aware接口,就调用相应的方法。 8.如果有和加载这个Bean的Spring容器相关的BeanPostProcessor对象,执postProcessBeforeInitialization方法。 9.如果Bean实现了InitializingBean接口,执行afeterPropertiesSet方法。 10.如果Bean在配置文件中的定义包含init-method属性,执行指定的方法。 11.如果有和加载这个Bean的Spring容器相关的BeanPostProcess对象,执行postProcessAfterInitialization方法。 12.当要销毁Bean的时候,如果Bean实现了DisposableBean接口,执行destroy方法。 13.当要销毁Bean的时候,如果Bean在配置文件中的定义包含destroy-method属性,执行指定的方法。 Spring框架中用到了哪些设计模式? 1.工厂设计模式:Spring使用工厂模式通过BeanFactory和ApplicationContext创建bean对象。 2.代理设计模式:Spring AOP功能的实现。 3.单例设计模式:Spring中的bean默认都是单例的。 4.模板方法模式:Spring中的jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类,它们就使用到了模板模式。 5.包装器设计模式:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。 6.观察者模式:Spring事件驱动模型就是观察者模式很经典的一个应用。 7.适配器模式:Spring AOP的增强或通知(Advice)使用到了适配器模式、Spring MVC中也是用到了适配器模式适配Controller。 还有很多。。。。。。。 @Component和@Bean的区别是什么 1.作用对象不同。@Component注解作用于类,而@Bean注解作用于方法。 2.@Component注解通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中(我们可以使用@ComponentScan注解定义要扫描的路径)。@Bean注解通常是在标有该注解的方法中定义产生这个bean,告诉Spring这是某个类的实例,当我需要用它的时候还给我。 3.@Bean注解比@Component注解的自定义性更强,而且很多地方只能通过@Bean注解来注册bean。比如当引用第三方库的类需要装配到Spring容器的时候,就只能通过@Bean注解来实现。 @Configuration public class AppConfig { @Bean public TransferService transferService { return new TransferServiceImpl; } } <beans> <bean id="transferService" class="com.kk.TransferServiceImpl"/> </beans> @Bean public OneService getService(status) { case (status) { when 1: return new serviceImpl1; when 2: return new serviceImpl2; when 3: return new serviceImpl3; } } 将一个类声明为Spring的bean的注解有哪些? 声明bean的注解: @Component 组件,没有明确的角色 @Service 在业务逻辑层使用(service层) @Repository 在数据访问层使用(dao层) @Controller 在展现层使用,控制器的声明 注入bean的注解: @Autowired:由Spring提供 @Inject:由JSR-330提供 @Resource:由JSR-250提供 *扩:JSR 是 java 规范标准 Spring事务管理的方式有几种? 1.编程式事务:在代码中硬编码(不推荐使用)。 2.声明式事务:在配置文件中配置(推荐使用),分为基于XML的声明式事务和基于注解的声明式事务。 Spring事务中的隔离级别有哪几种? 在TransactionDefinition接口中定义了五个表示隔离级别的常量:ISOLATION_DEFAULT:使用后端数据库默认的隔离级别,Mysql默认采用的REPEATABLE_READ隔离级别;Oracle默认采用的READ_COMMITTED隔离级别。ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。ISOLATION_SERIALIZABLE:最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。 Spring事务中有哪几种事务传播行为? 在TransactionDefinition接口中定义了八个表示事务传播行为的常量。 支持当前事务的情况:PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)。 不支持当前事务的情况:PROPAGATION_REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务挂起。PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。PROPAGATION_NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常。 其他情况:PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于PROPAGATION_REQUIRED。 二、SpringMVC篇 什么是Spring MVC ?简单介绍下你对springMVC的理解? Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把Model,View,Controller分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。 Spring MVC的工作原理了解嘛? image.png Springmvc的优点: (1)可以支持各种视图技术,而不仅仅局限于JSP; (2)与Spring框架集成(如IoC容器、AOP等); (3)清晰的角色分配:前端控制器(dispatcherServlet) , 请求到处理器映射(handlerMapping), 处理器适配器(HandlerAdapter), 视图解析器(ViewResolver)。 (4) 支持各种请求资源的映射策略。 Spring MVC的主要组件? (1)前端控制器 DispatcherServlet(不需要程序员开发) 作用:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。 (2)处理器映射器HandlerMapping(不需要程序员开发) 作用:根据请求的URL来查找Handler (3)处理器适配器HandlerAdapter 注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。 (4)处理器Handler(需要程序员开发) (5)视图解析器 ViewResolver(不需要程序员开发) 作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view) (6)视图View(需要程序员开发jsp) View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等) springMVC和struts2的区别有哪些? (1)springmvc的入口是一个servlet即前端控制器(DispatchServlet),而struts2入口是一个filter过虑器(StrutsPrepareAndExecuteFilter)。 (2)springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。 (3)Struts采用值栈存储请求和响应的数据,通过OGNL存取数据,springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。 SpringMVC怎么样设定重定向和转发的? (1)转发:在返回值前面加"forward:",譬如"forward:user.do?name=method4" (2)重定向:在返回值前面加"redirect:",譬如"redirect:http://www.baidu.com" SpringMvc怎么和AJAX相互调用的? 通过Jackson框架就可以把Java里面的对象直接转化成Js可以识别的Json对象。具体步骤如下 : (1)加入Jackson.jar (2)在配置文件中配置json的映射 (3)在接受Ajax方法里面可以直接返回Object,List等,但方法前面要加上@ResponseBody注解。 如何解决POST请求中文乱码问题,GET的又如何处理呢? (1)解决post请求乱码问题: 在web.xml中配置一个CharacterEncodingFilter过滤器,设置成utf-8; <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> (2)get请求中文参数出现乱码解决方法有两个: ①修改tomcat配置文件添加编码与工程编码一致,如下: <ConnectorURIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/> ②另外一种方法对参数进行重新编码: String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8") ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码。 Spring MVC的异常处理 ? 统一异常处理: Spring MVC处理异常有3种方式: (1)使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver; (2)实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器; (3)使用@ExceptionHandler注解实现异常处理; 统一异常处理的博客:https://blog.csdn.net/ctwy291314/article/details/81983103 SpringMVC的控制器是不是单例模式,如果是,有什么问题,怎么解决? 是单例模式,所以在多线程访问的时候有线程安全问题,不要用同步,会影响性能的,解决方案是在控制器里面不能写成员变量。(此题目类似于上面Spring 中 第5题 有两种解决方案) SpringMVC常用的注解有哪些? @RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。 @RequestBody:注解实现接收http请求的json数据,将json转换为java对象。 @ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户。 SpingMvc中的控制器的注解一般用那个,有没有别的注解可以替代? 一般用@Controller注解,也可以使用@RestController,@RestController注解相当于@ResponseBody + @Controller,表示是表现层,除此之外,一般不用别的注解代替。 如果在拦截请求中,我想拦截get方式提交的方法,怎么配置? 可以在@RequestMapping注解里面加上method=RequestMethod.GET。 怎样在方法里面得到Request,或者Session? 直接在方法的形参中声明request,SpringMVC就自动把request对象传入。 如果想在拦截的方法里面得到从前台传入的参数,怎么得到? 直接在形参里面声明这个参数就可以,但必须名字和传过来的参数一样。 如果前台有很多个参数传入,并且这些参数都是一个对象的,那么怎么样快速得到这个对象? 直接在方法中声明这个对象,SpringMVC就自动会把属性赋值到这个对象里面。 SpringMVC中函数的返回值是什么? 返回值可以有很多类型,有String, ModelAndView。ModelAndView类把视图和数据都合并的一起的。 SpringMVC用什么对象从后台向前台传递数据的? 通过ModelMap对象,可以在这个对象里面调用put方法,把对象加到里面,前台就可以拿到数据。 怎么样把ModelMap里面的数据放入Session里面? 可以在类上面加上@SessionAttributes注解,里面包含的字符串就是要放入session里面的key。 SpringMvc里面拦截器是怎么写的: 有两种写法,一种是实现HandlerInterceptor接口,另外一种是继承适配器类,接着在接口方法当中,实现处理逻辑;然后在SpringMvc的配置文件中配置拦截器即可: <!-- 配置SpringMvc的拦截器 --> <mvc:interceptors> <!-- 配置一个拦截器的Bean就可以了 默认是对所有请求都拦截 --> <bean id="myInterceptor" class="com.zwp.action.MyHandlerInterceptor"></bean> <!-- 只针对部分请求拦截 --> <mvc:interceptor> <mvc:mapping path="/modelMap.do" /> <bean class="com.zwp.action.MyHandlerInterceptorAdapter" /> </mvc:interceptor> </mvc:interceptors> 注解原理: 注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象。通过代理对象调用自定义注解的方法,会最终调用AnnotationInvocationHandler的invoke方法。该方法会从memberValues这个Map中索引出对应的值。而memberValues的来源是Java常量池 三、Mybatis篇 什么是MyBatis? MyBatis是一个可以自定义SQL、存储过程和高级映射的持久层框架。 讲下MyBatis的缓存 MyBatis的缓存分为一级缓存和二级缓存,一级缓存放在session里面,默认就有, 二级缓存放在它的命名空间里,默认是不打开的,使用二级缓存属性类需要实现Serializable序列化接口, 可在它的映射文件中配置<cache/> Mybatis是如何进行分页的?分页插件的原理是什么? 1)Mybatis使用RowBounds对象进行分页,也可以直接编写sql实现分页,也可以使用Mybatis的分页插件。 2)分页插件的原理:实现Mybatis提供的接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql。 举例:select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0,10 简述Mybatis的插件运行原理,以及如何编写一个插件? 1)Mybatis仅可以编写针对ParameterHandler、ResultSetHandler、StatementHandler、 Executor这4种接口的插件,Mybatis通过动态代理, 为需要拦截的接口生成代理对象以实现接口方法拦截功能, 每当执行这4种接口对象的方法时,就会进入拦截方法, 具体就是InvocationHandler的invoke方法,当然, 只会拦截那些你指定需要拦截的方法。 2)实现Mybatis的Interceptor接口并复写intercept方法, 然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可, 记住,别忘了在配置文件中配置你编写的插件。 Mybatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不? 1)Mybatis动态sql可以让我们在Xml映射文件内, 以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能。 2)Mybatis提供了9种动态sql标签:trim|where|set|foreach|if|choose|when|otherwise|bind。 3)其执行原理为,使用OGNL从sql参数对象中计算表达式的值, 根据表达式的值动态拼接sql,以此来完成动态sql的功能。 #{}和${}的区别是什么? 1)#{}是预编译处理,${}是字符串替换。 2)Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值(有效的防止SQL注入); 3)Mybatis在处理${}时,就是把${}替换成变量的值。 为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里? Hibernate属于全自动ORM映射工具, 使用Hibernate查询关联对象或者关联集合对象时, 可以根据对象关系模型直接获取,所以它是全自动的。 而Mybatis在查询关联对象或关联集合对象时, 需要手动编写sql来完成,所以,称之为半自动ORM映射工具。 Mybatis是否支持延迟加载?如果支持,它的实现原理是什么? 1)Mybatis仅支持association关联对象和collection关联集合对象的延迟加载, association指的就是一对一,collection指的就是一对多查询。 在Mybatis配置文件中, 可以配置是否启用延迟加载lazyLoadingEnabled=true|false。 2)它的原理是,使用CGLIB创建目标对象的代理对象, 当调用目标方法时,进入拦截器方法, 比如调用a.getB.getName, 拦截器invoke方法发现a.getB是null值, 那么就会单独发送事先保存好的查询关联B对象的sql, 把B查询上来,然后调用a.setB(b), 于是a的对象b属性就有值了, 接着完成a.getB.getName方法的调用。 这就是延迟加载的基本原理。 MyBatis与Hibernate有哪些不同? 1)Mybatis和hibernate不同,它不完全是一个ORM框架, 因为MyBatis需要程序员自己编写Sql语句, 不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句, 并将java对象和sql语句映射生成最终执行的sql, 最后将sql执行的结果再映射生成java对象。 2)Mybatis学习门槛低,简单易学,程序员直接编写原生态sql, 可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发, 例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁, 一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性, 如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。 3)Hibernate对象/关系映射能力强,数据库无关性好, 对于关系模型要求高的软件(例如需求固定的定制化软件) 如果用hibernate开发可以节省很多代码,提高效率。 但是Hibernate的缺点是学习门槛高,要精通门槛更高, 而且怎么设计O/R映射,在性能和对象模型之间如何权衡, 以及怎样用好Hibernate需要具有很强的经验和能力才行。 总之,按照用户的需求在有限的资源环境下只要能做出维护性、 扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。 MyBatis的好处是什么? 1)MyBatis把sql语句从Java源程序中独立出来,放在单独的XML文件中编写, 给程序的维护带来了很大便利。 2)MyBatis封装了底层JDBC API的调用细节,并能自动将结果集转换成Java Bean对象, 大大简化了Java数据库编程的重复工作。 3)因为MyBatis需要程序员自己去编写sql语句, 程序员可以结合数据库自身的特点灵活控制sql语句, 因此能够实现比Hibernate等全自动orm框架更高的查询效率,能够完成复杂查询。 简述Mybatis的Xml映射文件和Mybatis内部数据结构之间的映射关系? Mybatis将所有Xml配置信息都封装到All-In-One重量级对象Configuration内部。 在Xml映射文件中,<parameterMap>标签会被解析为ParameterMap对象, 其每个子元素会被解析为ParameterMapping对象。 <resultMap>标签会被解析为ResultMap对象, 其每个子元素会被解析为ResultMapping对象。 每一个<select>、<insert>、<update>、<delete> 标签均会被解析为MappedStatement对象, 标签内的sql会被解析为BoundSql对象。 什么是MyBatis的接口绑定,有什么好处? 接口映射就是在MyBatis中任意定义接口,然后把接口里面的方法和SQL语句绑定, 我们直接调用接口方法就可以,这样比起原来了SqlSession提供的方法我们可以有更加灵活的选择和设置. 接口绑定有几种实现方式,分别是怎么实现的? 接口绑定有两种实现方式,一种是通过注解绑定,就是在接口的方法上面加 上@Select@Update等注解里面包含Sql语句来绑定, 另外一种就是通过xml里面写SQL来绑定,在这种情况下, 要指定xml映射文件里面的namespace必须为接口的全路径名. 什么情况下用注解绑定,什么情况下用xml绑定? 当Sql语句比较简单时候,用注解绑定;当SQL语句比较复杂时候,用xml绑定,一般用xml绑定的比较多 MyBatis实现一对一有几种方式?具体怎么操作的? 有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次, 通过在resultMap里面配置association节点配置一对一的类就可以完成; 嵌套查询是先查一个表,根据这个表里面的结果的外键id, 去再另外一个表里面查询数据,也是通过association配置, 但另外一个表的查询通过select属性配置。 Mybatis能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别? 能,Mybatis不仅可以执行一对一、一对多的关联查询, 还可以执行多对一,多对多的关联查询,多对一查询, 其实就是一对一查询,只需要把selectOne修改为selectList即可; 多对多查询,其实就是一对多查询,只需要把selectOne修改为selectList即可。 关联对象查询,有两种实现方式,一种是单独发送一个sql去查询关联对象, 赋给主对象,然后返回主对象。另一种是使用嵌套查询,嵌套查询的含义为使用join查询, 一部分列是A对象的属性值,另外一部分列是关联对象B的属性值, 好处是只发一个sql查询,就可以把主对象和其关联对象查出来。 MyBatis里面的动态Sql是怎么设定的?用什么语法? MyBatis里面的动态Sql一般是通过if节点来实现,通过OGNL语法来实现, 但是如果要写的完整,必须配合where,trim节点,where节点是判断包含节点有 内容就插入where,否则不插入,trim节点是用来判断如果动态语句是以and 或or 开始,那么会自动把这个and或者or取掉。 Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式? 第一种是使用<resultMap>标签,逐一定义列名和对象属性名之间的映射关系。 第二种是使用sql列的别名功能,将列别名书写为对象属性名, 比如T_NAME AS NAME,对象属性名一般是name,小写, 但是列名不区分大小写,Mybatis会忽略列名大小写,