Tightly Coupled LiDAR Inertial Odometry and Mapping源码解析(二)

  • 3. Joint optimization
    • 3.1 Marginalization
      • 3.1.1 什么是Marginalization
      • 3.1.2 Basics of Multi-variate Gauss Distribution
      • 3.1.3 Marginalization in covariance and information form
      • 3.1.4 Schur Complement

3. Joint optimization

在上一个博客中,我们分别介绍了IMU预积分,LiDAR Relative Measurements,接下来就是非常重要优化环节了,优化过后才可以获得里程计计算结果。在这篇论文中,优化的目标函数主要由三部分构成:marginalization factorimu-preintegration,以及LiDAR relative measurements,我们首先来看第一个marginalization factor

3.1 Marginalization

3.1.1 什么是Marginalization

在上一博客中,我们已经知道该篇论文中引入了一个滑窗(Sliding Window),来限制待优化的状态向量数量。如下图所示,我们考虑这样一种情景,假设当前时刻窗口内的优化变量为x1,x2,...,x6x_1,x_2,...,x_6x1​,x2​,...,x6​,且已经对里程计中的目标函数完成了优化,也就是相当于拟合出来了一个概率分布p(x1,x2,...,x6)p(x_1,x_2,...,x_6)p(x1​,x2​,...,x6​),即多维高斯分布对应的均值μ\muμ和协方差矩阵KKK。此时在下一个优化时刻到来之前,我们需要将窗口往后移动一个格子,即开始优化此时窗口内的优化变量x2,x3,...,x7x_2,x_3,...,x_7x2​,x3​,...,x7​,这种过程会贯穿整个估计过程,直至算法停止运行。那么一个明显的问题是,我们在优化拟合出来p(x2,x3,...,x7)p(x_2,x_3,...,x_7)p(x2​,x3​,...,x7​)之前,该怎样处理概率分布p(x1,x2,...,x6)p(x_1,x_2,...,x_6)p(x1​,x2​,...,x6​)呢?

为了更形象的说明这个问题,我们来假设这样一种情景。小明开车想从中国科学技术大学到之心城买件衣服,怕迷路,想时刻估计一下自己到哪了,因此搞了个滑窗,利用gps,轮速计来分析自己当前和过往几个时刻自己开车到哪了。通过各种融合算法,发现自己x1,x2,...,x6x_1,x_2,...,x_6x1​,x2​,...,x6​时的位置分布为p(x1,x2,...,x6)p(x_1,x_2,...,x_6)p(x1​,x2​,...,x6​)发现自己原来刚出东门。然后接着往前开啊,现在滑窗内的状态就是x2,x3,...,x7x_2,x_3,...,x_7x2​,x3​,...,x7​了。那么如何估计我x2,x3,...,x7x_2,x_3,...,x_7x2​,x3​,...,x7​时刻的位置呢?
一种方法就是继续像上一时刻那样用自身的gps和轮速计等融合p(x2,x3,...,x7)p(x_2,x_3,...,x_7)p(x2​,x3​,...,x7​),也就是说我才不管你x1,x2,x3,...,x6x_1,x_2,x_3,...,x_6x1​,x2​,x3​,...,x6​时在哪,我只关心p(x2,x3,...,x7)p(x_2,x_3,...,x_7)p(x2​,x3​,...,x7​),计算完发现我去怎么还在东门附近?不是刚路过了吗?是不是算错了?
这时,聪明的副驾驶提醒你,哎这孩子读书读傻了,笨不笨,明明(x1,x2,...,x6)(x_1,x_2,...,x_6)(x1​,x2​,...,x6​)时刻都到p(x1,x2,...,x6)p(x_1,x_2,...,x_6)p(x1​,x2​,...,x6​)了,你咋还给忘了?你这不是黑瞎子掰玉米掰一个扔一个吗?把p(x2,...,x6)p(x_2,...,x_6)p(x2​,...,x6​)也就是我们刚刚路过东门这个消息加到你的那个什么融合算法里,再算一算我们现在到哪了?小明这才计算出来原来已经到东门前的十字路口了。
这个例子说明,在更新计算p(x2,x3,...,x7)p(x_2,x_3,...,x_7)p(x2​,x3​,...,x7​)时,总共有两种方法,第一种是直接丢掉之前窗口内拟合的分布p(x1,x2,...,x6)p(x_1,x_2,...,x_6)p(x1​,x2​,...,x6​),重新计算估计p(x2,x3,...,x7)p(x_2,x_3,...,x_7)p(x2​,x3​,...,x7​)。但是这种方法有一个比较重要的缺陷就是信息损失,可能p(x2,x3,...,x6)p(x_2,x_3,...,x_6)p(x2​,x3​,...,x6​)内的估计非常准确,而你却把这么重要的信息给直接扔了,这不是败家吗你说?第二种方法就是将p(x1,x2,...,x6)p(x_1,x_2,...,x_6)p(x1​,x2​,...,x6​)中的p(x2,x3,...,x6)p(x_2,x_3,...,x_6)p(x2​,x3​,...,x6​)计算出来,并将p(x2,x3,...,x6)p(x_2,x_3,...,x_6)p(x2​,x3​,...,x6​)作为先验信息加入到新窗口的估计中。那么问题来了,怎样根据p(x1,x2,...,x6)p(x_1,x_2,...,x_6)p(x1​,x2​,...,x6​)计算p(x2,x3,...,x6)p(x_2,x_3,...,x_6)p(x2​,x3​,...,x6​)呢?这个过程就叫做Marginalization。下图能比较清晰严谨的说明这个问题,数理基础比较好的话也能想到我们好像学过这个公式:p(xa)=∫xbp(xa,xb)p(x_a)=\int_{x_b}p(x_a,x_b)p(xa​)=∫xb​​p(xa​,xb​)。接下来我们从数学的角度严谨的说明一下Marginalization

3.1.2 Basics of Multi-variate Gauss Distribution

如下图所示,假设有一个系统长这个样子,其中y2y_2y2​表示的是室外的温度,y1y_1y1​表示的是房间1的温度,y3y_3y3​表示的是房间3的温度,且他们之间的函数关系表示为:

{y2=v2y1=w1y2+v1y3=w3y2+v3vi−N(0,σi2),高斯噪声\begin{cases} y_2=v_2\\ y_1=w_1y_2+v_1\\ y_3=w_3y_2+v_3\\ v_i-N(0,\sigma_i^2),高斯噪声 \end{cases} ⎩⎪⎪⎪⎨⎪⎪⎪⎧​y2​=v2​y1​=w1​y2​+v1​y3​=w3​y2​+v3​vi​−N(0,σi2​),高斯噪声​
则状态向量y=[y1,y2,y3]Ty=[y_1,y_2,y_3]^Ty=[y1​,y2​,y3​]T对应的协防差矩阵KKK为:
K11=E(y1y1)=w12σ22+σ12,K22=E(y2y2)=σ22,K33=E(y3y3)=w32σ22+σ32K12=K21=E(y1y2)=w12σ22,K13=K31=w1w3σ22,K23=K32=w3σ22K_{11}=E(y_1y_1)=w_1^2\sigma_2^2+\sigma_1^2,K_{22}=E(y_2y_2)=\sigma_2^2,K_{33}=E(y_3y_3)=w_3^2\sigma_2^2+\sigma_3^2 \\ K_{12}=K_{21}=E(y_1y_2)=w_1^2\sigma_2^2,K_{13}=K_{31}=w_1w_3\sigma_2^2,K_{23}=K_{32}=w_3\sigma_2^2 K11​=E(y1​y1​)=w12​σ22​+σ12​,K22​=E(y2​y2​)=σ22​,K33​=E(y3​y3​)=w32​σ22​+σ32​K12​=K21​=E(y1​y2​)=w12​σ22​,K13​=K31​=w1​w3​σ22​,K23​=K32​=w3​σ22​
即:
K=(w12σ22+σ12w1σ22w1w3σ22w1σ22σ22w3σ22w1w3σ22w3σ22w32σ22+σ32)K= \left( \begin{matrix} w_1^2\sigma_2^2+\sigma_1^2 & w_1\sigma_2^2 & w_1w_3\sigma_2^2\\ w_1\sigma_2^2 & \sigma_2^2 & w_3\sigma_2^2\\ w_1w_3\sigma_2^2 & w_3\sigma_2^2 & w_3^2\sigma_2^2+\sigma_3^2 \end{matrix} \right) K=⎝⎛​w12​σ22​+σ12​w1​σ22​w1​w3​σ22​​w1​σ22​σ22​w3​σ22​​w1​w3​σ22​w3​σ22​w32​σ22​+σ32​​⎠⎞​
现在知道了该向量对应的协方差矩阵,只需要求解其逆矩阵就可以得到信息矩阵。不过直接求解其逆矩阵还是比较麻烦的,因此我们按照如下的方法求解。我们首先需要求解​对应的联合概率分布,则根据贝叶斯公式可以得到:
p(y1,y2,y3)=p(y1,y3∣y2)p(y2)=p(y1∣y3,y2)p(y3∣y2)p(y2)p(y_1,y_2,y_3)=p(y_1,y_3|y_2)p(y_2)=p(y_1|y_3,y_2)p(y_3|y_2)p(y_2)p(y1​,y2​,y3​)=p(y1​,y3​∣y2​)p(y2​)=p(y1​∣y3​,y2​)p(y3​∣y2​)p(y2​)
而由前面​之间的关系我们知道,​​​​y1y_1y1​是不依赖于y3y_3y3​​的,因此​p(y1∣y3,y2)=p(y1∣y2)p(y_1|y_3,y_2)=p(y_1|y_2)p(y1​∣y3​,y2​)=p(y1​∣y2​)​​​​​​​​,因此上式可以化简为:
p(y1,y2,y3)=p(y1∣y2)p(y3∣y2)p(y2)p(y_1,y_2,y_3)=p(y_1|y_2)p(y_3|y_2)p(y_2)p(y1​,y2​,y3​)=p(y1​∣y2​)p(y3​∣y2​)p(y2​)
p(y2)=1Z2e−y222σ22p(y_2)=\frac{1}{Z_2}e^{-\frac{y_2^2}{2\sigma_2^2}}p(y2​)=Z2​1​e−2σ22​y22​​
p(y1∣y2)=1Z1e−(y1−w1y2)22σ12p(y_1|y_2)=\frac{1}{Z_1}e^{-\frac{(y_1-w_1y_2)^2}{2\sigma_1^2}}p(y1​∣y2​)=Z1​1​e−2σ12​(y1​−w1​y2​)2​
p(y3∣y2)=1Z3e−(y3−w3y2)22σ32p(y_3|y_2)=\frac{1}{Z_3}e^{-\frac{(y_3-w_3y_2)^2}{2\sigma_3^2}}p(y3​∣y2​)=Z3​1​e−2σ32​(y3​−w3​y2​)2​
p(y1,y2,y3)=1Z′exp(−12(y22σ22+(y1−w1y2)2σ12+(y3−w3y2)2σ32))p(y_1,y_2,y_3)=\frac{1}{Z'}exp(-\frac{1}{2}(\frac{y_2^2}{\sigma_2^2}+\frac{(y_1-w_1y_2)^2}{\sigma_1^2}+\frac{(y_3-w_3y_2)^2}{\sigma_3^2}))p(y1​,y2​,y3​)=Z′1​exp(−21​(σ22​y22​​+σ12​(y1​−w1​y2​)2​+σ32​(y3​−w3​y2​)2​))
写成信息矩阵的形式既可以写为:
p(y1,y2,y3)=1Z′exp(−12[y1y2y3][1σ12−w1σ120−w1σ121σ22+w12σ12+w32σ32−w3σ320−w3σ321σ32][y1y2y3])p(y_1,y_2,y_3)=\frac{1}{Z'}exp(-\frac{1}{2}\left[\begin{matrix}y_1 & y_2 & y_3\end{matrix}\right]\left[\begin{matrix}\frac{1}{\sigma_1^2} & -\frac{w_1}{\sigma_1^2} & 0\\-\frac{w_1}{\sigma_1^2} & \frac{1}{\sigma_2^2}+\frac{w_1^2}{\sigma_1^2}+\frac{w_3^2}{\sigma_3^2} & -\frac{w_3}{\sigma_3^2}\\0 & -\frac{w_3}{\sigma_3^2} & \frac{1}{\sigma_3^2}\end{matrix}\right]\left[\begin{matrix}y_1 \\ y_2\\ y_3\end{matrix}\right])p(y1​,y2​,y3​)=Z′1​exp(−21​[y1​​y2​​y3​​]⎣⎢⎡​σ12​1​−σ12​w1​​0​−σ12​w1​​σ22​1​+σ12​w12​​+σ32​w32​​−σ32​w3​​​0−σ32​w3​​σ32​1​​⎦⎥⎤​⎣⎡​y1​y2​y3​​⎦⎤​)
Ω=[1σ12−w1σ120−w1σ121σ22+w12σ12+w32σ32−w3σ320−w3σ321σ32]\Omega=\left[\begin{matrix}\frac{1}{\sigma_1^2} & -\frac{w_1}{\sigma_1^2} & 0\\-\frac{w_1}{\sigma_1^2} & \frac{1}{\sigma_2^2}+\frac{w_1^2}{\sigma_1^2}+\frac{w_3^2}{\sigma_3^2} & -\frac{w_3}{\sigma_3^2}\\0 & -\frac{w_3}{\sigma_3^2} & \frac{1}{\sigma_3^2}\end{matrix}\right] Ω=⎣⎢⎡​σ12​1​−σ12​w1​​0​−σ12​w1​​σ22​1​+σ12​w12​​+σ32​w32​​−σ32​w3​​​0−σ32​w3​​σ32​1​​⎦⎥⎤​

3.1.3 Marginalization in covariance and information form

对于3.1.2中的系统,现在我们想marginalize out状态变量y3y_3y3​,也就是说现在的状态向量变为y‘=[y1,y2]Ty‘=[y_1,y_2]^Ty‘=[y1​,y2​]T,则该状态向量对应的协方差矩阵为:
K′=[w12σ22+σ12w1σ22w1σ22σ22]K'=\left[ \begin{matrix} w_1^2\sigma_2^2+\sigma_1^2 & w_1\sigma_2^2\\ w_1\sigma_2^2 & \sigma_2^2 \end{matrix} \right] K′=[w12​σ22​+σ12​w1​σ22​​w1​σ22​σ22​​]
从K′K'K′和KKK的对比中我们可以发现,在marginalize out y3y_3y3​后,新的状态变量对应的协方差矩阵K′K'K′不过是将原来的协方差矩阵KKK的第3行和第3列删掉,那么信息矩阵是不是也是这样呢?我们一起来推导一下。
p(y1,y2)=p(y1∣y2)p(y2)=1Z′exp(−12(y22σ22+(y1−w1y2)2σ12))=1Z′exp(−12[y1y2][1σ12−w1σ12−w1σ121σ22+w12σ12][y1y2])p(y_1,y_2)=p(y_1|y_2)p(y_2)=\frac{1}{Z'}exp(-\frac{1}{2}(\frac{y_2^2}{\sigma_2^2}+\frac{(y_1-w_1y_2)^2}{\sigma_1^2}))\\=\frac{1}{Z'}exp(-\frac{1}{2}\left[ \begin{matrix}y_1 & y_2\end{matrix} \right]\left[ \begin{matrix} \frac{1}{\sigma_1^2} & -\frac{w_1}{\sigma_1^2}\\ -\frac{w_1}{\sigma_1^2} & \frac{1}{\sigma_2^2}+\frac{w_1^2}{\sigma_1^2} \end{matrix} \right]\left[ \begin{matrix}y_1 \\ y_2\end{matrix} \right]) p(y1​,y2​)=p(y1​∣y2​)p(y2​)=Z′1​exp(−21​(σ22​y22​​+σ12​(y1​−w1​y2​)2​))=Z′1​exp(−21​[y1​​y2​​][σ12​1​−σ12​w1​​​−σ12​w1​​σ22​1​+σ12​w12​​​][y1​y2​​])
也就是说:
Ω′=[1σ12−w1σ12−w1σ121σ22+w12σ12]\Omega'=\left[ \begin{matrix} \frac{1}{\sigma_1^2} & -\frac{w_1}{\sigma_1^2}\\ -\frac{w_1}{\sigma_1^2} & \frac{1}{\sigma_2^2}+\frac{w_1^2}{\sigma_1^2} \end{matrix} \right] Ω′=[σ12​1​−σ12​w1​​​−σ12​w1​​σ22​1​+σ12​w12​​​]
发现,咦,信息矩阵好像不像协方差矩阵那样直接把y3y_3y3​对应的第3行和第3列去掉就可以了。也就是说对于一般情况来讲,假如一个状态向量为x=[aT,bT]Tx=[a^T,b^T]^Tx=[aT,bT]T,如果我们想marginalize out状态向量bbb,那么对于协方差矩阵仅需要将状态向量bbb对应的行和列删除就可以。可是信息矩阵不行啊,这怎么办呢?这时候就需要Schur Complement了。skir~~ skir~~

3.1.4 Schur Complement

为不失一般性,咱这次就不拿前两节中那个温度模型说事儿了。现在假设状态变量为x=[aT,bT]Tx=[a^T,b^T]^Tx=[aT,bT]T,其对应的协防差矩阵为:
K=[ACTCD]K=\left[ \begin{matrix} A & C^T\\ C & D \end{matrix} \right] K=[AC​CTD​]
其中,AAA和DDD为可逆方阵。
记其信息矩阵为Λ\LambdaΛ:
Λ=[ΛaaΛabΛbaΛbb]\Lambda = \left[ \begin{matrix} \Lambda_{aa} & \Lambda_{ab}\\ \Lambda_{ba} & \Lambda_{bb} \end{matrix} \right] Λ=[Λaa​Λba​​Λab​Λbb​​]
假设状态变量xxx满足多维高斯分布,则有下式:
p(x)=p0exp(−12E)p(x)=p_0exp(-\frac{1}{2}E) p(x)=p0​exp(−21​E)
E=[xaT,xbT]Λ[xaxb]=[xaT,xbT][ΛaaΛabΛbaΛbb][xaxb]\begin{matrix} E =\left[x_a^T,x_b^T\right]\Lambda\left[\begin{matrix}x_a\\x_b\end{matrix}\right]\\ = \left[x_a^T,x_b^T\right]\left[\begin{matrix}\Lambda_{aa}&\Lambda_{ab}\\\Lambda_{ba}&\Lambda_{bb}\end{matrix}\right]\left[\begin{matrix}x_a\\x_b\end{matrix}\right] \end{matrix} E=[xaT​,xbT​]Λ[xa​xb​​]=[xaT​,xbT​][Λaa​Λba​​Λab​Λbb​​][xa​xb​​]​
将上式打开就可以得到下式:
E=xaTΛaaxa+2xbTΛbaxa+xbTΛbbxbE=x_a^T\Lambda_{aa}x_a+2x_b^T\Lambda_{ba}x_a+x_b^T\Lambda_{bb}x_b E=xaT​Λaa​xa​+2xbT​Λba​xa​+xbT​Λbb​xb​
容易发现上式就是一个二次型,比较遗憾的是存在一个xbx_bxb​和xax_axa​的交叉项。为了分离变量,就需要用到我们线性代数中学过的配方法求标准二次型问题了。考虑到这个东西可能离大家比较久远,我们首先来简单回顾一下这种方法,简单来说就比如说一个函数Q(x1,x2)=x12+x22+3x1x2Q(x_1,x_2)=x_1^2+x_2^2+3x_1x_2Q(x1​,x2​)=x12​+x22​+3x1​x2​,写成矩阵的形式就是:
Q(x1,x2)=[x1,x2][1301][x1x2]Q(x_1,x_2)=\left[x_1,x_2\right]\left[\begin{matrix}1&3\\0&1\end{matrix}\right]\left[\begin{matrix}x_1\\x_2\end{matrix}\right] Q(x1​,x2​)=[x1​,x2​][10​31​][x1​x2​​]
我们说这个东西不是标准二次型就是因为中间的矩阵不是对角阵,右上角有一个比较烦人的数字3.那么怎么能把这个3搞没呢,这里就可以无脑用配方法啦。可以把Q函数改写成:
Q(x1,x2)=(x1+32x2)2−54x22Q(x_1,x_2)=(x_1+\frac{3}{2}x_2)^2-\frac{5}{4}x_2^2 Q(x1​,x2​)=(x1​+23​x2​)2−45​x22​
如果另y1=x1+1.5×x2,y2=x2y_1=x_1+1.5\times x_2,y_2=x_2y1​=x1​+1.5×x2​,y2​=x2​,然后上式就可以改写成:Q(y1,y2)=y12−1.25y22Q(y_1,y_2)=y_1^2-1.25y_2^2Q(y1​,y2​)=y12​−1.25y22​,也就是标准二次型的形式。
按照这种方法我们对EEE进行标准化则可以得到:
E=(xb+Λbb−1Λbaxa)TΛbb(xb+Λbb−1Λbaxa)+xaT(Λaa−ΛbaTΛbb−1Λba)xaE=(x_b+\Lambda_{bb}^{-1}\Lambda_{ba}x_a)^T\Lambda_{bb}(x_b+\Lambda_{bb}^{-1}\Lambda_{ba}x_a)+x_a^T(\Lambda_{aa}-\Lambda_{ba}^T\Lambda_{bb}^{-1}\Lambda_{ba})x_a E=(xb​+Λbb−1​Λba​xa​)TΛbb​(xb​+Λbb−1​Λba​xa​)+xaT​(Λaa​−ΛbaT​Λbb−1​Λba​)xa​
所谓的Λaa−ΛbaTΛbb−1Λba\Lambda_{aa}-\Lambda_{ba}^T\Lambda_{bb}^{-1}\Lambda_{ba}Λaa​−ΛbaT​Λbb−1​Λba​,也就是我们经常在论文里面看到的Schur Complements了,将会给基于信心矩阵的边缘化带来极大方便。对化简后的概率分布求积分p(xa)=∫p(xa,xb)dxbp(x_a)=\int p(x_a,x_b)dx_bp(xa​)=∫p(xa​,xb​)dxb​就可以得到去掉xbx_bxb​后的边缘分布啦,其信息矩阵就是这个schur complement。关于这部分的详细推导建议大家看这篇论文里面的定理1:

Manipulating the Multivariate Gaussian Density。

好了这篇博客就先到这里了,我们下篇博客见。

Tightly Coupled LiDAR Inertial Odometry and Mapping源码解析(二)相关推荐

  1. Tightly Coupled LiDAR Inertial Odometry and Mapping源码解析(一)

    Tightly Coupled LiDAR Inertial Odometry and Mapping源码解析(一) 1. LiDAR inertial odometry and mapping简介 ...

  2. Tightly Coupled LiDAR Inertial Odometry and Mapping源码解析(四)

    Tightly Coupled LiDAR Inertial Odometry and Mapping源码解析(四) 3. Joint optimization 3.3 IMU preintegrat ...

  3. Tightly Coupled LiDAR Inertial Odometry and Mapping源码解析(三)

    Tightly Coupled LiDAR Inertial Odometry and Mapping源码解析(三) 3. Joint optimization 3.2 IMU preintegrat ...

  4. 激光SLAM系统Fast LOAM (Lidar Odometry And Mapping)源码解析

    github地址:Fast LOAM (Lidar Odometry And Mapping) Fast LOAM提供了mapping和localization的两个节点,目前只使用其定位部分,以ve ...

  5. 【深度学习模型】智云视图中文车牌识别源码解析(二)

    [深度学习模型]智云视图中文车牌识别源码解析(二) 感受 HyperLPR可以识别多种中文车牌包括白牌,新能源车牌,使馆车牌,教练车牌,武警车牌等. 代码不可谓不混乱(别忘了这是职业公司的准产品级代码 ...

  6. erlang下lists模块sort(排序)方法源码解析(二)

    上接erlang下lists模块sort(排序)方法源码解析(一),到目前为止,list列表已经被分割成N个列表,而且每个列表的元素是有序的(从大到小) 下面我们重点来看看mergel和rmergel ...

  7. Kubernetes学习笔记之Calico CNI Plugin源码解析(二)

    女主宣言 今天小编继续为大家分享Kubernetes Calico CNI Plugin学习笔记,希望能对大家有所帮助. PS:丰富的一线技术.多元化的表现形式,尽在"360云计算" ...

  8. Mobx 源码解析 二(autorun)

    前言 我们在Mobx 源码解析 一(observable)已经知道了observable 做的事情了, 但是我们的还是没有讲解明白在我们的Demo中,我们在Button 的Click 事件中只是对ba ...

  9. android网络框架retrofit源码解析二

    注:源码解析文章参考了该博客:http://www.2cto.com/kf/201405/305248.html 前一篇文章讲解了retrofit的annotation,既然定义了,那么就应该有解析的 ...

最新文章

  1. ab测试nginx Nginx性能优化
  2. 如何为回归问题选择最合适的机器学习方法?
  3. MarkDown常用技巧总结
  4. JUC 中的多线程协作工具类:CountDownLatch 和 CyclicBarrier
  5. listview mysql查询_Sqlite 数据库分页查询(ListView分页显示数据)
  6. 使用pscp命令将windows系统里的文件传送到远程服务器
  7. 热狗树 树形dp(中国石油大学我要变强第九场)
  8. linux拷贝到新建文件夹命令行,Linux创建文件touch,复制文件cp,tab补全,链接文件ln命令...
  9. php 判断wap,php判断是否wap手机客户端的方法详解
  10. java servlet jsp 实例_Servlet+JSP例子
  11. 鸿蒙系统更新法定年龄,超25000位开发者参赛,华为首届鸿蒙开发者创新大赛创意满满...
  12. Mac实用技巧:怎样使用终端在macOS Big Sur Finder中锁定文件!
  13. AO*算法详解,附例子和算法详细步骤
  14. 华为交换机,登录密码忘记
  15. c语言需要什么硬件基础知识,学习c语言需要什么 基础c语言需要这些知识
  16. 数学知识-三角函数公式大全(值得收藏)
  17. 利用Excel可视化分析,柱形图、条形图、饼图、复合饼图,圆环图、组合图、漏斗图、地图的操作方法(适合小白)
  18. Wordress博客添加音乐播放器插件
  19. 《中国历代著名文学家评传》目录
  20. iOS仿微信录像和拍照(swift5.0)

热门文章

  1. 远程桌面常见问题及注意事项
  2. Android11谷歌安装器,谷歌Pixel5安卓11安装面具ROOT方案【赠送5G模块】
  3. 给谷歌安装es-head
  4. 手动安装Xposed5.1.1框架zip包,解决Could not found ZIP files报错
  5. LVGL hal indev(porting evdev)
  6. Mathpix公式识别使用教程
  7. 实践分享:一定要用OKR进行持续绩效管理的4个理由
  8. 2019互联网月饼大赏,你公司有上榜吗?
  9. 3分钟搞定高逼格PPT封底——简约型
  10. 计算机网络专业论文doc,计算机专业毕业论文(网络).doc