当前位置: 首页 > news >正文

《视觉SLAM十四讲》-- 非线性优化

文章目录

    • 05 非线性优化
      • 5.1 批量状态估计与最大后验估计
      • 5.2 最小二乘的引出
      • 5.3 非线性最小二乘
        • 5.3.1 一阶和二阶梯度法
        • 5.3.2 高斯牛顿法
        • 5.3.3 列文伯格-马夸尔特方法
      • 5.4 实践:曲线拟合问题

05 非线性优化

5.1 批量状态估计与最大后验估计

(1)两种状态估计方法:

  • 增量/渐进式(滤波器):数据是随时间逐渐到来的;

  • 批量式:一次给定所有的数据,估计所有的变量。

(2)经典的 SLAM 模型由一个运动方程和一个观测方程组成

{ x k = f ( x k − 1 , u k ) + w k z k , j = h ( y j , x k ) + v k , j (5-1) \left\{\begin{array}{l} \boldsymbol{x}_{k}=f\left(\boldsymbol{x}_{k-1}, \boldsymbol{u}_{k}\right)+\boldsymbol{w}_{k} \\ \boldsymbol{z}_{k, j}=h\left(\boldsymbol{y}_{j}, \boldsymbol{x}_{k}\right)+\boldsymbol{v}_{k, j} \end{array}\right. \tag{5-1} {xk=f(xk1,uk)+wkzk,j=h(yj,xk)+vk,j(5-1)

定义所有时刻的机器人位姿和路标点坐标

x = { x 1 , … , x N } , y = { y 1 , … , y M } \boldsymbol{x}=\left\{\boldsymbol{x}_{1}, \ldots, \boldsymbol{x}_{N}\right\}, \quad \boldsymbol{y}=\left\{\boldsymbol{y}_{1}, \ldots, \boldsymbol{y}_{M}\right\} x={x1,,xN},y={y1,,yM}

u \boldsymbol{u} u 表示所有时刻的输入, z \boldsymbol{z} z 表示所有时刻的观测数据。在已知输入和观测数据的条件下,求机器人状态 x \boldsymbol{x} x y \boldsymbol{y} y 的概率分布,即

P ( x , y ∣ u , z ) P(\boldsymbol{x}, \boldsymbol{y}| \boldsymbol{u}, \boldsymbol{z}) P(x,yu,z)

根据贝叶斯法则,

P ( x , y ∣ z , u ) ⏟ 后验  = P ( z , u ∣ x , y ) P ( x , y ) P ( z , u ) ∝ P ( z , u ∣ x , y ) ⏟ 似然  P ( x , y ) ⏟ 先验  (5-2) \underbrace{P(\boldsymbol{x}, \boldsymbol{y} \mid \boldsymbol{z}, \boldsymbol{u})}_{\text {后验 }}=\frac{P(\boldsymbol{z}, \boldsymbol{u} \mid \boldsymbol{x}, \boldsymbol{y}) P(\boldsymbol{x}, \boldsymbol{y})}{P(\boldsymbol{z}, \boldsymbol{u})} \propto \underbrace{P(\boldsymbol{z}, \boldsymbol{u} \mid \boldsymbol{x}, \boldsymbol{y})}_{\text {似然 }} \underbrace{P(\boldsymbol{x}, \boldsymbol{y})}_{\text {先验 }} \tag{5-2} 后验  P(x,yz,u)=P(z,u)P(z,ux,y)P(x,y)似然  P(z,ux,y)先验  P(x,y)(5-2)

那么,求解最大后验概率等价于最大化似然概率和先验概率的乘积。但是,有时我们并不知道机器人位姿或路标大概在什么地方,也就不知道先验概率,上式就简化为求解最大似然概率

( x , y ) M L E ∗ = arg max ⁡ P ( z , u ∣ x , y ) (\boldsymbol{x}, \boldsymbol{y})^*_{MLE}=\argmax P(\boldsymbol{z}, \boldsymbol{u} \mid \boldsymbol{x}, \boldsymbol{y}) (x,y)MLE=argmaxP(z,ux,y)

直观地讲,似然是指“在现在的位姿下,可能产生怎样的观测数据”,但由于观测数据已知,则上式可理解为在什么样的状态下,最可能产生观测到的数据

5.2 最小二乘的引出

(1)在高斯分布的假设下,最大似然有较简单的形式。对于某一次观测

z k , j = h ( y j , x k ) + v k , j \boldsymbol{z}_{k, j}=h\left(\boldsymbol{y}_{j}, \boldsymbol{x}_{k}\right)+\boldsymbol{v}_{k, j} zk,j=h(yj,xk)+vk,j

其中噪声项满足 v k ∼ N ( 0 , Q k , j ) \boldsymbol{v}_{k} \sim \mathcal{N}\left(\mathbf{0}, \boldsymbol{Q}_{k, j}\right) vkN(0,Qk,j),所以观测数据的条件概率为

P ( z k , j ∣ y j , x k ) = N ( h ( y j , x k ) , Q k , j ) P(\boldsymbol{z}_{k, j}|\boldsymbol{y}_{j}, \boldsymbol{x}_{k})=N(h\left(\boldsymbol{y}_{j}, \boldsymbol{x}_{k}\right),\boldsymbol{Q}_{k, j}) P(zk,jyj,xk)=N(h(yj,xk),Qk,j)

依然满足高斯分布。

(2)对于任意维高斯分布 x ∼ N ( μ , Σ ) \boldsymbol{x} \sim \mathcal{N}\left(\boldsymbol{\mu}, \boldsymbol{\Sigma}\right) xN(μ,Σ),则其概率密度函数为

P ( x ) = 1 ( 2 π ) N det ⁡ ( Σ ) exp ⁡ ( − 1 2 ( x − μ ) T Σ − 1 ( x − μ ) ) (5-3) P(\boldsymbol{x})=\frac{1}{\sqrt{(2\pi)^N\det(\boldsymbol{\Sigma})}}\exp{(-\frac{1}{2}(\boldsymbol{x-\mu})^T\Sigma^{-1}(\boldsymbol{x-\mu}))} \tag{5-3} P(x)=(2π)Ndet(Σ) 1exp(21(xμ)TΣ1(xμ))(5-3)

其中, N N N 为向量 x \boldsymbol{x} x 的维度; det ⁡ ( Σ ) \det(\boldsymbol{\Sigma}) det(Σ) 表示求 Σ \boldsymbol{\Sigma} Σ 的行列式。

取其负对数,则变为

− ln ⁡ ( P ( x ) ) = 1 2 ln ⁡ ( ( 2 π ) N det ⁡ ( Σ ) ) + 1 2 ( x − μ ) T Σ − 1 ( x − μ ) (5-4) -\ln(P(\boldsymbol{x}))=\frac{1}{2}\ln((2\pi)^N\det(\boldsymbol{\Sigma}))+\frac{1}{2}(\boldsymbol{x-\mu})^T\Sigma^{-1}(\boldsymbol{x-\mu}) \tag{5-4} ln(P(x))=21ln((2π)Ndet(Σ))+21(xμ)TΣ1(xμ)(5-4)

对原函数求最大化相当于对负对数求最小化。显然与第一项无关,故只需考虑最小化右侧的二次型项,则

( x k , y j ) ∗ = arg ⁡ max ⁡ N ( h ( y j , x k ) , Q k , j ) = arg ⁡ min ⁡ ( ( z k , j − h ( x k , y j ) ) T Q k , j − 1 ( z k , j − h ( x k , y j ) ) ) (5-5) \begin{aligned} \left(\boldsymbol{x}_{k}, \boldsymbol{y}_{j}\right)^{*} &=\arg \max \mathcal{N}\left(h\left(\boldsymbol{y}_{j}, \boldsymbol{x}_{k}\right), \boldsymbol{Q}_{k, j}\right) \\ &=\arg \min \left(\left(\boldsymbol{z}_{k, j}-h\left(\boldsymbol{x}_{k}, \boldsymbol{y}_{j}\right)\right)^{\mathrm{T}} \boldsymbol{Q}_{k, j}^{-1}\left(\boldsymbol{z}_{k, j}-h\left(\boldsymbol{x}_{k}, \boldsymbol{y}_{j}\right)\right)\right) \end{aligned} \tag{5-5} (xk,yj)=argmaxN(h(yj,xk),Qk,j)=argmin((zk,jh(xk,yj))TQk,j1(zk,jh(xk,yj)))(5-5)

机器人状态 x \boldsymbol{x} x y \boldsymbol{y} y 等于使二次型项最小时的值。

(3)假设各个时刻的输入和观测都是相互独立的,那么,我们对似然概率进行因式分解,得

P ( z , u ∣ x , y ) = ∏ k P ( u k ∣ x k − 1 , x k ) ∏ k , j P ( z k , j ∣ x k , y j ) (5-6) P(\boldsymbol{z}, \boldsymbol{u} \mid \boldsymbol{x}, \boldsymbol{y})=\prod_{k} P\left(\boldsymbol{u}_{k} \mid \boldsymbol{x}_{k-1}, \boldsymbol{x}_{k}\right) \prod_{k, j} P\left(\boldsymbol{z}_{k, j} \mid \boldsymbol{x}_{k}, \boldsymbol{y}_{j}\right) \tag{5-6} P(z,ux,y)=kP(ukxk1,xk)k,jP(zk,jxk,yj)(5-6)

定义真实输入、观测数据与预测输入、观测数据之间的误差

e u , k = x k − f ( u k , x k − 1 ) \boldsymbol{e_u}_{, k}=\boldsymbol{x}_{k}-f(\boldsymbol{u}_k, \boldsymbol{x}_{k-1}) eu,k=xkf(uk,xk1)
e z , j , k = z k , j − h ( x k , y j ) (5-7) \boldsymbol{e_z}_{,j, k}=\boldsymbol{z}_{k, j}-h(\boldsymbol{x}_{k}, \boldsymbol{y}_{j}) \tag{5-7} ez,j,k=zk,jh(xk,yj)(5-7)

那么,式(5-5)可以转化为一个最小二乘问题,即

min ⁡ J ( x , y ) = ∑ k e u , k T R k − 1 e u , k + ∑ k ∑ j e z , k , j T Q k , j − 1 e z , k , j (5-8) \min J(\boldsymbol{x}, \boldsymbol{y})=\sum_{k} e_{\boldsymbol{u}, k}^{\mathrm{T}} \boldsymbol{R}_{k}^{-1} \boldsymbol{e}_{\boldsymbol{u}, k}+\sum_{k} \sum_{j} \boldsymbol{e}_{\boldsymbol{z}, k, j}^{\mathrm{T}} \boldsymbol{Q}_{k, j}^{-1} \boldsymbol{e}_{\boldsymbol{z}, k, j} \tag{5-8} minJ(x,y)=keu,kTRk1eu,k+kjez,k,jTQk,j1ez,k,j(5-8)

5.3 非线性最小二乘

非线性函数常常难以用求导法得到最值,而采用梯度下降法,即,通过不断迭代 x k + 1 = x k + Δ x k \boldsymbol{x}_{k+1}=\boldsymbol{x}_k+\Delta\boldsymbol{x}_k xk+1=xk+Δxk,使得 ∣ ∣ f ( x k + Δ x k ) ∣ ∣ 2 ||f(\boldsymbol{x}_k+\Delta\boldsymbol{x}_k)||^2 ∣∣f(xk+Δxk)2 达到极小值
,当 Δ x \Delta \boldsymbol{x} Δx 足够小时,即停止。关键在于增量 Δ x \Delta\boldsymbol{x} Δx 的选取。

过程如下:

——————————————————————————————————————————————————————

  • 给定某个初值 x 0 \boldsymbol{x}_0 x0

  • 对于第 k k k 次迭代,寻找增量 Δ x k \Delta\boldsymbol{x}_k Δxk

  • Δ x k \Delta \boldsymbol{x}_k Δxk 足够小时,即停止;否则,重复第二步,继续寻找。

——————————————————————————————————————————————————————

下面介绍几个常用的优化方法。

5.3.1 一阶和二阶梯度法

考虑最小二乘问题:

min ⁡ x F ( x ) = 1 2 ∥ f ( x ) ∥ 2 2 \min _{x} F(x)=\frac{1}{2}\|f(x)\|_{2}^{2} xminF(x)=21f(x)22

注意 F ( x ) F(\boldsymbol{x}) F(x) f ( x ) f(\boldsymbol{x}) f(x) 的区别(可以理解为 f ( x ) f(\boldsymbol{x}) f(x)为残差矩阵)。

参考:https://blog.csdn.net/u014709760/article/details/97576395

对于非线性函数 F ( x ) F(\boldsymbol{x}) F(x),考虑第 k k k 次迭代,将其在 x k \boldsymbol{x}_k xk 附近泰勒展开(将 Δ x k \Delta \boldsymbol{x}_k Δxk 看做未知数),

F ( x ) = F ( x k + Δ x k ) ≈ F ( x k ) + J ( x k ) T Δ x k + 1 2 Δ x k T H ( x k ) T Δ x k (5-9) F(\boldsymbol{x})=F(\boldsymbol{x}_k+\Delta \boldsymbol{x}_k) \approx F(\boldsymbol{x}_k)+\boldsymbol{J}(\boldsymbol{x}_k)^T\Delta \boldsymbol{x}_k+\frac{1}{2}\Delta \boldsymbol{x}_k^T\boldsymbol{H}(\boldsymbol{x}_k)^T\Delta \boldsymbol{x}_k \tag{5-9} F(x)=F(xk+Δxk)F(xk)+J(xk)TΔxk+21ΔxkTH(xk)TΔxk(5-9)

其中, J ( x k ) \boldsymbol{J}(\boldsymbol{x}_k) J(xk) F ( x ) F(\boldsymbol{x}) F(x) 关于 x \boldsymbol{x} x 的一阶导数, H ( x k ) \boldsymbol{H}(\boldsymbol{x}_k) H(xk) 是二阶导数。

(1)仅保留一阶导数时,取增量为反向梯度即可,即

Δ x ∗ = − J ( x k ) \Delta \boldsymbol{x}^*=-\boldsymbol{J}(\boldsymbol{x}_k) Δx=J(xk)

也被称为最速下降法

(2)保留二阶梯度信息。此时增量方程为

Δ x ∗ = arg ⁡ min ⁡ ( F ( x ) + J ( x ) T Δ x + 1 2 Δ x T H Δ x ) (5-10) \Delta \boldsymbol{x}^{*}=\arg \min \left(F(\boldsymbol{x})+\boldsymbol{J}(\boldsymbol{x})^{\mathrm{T}} \Delta \boldsymbol{x}+\frac{1}{2} \Delta \boldsymbol{x}^{\mathrm{T}} \boldsymbol{H} \Delta \boldsymbol{x}\right) \tag{5-10} Δx=argmin(F(x)+J(x)TΔx+21ΔxTHΔx)(5-10)

右侧各项分别为 Δ x \Delta \boldsymbol{x} Δx 的零次、一次和二次项,将其对 Δ x \Delta \boldsymbol{x} Δx 求导,并令其为零

J + H Δ x = 0 (5-11) \boldsymbol{J}+\boldsymbol{H} \Delta \boldsymbol{x}=0 \tag{5-11} J+HΔx=0(5-11)

求解这个方程,即得到增量。此方法也被称为牛顿法。但在实际中, H \boldsymbol{H} H 矩阵计算较为困难。

5.3.2 高斯牛顿法

f ( x ) f(\boldsymbol{x}) f(x) 一阶泰勒展开(注意不是 F ( x ) F(\boldsymbol{x}) F(x)):

f ( x + Δ x ) ≈ f ( x ) + J ( x ) T Δ x (5-12) f(\boldsymbol{x}+\Delta \boldsymbol{x}) \approx f(\boldsymbol{x})+\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x} \tag{5-12} f(x+Δx)f(x)+J(x)TΔx(5-12)
其中, J ( x ) \boldsymbol{J}(\boldsymbol{x}) J(x) f ( x ) f(\boldsymbol{x}) f(x) 关于 x \boldsymbol{x} x 的一阶导数,为 n × 1 n \times 1 n×1 列向量。

此时,我们的问题变为找到 Δ x \Delta \boldsymbol{x} Δx ,使得
1 2 ∥ f ( x ) + J ( x ) T Δ x ∥ 2 \frac{1}{2} \|f(\boldsymbol{x})+\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x}\|^2 21f(x)+J(x)TΔx2 最小。将其展开

1 2 ∥ f ( x ) + J ( x ) T Δ x ∥ 2 = 1 2 ( f ( x ) + J ( x ) T Δ x ) T ( f ( x ) + J ( x ) T Δ x ) = 1 2 ( ∥ f ( x ∥ 2 + 2 f ( x ) J ( x ) T Δ x + Δ x T J ( x ) J ( x ) T Δ x ) (5-13) \begin{aligned} \frac{1}{2} \|f(\boldsymbol{x})+\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x}\|^2&=\frac{1}{2} (f(\boldsymbol{x})+\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x})^T(f(\boldsymbol{x})+\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x}) \\ &=\frac{1}{2} (\|f(\boldsymbol{x}\|^2+2f(\boldsymbol{x})\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x}+\Delta \boldsymbol{x}^T\boldsymbol{J}(\boldsymbol{x})\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x}) \end{aligned} \tag{5-13} 21f(x)+J(x)TΔx2=21(f(x)+J(x)TΔx)T(f(x)+J(x)TΔx)=21(f(x2+2f(x)J(x)TΔx+ΔxTJ(x)J(x)TΔx)(5-13)

Δ x \Delta \boldsymbol{x} Δx 看做未知数,对其求导,并令其为零:

f ( x ) J ( x ) + J ( x ) J ( x ) T Δ x = 0 (5-14) f(\boldsymbol{x})\boldsymbol{J}(\boldsymbol{x})+\boldsymbol{J}(\boldsymbol{x})\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x}=\boldsymbol{0} \tag{5-14} f(x)J(x)+J(x)J(x)TΔx=0(5-14)

J ( x ) J T ⏟ H ( x ) ( x ) Δ x = − J ( x ) f ( x ) ⏟ g ( x ) (5-15) \underbrace{\boldsymbol{J}(\boldsymbol{x}) \boldsymbol{J}^{\mathrm{T}}}_{\boldsymbol{H}(\boldsymbol{x})}(\boldsymbol{x}) \Delta \boldsymbol{x}=\underbrace{-\boldsymbol{J}(\boldsymbol{x}) f(\boldsymbol{x})}_{\boldsymbol{g}(\boldsymbol{x})} \tag{5-15} H(x) J(x)JT(x)Δx=g(x) J(x)f(x)(5-15)

H ( x ) Δ x = g ( x ) (5-16) \boldsymbol{H}(\boldsymbol{x})\Delta \boldsymbol{x}=\boldsymbol{g}(\boldsymbol{x}) \tag{5-16} H(x)Δx=g(x)(5-16)

5.3.3 列文伯格-马夸尔特方法

以上方法都是用一阶或二阶泰勒展开式近似替代原函数,不可避免存在精度问题,因此我们定义一个指标 ρ \rho ρ 来描述近似的好坏程度:

ρ = f ( x + Δ x ) − f ( x ) J ( x ) T Δ x (5-17) \rho=\frac{f(\boldsymbol{x}+\boldsymbol{\Delta x})-f(\boldsymbol{x})}{\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x}} \tag{5-17} ρ=J(x)TΔxf(x+Δx)f(x)(5-17)

其中,分子是实际下降的值,分母是近似下降的值。若 ρ \rho ρ 接近于 1 ,则近似效果好;若 ρ \rho ρ 太小,则说明实际减小的值远小于近似减小的值,即近似效果较差,需缩小近似范围; 若 ρ \rho ρ 太大,则说明实际减小的值大于近似减小的值,则需放大近似范围。

基于此,提出一个改进的高斯牛顿法:

——————————————————————————————————————————————————————

  • 给定初始值 x 0 \boldsymbol{x_0} x0,以及初始优化半径 μ \mu μ

  • 对于第 k k k 次迭代,在高斯牛顿法的基础上加上信赖区域,求解:

min ⁡ Δ x k 1 2 ∥ f ( x k ) + J ( x k ) T Δ x k ∥ 2 , s.t.  ∥ D Δ x k ∥ 2 ⩽ μ (5-18) \min _{\Delta \boldsymbol{x}_{k}} \frac{1}{2}\left\|f\left(\boldsymbol{x}_{k}\right)+\boldsymbol{J}\left(\boldsymbol{x}_{k}\right)^{\mathrm{T}} \Delta \boldsymbol{x}_{k}\right\|^{2}, \quad \text { s.t. } \quad\left\|\boldsymbol{D} \Delta \boldsymbol{x}_{k}\right\|^{2} \leqslant \mu \tag{5-18} Δxkmin21 f(xk)+J(xk)TΔxk 2, s.t. DΔxk2μ(5-18)

其中 μ \mu μ 是信赖区域的半径, D \boldsymbol{D} D 是系数矩阵。

  • 计算 ρ \rho ρ

  • ρ > 3 4 \rho>\frac{3}{4} ρ>43(需放大近似范围),则设置 μ = 2 μ \mu=2\mu μ=2μ;若 ρ < 1 4 \rho<\frac{1}{4} ρ<41(需缩小近似范围),则设置 μ = 0.5 μ \mu=0.5\mu μ=0.5μ

  • ρ \rho ρ 在范围内,则认为近似效果好,令 x k + 1 = x k + Δ x k \boldsymbol{x}_{k+1}=\boldsymbol{x}_{k}+\Delta \boldsymbol{x}_{k} xk+1=xk+Δxk

  • Δ x k \Delta \boldsymbol{x}_{k} Δxk 足够小,则停止;否则返回第二步。

——————————————————————————————————————————————————————

对于式(5-18),构造拉格朗日函数

L ( Δ x k , λ ) = 1 2 ∥ f ( x k ) + J ( x k ) T Δ x k ∥ 2 + λ 2 ( ∥ D Δ x k ∥ 2 − μ ) (5-19) \mathcal{L}\left(\Delta \boldsymbol{x}_{k}, \lambda\right)=\frac{1}{2}\left\|f\left(\boldsymbol{x}_{k}\right)+\boldsymbol{J}\left(\boldsymbol{x}_{k}\right)^{\mathrm{T}} \Delta \boldsymbol{x}_{k}\right\|^{2}+\frac{\lambda}{2}\left(\left\|\boldsymbol{D} \Delta \boldsymbol{x}_{k}\right\|^{2}-\mu\right) \tag{5-19} L(Δxk,λ)=21 f(xk)+J(xk)TΔxk 2+2λ(DΔxk2μ)(5-19)

Δ x \Delta \boldsymbol{x} Δx 求导,并令等于零,得

( H + λ D T D ) Δ x = g (5-20) (\boldsymbol{H}+\lambda\boldsymbol{D}^T\boldsymbol{D})\Delta \boldsymbol{x}=\boldsymbol{g} \tag{5-20} (H+λDTD)Δx=g(5-20)

这里的 H \boldsymbol{H} H g \boldsymbol{g} g 与高斯牛顿法中的 H \boldsymbol{H} H g \boldsymbol{g} g含义相同。

若将 D \boldsymbol{D} D 简化的看做为 I \boldsymbol{I} I,则上式变为

( H + λ I ) Δ x = g (5-21) (\boldsymbol{H}+\lambda\boldsymbol{I})\Delta \boldsymbol{x}=\boldsymbol{g} \tag{5-21} (H+λI)Δx=g(5-21)

可以看出,当 λ \lambda λ 较小时, H \boldsymbol{H} H 占主导地位,说明该范围内二次近似模型表现较好,此时,该方法更接近于高斯牛顿法;当 λ \lambda λ 较大时, λ I \lambda \boldsymbol{I} λI 占主导地位,此时,该方法更接近于一阶梯度法。

5.4 实践:曲线拟合问题

相关文章:

  • 03【远程协作开发、TortoiseGit、IDEA绑定Git插件的使用】
  • Banana Pi BPI-P2 Pro Rockchip RK3308开发板启动及设置
  • Huggingface网页解析和下载爬虫
  • 2023年【安全员-B证】新版试题及安全员-B证免费试题
  • 新的LLM 评价方法优化
  • [Hive] INSERT OVERWRITE DIRECTORY要注意的问题
  • 网站引流绝技:如何通过外链持续给网站带来高质量流量
  • 算法--数据结构
  • 如何卸载在linux下通过rpm安装的mysql
  • 常用的三角函数公式
  • 国产小体积超低成本电动车仪表智能刷卡解锁13.56M非接触式读写芯片CI522兼容替代RC522
  • URI 和 URL 的区别
  • 收银系统怎么选,网页版还是安装版好?
  • 大数据毕业设计选题推荐-河长制大数据监测平台-Hadoop-Spark-Hive
  • 普洱茶上市?澜沧古茶通过港股聆讯
  • [iOS]Core Data浅析一 -- 启用Core Data
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • 2019.2.20 c++ 知识梳理
  • echarts的各种常用效果展示
  • Iterator 和 for...of 循环
  • JAVA 学习IO流
  • Just for fun——迅速写完快速排序
  • Magento 1.x 中文订单打印乱码
  • Mysql5.6主从复制
  • OSS Web直传 (文件图片)
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • spring学习第二天
  • ucore操作系统实验笔记 - 重新理解中断
  • Wamp集成环境 添加PHP的新版本
  • 开源SQL-on-Hadoop系统一览
  • 如何在GitHub上创建个人博客
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 用mpvue开发微信小程序
  • 鱼骨图 - 如何绘制?
  • 2017年360最后一道编程题
  • ionic入门之数据绑定显示-1
  • Salesforce和SAP Netweaver里数据库表的元数据设计
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • "无招胜有招"nbsp;史上最全的互…
  • (js)循环条件满足时终止循环
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • (原創) 物件導向與老子思想 (OO)
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .Net7 环境安装配置
  • .NET框架设计—常被忽视的C#设计技巧
  • .sh 的运行
  • @Transactional 详解
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • []FET-430SIM508 研究日志 11.3.31
  • [<MySQL优化总结>]
  • [2023年]-hadoop面试真题(一)
  • [C语言]——C语言常见概念(1)
  • [error] 17755#0: *58522 readv() failed (104: Connection reset by peer) while reading upstream
  • [ffmpeg] x264 配置参数解析