2023年4月

本文将主要围绕范数的经典问题进行推导、分析,由于笔者的数理基础浅薄,下面的证明过程若存在错误,欢迎评论指正。

LASSO问题

推导

​ 问题定义:
\(\underset{x}{\min}||y-X\beta||_2^2+\tau||\beta||_\mathcal{A}\)

​ 问题推导:

​ 0、上述问题是典型的无约束问题,可以通过
变量替换
的思想进行处理。

​ 1、令
\(z=X\beta\)
,上述问题更新为
\(g(u)=\min_{\beta,z}=\frac{1}{2}\Vert y-z\Vert_2^2+\lambda\Vert\beta\Vert_1+u^T(z-X\beta)\)
.

​ 2、可以观察到
\(g(u)\)
中关于
\(\beta\)

\(z\)
的元素项不存在耦合关系,因此可进步将
\(g(u)\)
问题拆解为独立的最小项
\(g(\beta)\)

\(g(z)\)
,其中
\(g(\beta)=\min_\beta~\lambda\Vert\beta\Vert_1-u^TX\beta\)
,
\(g(z)=\min_\beta~\frac{1}{2} \Vert y-z\Vert_2^2+u^Tz\)

​ 3、
\(g(\beta)=\min_\beta~\lambda\Vert\beta\Vert_1-u^TX\beta=-\max_\beta~\lambda(-\Vert\beta\Vert_1+\frac{u^TX\beta}{\lambda})=-\lambda~g^*(\frac{X^Tu}{\lambda})=-\lambda I_{\{v_i|\Vert v\Vert_\infty \leq1\}}(\frac{X^Tu}{\lambda})\)
,这个最小项可以表征为示性函数形式,示性函数
\(f^*(y)=\begin{cases}0&||y||_*\leq1\\ \infty&\text{otherwise}\end{cases}=I_{\{z:||z||_*\leq1\}}(y)\)
.

​ 4、对
\(g(z)\)
求极值,可以得到
\(-(y-z)+u=0\)
,即
\(z=y-u\)
.

​ 5、将上述约束代入
\(g(z)\)
,可以得到下式:


\(g(z)=\frac{1}{2}\Vert u\Vert^2_2+u^T(y-u)=u^Ty-\frac{1}{2}\Vert u\Vert_2^2=-\frac{1}{2}[\Vert y\Vert_2^2+\Vert u\Vert_2^2-2u^Ty]+\frac{1}{2}\Vert y\Vert_2^2=-\frac{1}{2}\Vert y-u\Vert_2^2+\frac{1}{2} \Vert y\Vert_2^2\)

​ 那么对偶问题可以表示为如下形式:


\(\max_u -\frac{1}{2}\Vert y-u\Vert_2^2+\frac{1}{2} \Vert y\Vert_2^2 ~s.t.X^Tu\leq\lambda\)

原子范数对偶问题

推导

​ 有噪声情况下,原子范数的原问题可以抽象为:
\(\operatorname*{min}_{x}\|x\|_{\mathcal{A}}\mathrm{subject~to}\left\{\begin{array}{l}{{\mathbf{y}={\mathcal{F}}_{M}x+\mathbf{n},}}\\ {{\|\mathbf{n}\|_{2}\leq\epsilon.}}\end{array}\right.\)

​ 对偶函数可以写为
\(g(x,u)\)

\(C\)
上的下确界,即
\(g(\mathbf{c},\xi)=\inf~L(x,\mathbf{c},\xi)\)

​ 下面对原问题的对偶问题进行推导:

​ 1、原问题的增广拉格朗日目标函数可以表示为:
\(L(x,\mathbf{c},\xi)=\|x\|_{\mathcal{A}}+\mathrm{Re}\left[\mathbf{c}^{H}\left(\mathbf{y}-\mathcal{F}_{M}x-\mathbf{n}\right)\right]+\xi\left(\mathbf{n}^{H}\mathbf{n}-\epsilon^{2}\right)\)

将拉格朗日方程进行重写,
\(\inf~L(x,\mathbf{c},\xi)=\mathrm{Re}[c^Hy-c^Hn]+\xi[n^Hn-\epsilon^2]+\inf[\Vert x\Vert_A-\mathrm{Re}[\lambda^HF_Mx]]\\\)

​ 2、下确界的求解是关于
\(x\)
的最小化,因此对原拉格朗日增广函数的最小化可以转换为对
\([\Vert x\Vert_A-\mathrm{Re}[\lambda^HF_Mx]]\)
求下确界。在求这项下确界时,需要对式中的噪声功率参数
\(n\)
和对偶变量
\(\xi\)
求偏导寻找极值点。

​ 当对噪声功率参数
\(n\)
求偏导时[
目的是为了使噪声功率最小化
],有
\(\frac{\partial g(\mathbf{c},\xi)}{\partial c}=-c+2\xi n=0\)
,可以得到最佳极值点
\(n_o=\frac{c}{2\xi}\)
,此时对应的对偶函数为
\(\begin{array}{c}g(\mathbf{c},\xi)|_{\mathbf{n_\circ}}=\mathrm{Re}\left[\mathbf{c}^{H}\mathbf{y}\right]-\dfrac{\mathbf{c}^{H}\mathbf{c}}{2\xi}+\xi\left(\dfrac{\mathbf{c}^{H}\mathbf{c}}{4\xi^{2}}-\epsilon^{2}\right)+\+\inf_{x}\left(\|x\|_{\mathcal{A}}-\mathrm{Re}\left[\mathbf{c}^{H}\mathcal{F}_{M}x\right]\right).\end{array}\)

​ 当对对偶变量
\(\xi\)
求偏导时,有
\(\frac{\partial g(\mathbf{c},\xi)_{n_o}}{\partial \xi}=\frac{c^Hc}{4\xi^2}-\epsilon^2=0\)
,可以得到最佳极值点
\(\xi_0=\frac{\Vert c\Vert}{2\epsilon}\)
.

​ 最后,基于最优极值点对偶函数可以表示为
\(g(c)|_{n_o,\xi_o}=\mathrm{Re}[c^Hy-\epsilon\Vert c\Vert_2+\inf_x(\Vert x\Vert_A-\mathrm{Re}[c^H\mathcal{F}_{M}]x)]\)
.

​ 对于下确界项,对每个
\(x_i\)
,有
\(\mathrm{Re}[(c^H\mathcal{F}_{M})_ix_i]=\mathrm{Re}[(\mathcal{F}_{M}^Hc)^H_ix_i]=|(\mathcal{F}_{M}^Hc)_i||x_i|\cos\phi_i\)

\(\phi_i\)
表示
\(x_i\)

\({F}_{M}^Hc\)
间的角度,基于此可以得到以下结论:
\(\begin{array}{c}|x_i|-\mathrm{Re}\left[\left(\mathcal{F}_M^H\mathbf{c}\right)_i^Hx_i\right]=|x_i|\left[1-|\left(\mathcal{F}_M^H\mathbf{c}\right)_i|\cos\phi_i\right]\geq|x_i|\left[1-|\left(\mathcal{F}_M^H\mathbf{c}\right)_i|\right].\end{array}\)

​ 当
\(|\mathcal{F}_{M}^Hc|\leq1\)
时下确界项为0;当
\(|x_i|\left[1-|\left(\mathcal{F}_M^H\mathbf{c}\right)_i|\right]<0\)
时下确界可以达到
\(-\infty\)

​ 3、整理上述讨论,有噪声下的原子范数的对偶问题可以表征为:


\(g(\mathbf{c})=\left\{\begin{array}{lcl}\operatorname{Re}\left[\mathbf{c}^H\mathbf{y}-\epsilon\Vert c\Vert_2\right],&\|\mathcal{F}_M^H\mathbf{c}\|_{\infty}\leq1\\ -\infty,&\quad\mathrm{otherwise.}\end{array}\right.\)

​ 在上式中,
\(\mathcal{F}_M^H\mathbf{c}\)

\(\mathcal{F}_M^H\)
表示逆FFT算子,对偶多项式可以表示为
\(H(z)=\mathcal{F}_M^H\mathbf{c}=\sum\limits_{m=0}^{M-1}c_m z^m=\sum\limits_{m=0}^{M-1}c_m e^{-j\left(2\pi\frac{d}{\lambda}t\right)m}\)
,其中
\(z(t)=e^{-j\left(2\pi\frac{d}{\lambda}t\right)}\)
.

​ 4、为了进一步抽象
\(g(\mathbf{c})\)
,我们可以作以下表示:

​ 令
\(a(\omega)=[1,e^{j\omega},...,e^{j\omega(L-1)}]^T\)

\(L-1\)
次的三角多项式向量,那么因果三角多项式可以表征为:
\(H(\omega)=\sum_{l=0}^{L-1}h_l e^{-j\omega l}=\mathbf{a}(\omega)^H\mathbf{h}\)
,其中
\(\textbf{h}=\left[h_0,\cdots,h_{L-1}\right]^T\in\mathbb{C}^L\)
表示多项式系数向量.

​ 对于非负三角多项式,可以有Hermitian矩阵
\(R(\omega)=|H(\omega)|^2=H(\omega)H(\omega)^H=a(\omega)^Hhh^Ha(\omega)=\sum_{k=-(L-1)}^{L-1}r_k e^{-j\omega k}\)
,其中
\(r_k=\sum_{l=0}^{L-1-k}h_l h_{l+k}^*\)

\(k\geq0\)
并且
\(r_{-k}=r_k^*\)
,稀疏
\(r_k\)
可以通过自相关矩阵
\(Q_{L\times L}=hh^H\)
的第
\(k\)
条对角线元素进行计算
\(r_k=\sum_{i=1}^{L-k}Q_{i,i+k}\)
.

​ 令两个多项式
\(H(\omega)\)

\(B(\omega)\)
满足以下不等关系:
\(|H(\omega)|\leq|B(\omega)|,\forall\omega\in[-\pi,\pi]\)

​ 这意味着
\(|H(\omega)|^2\leq|B(\omega)|^2,\forall\omega\in[-\pi,\pi]\)
,定义
\(R_H(\omega)=|H(\omega)|^2\)

\(R_B(\omega)=|B(\omega)|^2\)
,那么有
\(R_H(\omega)\leq R_B(\omega)\)
,即
\(Q_H \leq Q_B\)
,其中
\(Q_H=hh^H\)

\(Q_B=bb^H\)
为自相关向量
\(\mathbf{h}=[h_{0},\cdots,h_{L-1}]^{T}\)

\(\mathbf{b}=[b_{0},\cdots,b_{L-1}]^{T}\)
的自相关矩阵.


根据Schur补条件有
\(Q_B-hh^H\geq0\)
,即
\(\begin{bmatrix}\mathbf{Q}_B&\mathbf{h}_{L\times1}\\ \mathbf{h}_{1\times L}^{H}&1\end{bmatrix}\succeq0.\)

​ 令多项式
\(H(\omega)\)
的振幅均匀有界(对所有
\(\omega\in[-\pi,\pi]\)

\(H(\omega)\leq\gamma\)
,其中
\(\gamma \in R_+\)
为给定正实数.作为有界三角多项式的特例,令
\(|B(\omega)|=\gamma\)
,那么
\(H(\omega)\leq\gamma\)
可以用两个线性不等式抽象,如下:(其中
\(R_B(\omega)=\gamma^2\)
)


\(\begin{bmatrix}\mathbf{Q}_{L\times L}&\mathbf{h}_{L\times1}\\ \mathbf{h}_{1\times L}&1\end{bmatrix}\succeq0,\\ \sum_{i=1}^{L-j}Q_{i,i+j}=\left\{\begin{array}{c}\gamma^2,&j=0\\ 0,&j=1,\cdots,L-1.\end{array}\right.\)


有界三角多项式的结果可以用于
\(\infty\)
范数,因为多项式的最大振幅设置上界意味着多项式对所有
\(\omega\in[-\pi,\pi]\)
具有一致有界的振幅,


\(\begin{array}{l}\|H\|_{\infty}=\max\limits_{\omega\in[-\pi,\pi]}|H(\omega)|\leq\gamma,\\ |H(\omega)|\leq\gamma,\forall\omega\in[-\pi,\pi].\end{array}\)

​ 回到本节开始处,基于振幅一致有界条件和Schur补条件,
对偶问题可以表征为以下凸优化问题


\(\begin{array}{c}\max\operatorname{Re}\left(\mathbf{c}^{H}\mathbf{y}-\epsilon\Vert c\Vert_2\right)~~\operatorname{subject to}\left[\begin{array}{cc}\mathbf{Q}_{M\times M}&\mathbf{c}_{M\times1}\\ \mathbf{c}_{1\times M}&1\end{array}\right]\succeq0,\\ \sum_{i=1}^{M-j}\mathbf{Q}_{i,i+j}=\left\{\begin{array}{cc}1,&j=0\\ 0,&j=1,\cdots,M-1.\end{array}\right.\end{array}\)

代码

% 本处仅给出上述凸优化问题的核心代码
if noise_flag == 0 % 无噪声版本
    cvx_begin sdp quiet
    cvx_solver sdpt3
        variable S(M+1,M+1) hermitian 
        subject to
        S >= 0;
        S(M+1,M+1) == 1;
        trace(S) == 2; % 主对角元素迹为2
        for j = 1 : M-1
            sum(diag(S,j)) == S(M+1-j,M+1); % 非主对角线元素求和为0.
        end
        maximize (real(S(1:M,M+1)'* Y)) %  - 0.5 * norm(c)
    cvx_end
else % noise version
    regular_param = 0.2; % 有噪声需要引入正则化参数
    cvx_begin sdp quiet
    cvx_solver sdpt3
        variable S(M+1,M+1) hermitian
        subject to
        S >= 0;
        S(M+1,M+1) == 1;
        trace(S) == 2;
        for j = 1 : M - 1
            sum(diag(S,j)) == S(M+1-j,M+1);
        end
         maximize (real(S(1:M,M+1)'* Y) - regular_param * norm(c));
    cvx_end
end

原子范数软阈值问题的推导

推导

​ 原子集合由各个正弦曲线的样本组成,
\(a_{f,\phi}\in C^n\)
,表示为
\(a_{f,\phi}=e^{i2\pi\phi}\left[1~e^{i2\pi f}~\cdots e^{i2\pi(n-1)f}\right]^T\)

​ 无限原子集
\(\mathcal{A}=\{a_{f,\phi}:f\in[0,1],\phi\in[0,1]\}\)
组成了
\(x^*\)
适当的原子集合,
\(x^*\)
在对偶问题中可以写成一个稀疏的非负的原子组合。
\(x^\star=\sum_{l=1}^k c_l^\star a_{f_l^\star,0}=\sum_{l=1}^k|c_l^\star|a_{f_l^\star,\phi_l}\)

\(c_{l}^{\star}=|c_{l}^{\star}|e^{i2\pi\phi_{l}}\)
.

​ 相应的对偶范数采用直观的形式:
\(\|v\|_\mathcal{A}^*=\sup\limits_{f,\phi}\langle v,a_{f,\phi}\rangle=\sup\limits_{f\in[0,1]}\sup\limits_{\phi\in[0,1]}e^{i2\pi\phi}\sum\limits_{l=0}^{n-1}v_l e^{-2\pi i l f}=\sup\limits_{|z|\le1}\left|\sum\limits_{l=0}^{n-1}v_l z^l\right|\)

\(\|v\|_\mathcal{A}^*\)
可以理解为在单位圆上获得的最大绝对值
\(\zeta\mapsto\sum_{l=0}^{n-1}v_l{\zeta^l}\)
,
\({\cal A}=\{a_{f,\phi}|f\in[0,1],\phi\in[0,1]\}\)
为与线谱原子集相关的原子范数的半正定规划.

​ 根据上式可知向量
\(v\in C^n\)
的对偶原子范数是复数三角多项式
\(V(f)=\sum_{l=0}^{n-1}v_l e^{j2\pi lf}\)
的最大绝对值;因此,对对偶原子范数的约束等价于对
\(V(f)\)
大小的限制:
\(||v||_A^\text{t}\leq\tau\Leftrightarrow|V(f)|^2\leq\tau^2,\forall f\in[0,1]\)
.函数
\(q(f)=\tau^{2}-|V(f)|^{2}\)
是一个三角多项式,
\(q(f)\)
非负的充要条件是可以写成三角多项式的平方和.

​ 定义映射
\(T:\mathbb{C}^{n}\to\mathbb{C}^{n\times n}\)
,从输入创建一个Hermitian Toeplitz 矩阵,即
\(T(x)=\begin{bmatrix}x_1&&x_2&&...&&x_n\\ x_2^*&&x_1&&...&&x_{n-1}\\ \vdots&&\vdots&&\ddots&&\vdots\\ x_n^*&&x_{n-1}^*&&...&&x_1\end{bmatrix}\)
.

​ 对于给定的因果三角多项式
\(V(f)=\sum_{l=0}^{n-1}v_{l}e^{-2\pi i l f},\)
如果有且仅有复Hermitian矩阵
\(Q\)
存在时有
\(|V(f)|\leq\tau\)
,这与原子范数对偶问题中第4节证明类似,即有
\(T^*(Q)=\tau^2e_1~\mathrm{and}~\begin{bmatrix}Q&v\\ v^*&1\end{bmatrix}\succeq0.\)
其中
\(e_1=[1,0,0,....,0]^T\)

\(v^*\)
表示
\(v\)
的Hermitian转置.


重写原子范数
\(\Vert x \Vert_A=\sup_{\|v\|_\mathcal{A}^*\leq1}<x,v>\)
为下列形式:


\(\begin{array}{ll}\text{maximize}_{v,Q}&\langle x,v\rangle\\ \text{subject to}&T^*(Q)=e_1\\ &\begin{bmatrix}Q&v\\ v^*&1\end{bmatrix}\succeq0.\end{array}\)

​ 下面对上述问题进行对偶推导:

​ 1、首先需要将上述问题转化为无约束的拉格朗日方程形式,可以表示如下:

​ $L(Q,v,u,\Gamma)=\langle x,v\rangle +\langle u, T^* (Q)\rangle-\langle u,e_1\rangle-\langle\Gamma, \begin{bmatrix}Q&v\ v^*&1\end{bmatrix}\rangle $

​ 2、关于
\(v\)
的项为$\langle x,v\rangle-\langle\Gamma, \begin{bmatrix}Q&v\ v^*&1\end{bmatrix}\rangle
\(,下面对变量\)
v$求解极值,则有


\(x- Tr(\Gamma\begin{bmatrix}0&I\\ I^*&0\end{bmatrix})=x- Tr(\begin{bmatrix}\Gamma_{12}I^*&\Gamma_{11}I\\ \Gamma_{22}I^*&\Gamma_{21}I\end{bmatrix})=x-2\Gamma_{12}=0\)
,那么可以得到
\(\Gamma_{12}=\frac{x}{2};\)
\(\Gamma_{21}=\frac{x^*}{2}\)

​ 3、关于
\(Q\)
的项为
\(\langle u, T^* (Q)\rangle-\langle\Gamma, \begin{bmatrix}Q&v\\ v^*&1\end{bmatrix}\rangle\)
,对变量
\(Q\)
求解极值前,先将
\(\langle u, T^* (Q)\rangle\)
进步抽象为
\(Tr(T(u)\cdot Q)\)
,那么关于
\(Q\)
的偏导可表示为
\(T(u)-\langle\Gamma,\begin{bmatrix}I&0\\ 0&0\end{bmatrix}\rangle=0\)
,那么则有
\(\Gamma_{11}=T(u)\)
,其中
\(F_{22}=t\)
,用于半正定约束
\(\Gamma=\begin{bmatrix}T(u)&x/2\\ x^*/2&t\end{bmatrix}\geq0\)
.

​ 4、将
\(\Gamma\)
结果代入到
\(L\)
中,那么有如下证明:


\(L=Re(v^*x)+Tr(T(u)\cdot Q)-u^*e_1-Tr(\begin{bmatrix}T(u)Q+Re(v^*x)/2&x/2+T(u)v\\ tv^*+Re(Qx^*)/2&Re(x^*v)/2+t\end{bmatrix} ) =-u^*e_1-t=-u_1-t\)
.

​ 根据半正定约束条件
\(T(u)t-xx^*/4\geq0\)
,通过对
\(u\)

\(t\)
缩放则有
\(2t\cdot T(2u)-xx^*\geq0\)

​ 这等价于将对应目标函数缩放为
\(-u_1/2-t/2\)
,那么原问题的对偶形式可以表示如下:


\(\begin{array}{l l}{{\mathrm{minimize}_{t,u}}}&{{\frac{1}{2}(t+u_{1})}}\\ {{\mathrm{subject~to}}}&{{\begin{bmatrix}{T(u)}&{x}\\ {x^{*}}&{t}\end{bmatrix}\succeq0.}}\end{array}\)

​ 那么对应有噪声版本下的原问题对偶函数可以表示如下:[
\(\tau\)
表示正则参数]


\(\begin{array}{ll}\text{minimize}_{t,u,x}&\frac{1}{2}\|x-y\|_2^2+\frac{\tau}{2}(t+u_1)\\ \text{subject to}&\begin{bmatrix}T(u)&x\\ x^*&t\end{bmatrix}\succeq0.\end{array}\)


上述问题可以通过凸优化中的SDP解释器求解,但是计算复杂度较高,可以通过交替方向投影算子加速求解,这将在后续的章节进一步讨论。

代码

% 在上述推导过程中讨论了单快拍下有噪声和无噪声版本的原子范数模型
% 在本代码中笔者给出了单快拍和多快拍版本,后续将补充多快拍版本的理论
if noise_flag == 0 % 无噪声情况下的原子范数AST模型
    if snap == 1 % 单快拍模型
        cvx_begin sdp quiet
        cvx_solver sdpt3
            variable T(M, M) hermitian toeplitz
            variable x
            minimize (0.5 * x + 0.5 * T(1,1))
            [x Y'; Y T] >= 0;
        cvx_end
        [Phi, Val] = rootmusic(T, P, 'corr');
        Phis = Phi / 2 / pi ;
        estimated_theta = asind(-Phis * lambda / d);
    else % 多快拍模型
        cvx_begin sdp quiet
        cvx_solver sdpt3
            variable T(M, M) hermitian toeplitz
            variable X(snap, snap) hermitian
            minimize (trace(X)+trace(T))
            [X Y'; Y T] >= 0;
        cvx_end   
        [Phi, Val] = rootmusic(T, P, 'corr');
        Phis = Phi / 2 / pi ;
        estimated_theta = asind(-Phis * lambda / d);
    end
    
else % 有噪声情况下的原子范数AST模型
    if snap == 1 % 单快拍模型
        sigma = 1;
        regular_param = sqrt(M * log(M * sigma));
        cvx_begin sdp quiet
        cvx_solver sdpt3
            variable T(M, M) hermitian toeplitz
            variable x
            variable z(M,1) complex
            minimize (regular_param * 0.5 *(x + T(1,1)) + 0.5 * norm(Y-z))
            [x Y'; Y T] >= 0;
        cvx_end
        [Phi, Val] = rootmusic(T, P, 'corr');
        Phis = Phi / 2 / pi ;
        estimated_theta = asind(-Phis * lambda / d);
        
    else % 多快拍模型
        regular_param = sqrt(M * (snap + log(M) + sqrt(2 * snap * log(M))));
        cvx_begin sdp quiet
        cvx_solver sdpt3
            variable T(M,M) hermitian toeplitz
            variable X(snap, snap) hermitian
            variable Z(M, snap) complex
            minimize (regular_param * (trace(X) + trace(T)) + 1 / 2 * sum_square_abs(vec(Y - Z)));
            [X Y';Y T] >= 0;
        cvx_end
        [Phi, Val] = rootmusic(T, P, 'corr');
        Phis = Phi / 2 / pi ;
        estimated_theta = asind(-Phis * lambda / d);
    end
end

交替方向投影算子

原子范数软阈值AST推导

​ 在上一节中,有噪声版本下的原子范数软阈值问题可以表示为:


\(\begin{array}{ll}\text{minimize}_{t,u,x,Z}&\frac{1}{2}\|x-y\|_2^2+\frac{\tau}{2}(t+u_1)\\ \text{subject to}&Z=\begin{bmatrix}T(u)&x\\ x^*&t\end{bmatrix}\\ &Z\succeq0.\end{array}\)

​ 这里不作交替方向投影算子的具体介绍,其主要思想为将大问题拆解为若干子问题进行迭代求解,下面给出具体的变量迭代过程:

​ 1、首先需要将上述有约束条件的原问题表述为增广拉格朗日方程形式,如下所示:


\(\begin{array}{c}\mathcal{L}_\rho(t,u,x,Z,\Lambda)=\dfrac{1}{2}\|x-y\|_2^2+\dfrac{\tau}{2}(t+u_1)+\left\langle\Lambda,Z-\begin{bmatrix}T(u)&x\\ x^*&t\end{bmatrix}\right\rangle+\dfrac{\rho}{2}\left\|Z-\begin{bmatrix}T(u)&x\\ x^*&t\end{bmatrix}\right\|_F^2\end{array}\)

​ 其中,
\(\Lambda^l=\begin{bmatrix}\Lambda_{0}^l&\lambda_{1}^l\\ \lambda_{1}^{l*} & \Lambda_{n+1,n+1}^l\end{bmatrix}\)

\(Z^l=\begin{bmatrix}Z_{0}^l&z_{1}^l\\ z_{1}^{l*} & Z_{n+1,n+1}^l\end{bmatrix}\)

​ 2、下面依次对变量
\(x\)
,
\(t\)
,
\(u\)
依次迭代更新:

​ 2.1 首先提取关于
\(x\)
项的表达式,
\(\dfrac{1}{2}\|x-y\|_2^2+\left\langle\Lambda,Z-\begin{bmatrix}T(u)&x\\ x^*&t\end{bmatrix}\right\rangle+\dfrac{\rho}{2}\left\|Z-\begin{bmatrix}T(u)&x\\ x^*&t\end{bmatrix}\right\|_F^2\)

​ 其偏导为
\(-2\lambda_1^l+2\rho(x-z_1^l)+x-y=0,\)
那么有
\(x^{l+1}=\frac{y+2\lambda_1^l+2\rho z_1^l}{1+2\rho}\)
.

​ 2.2 其次提取关于
\(t\)
项的表达式,
\(\dfrac{\tau}{2}(t+u_1)+\left\langle\Lambda,Z-\begin{bmatrix}T(u)&x\\ x^*&t\end{bmatrix}\right\rangle+\dfrac{\rho}{2}\left\|Z-\begin{bmatrix}T(u)&x\\ x^*&t\end{bmatrix}\right\|_F^2\)

​ 其偏导为
\(\frac{\tau}{2}-\Lambda_{n+1,n+1}^l+\rho t-\rho Z_{n+1,n+1}^l=0\)
,那么有
\(t^{l+1}=\frac{1}{\rho}(\rho Z_{n+1,n+1}{l}+\Lambda_{n+1,n+1}^l-\tau/2)\)
.

​ 2.3 其次提取关于
\(u\)
项的表达式,
\(\dfrac{\tau}{2}(t+u_1)+\left\langle\Lambda,Z-\begin{bmatrix}T(u)&x\\ x^*&t\end{bmatrix}\right\rangle+\dfrac{\rho}{2}\left\|Z-\begin{bmatrix}T(u)&x\\ x^*&t\end{bmatrix}\right\|_F^2\)

​ 其偏导为
\(\frac{\tau}{2}e_1-\Lambda_0^l+\rho(T(u)-\Z_0^l)=0\)
,那么有
\(u^{l+1}=W\left(T^*(Z_0^l+\Lambda_0^l/\rho)-\dfrac{\tau}{2\rho}e_1\right)\)
,对角矩阵
\(W\)
满足关系
\(W_{ii}=\begin{cases}\frac{1}{n}&i=1\\ \frac{1}{2(n-i+1)}&i>1\end{cases}\)

\(T^*(\cdot)\)
表示生成共轭转置向量.

​ 2.4 其次提取关于
\(Z\)
项的表达式,
\(\left\langle\Lambda,Z-\begin{bmatrix}T(u)&x\\ x^*&t\end{bmatrix}\right\rangle+\dfrac{\rho}{2}\left\|Z-\begin{bmatrix}T(u)&x\\ x^*&t\end{bmatrix}\right\|_F^2\)

​ 其可进步表示为
\(\dfrac{\rho}{2}\left\|Z-\begin{bmatrix}T(u)&x\\ x^*&t\end{bmatrix}+\rho^{-1}\Lambda\right\|_F^2+Const\)
,当且仅当
\(Z=\begin{bmatrix}T(u)&x\\ x^*&t\end{bmatrix}+\rho^{-1}\Lambda\)
时有最小值.

​ 因此
\(Z^{l+1}=\begin{bmatrix}T(u^{l+1})&x^{l+1}\\ (x^{l+1})^*&t^{l+1}\end{bmatrix}+\rho^{-1}\Lambda^{l}\)

​ 2.5 最后,更新拉格朗日乘子项
\(\Lambda^{l+1}=\Lambda^{l}+\rho(Z^{l+1}-\begin{bmatrix}T(u^{l+1})&x^{l+1}\\ (x^{l+1})^*&t^{l+1}\end{bmatrix})\)

参考文献

[1] Atomic norm denoising with applications to line spectral estimation.
https://arxiv.org/abs/1204.0562

[2] Grid-free compressive beamforming.
https://arxiv.org/abs/1504.01662

[3] Positive Trigonometric Polynomials and Signal Processing Applications.

前言

PRINCE2,即 PRoject IN Controlled Environment(受控环境中的项目)是一种结构化的项目管理方法论,由英国政府内阁商务部(OGC)推出,是英国项目管理标准。

PRINCE2 作为一种开放的方法论,是一套结构化的项目管理流程,描述了如何以一种逻辑性的、有组织的方法,按照明确的步骤且基于商业论证对项目进行管理。

如果组织选择 PRINCE2 作为项目管理的标准,就可以在商业变革、组织结构、信息技术、重组与并购、研究、产品开发等多种商业活动领域,极大地提升组织的能力与成熟度。

(一)项目

项目是按照一个被批准的商业论证,为了交付一个或多个商业产品而创建的一个临时性组织。

● 被批准的商业论证。强调了项目是商业环境下被论证的,并且是有投资价值的。
● 交付一个或多个商品。 项目的目标是交付商业产品
○ 商业产品(商业环境中的产品)
○ 收益
■ 财务收益、非财务收益
■ 主收益、副收益
■ 正收益、负收益
■ 短期收益、长期收益

● 临时性组织。 强调人的重要性,强调项目管理即是人的管理。

PRINCE2 总体从原则、主题、流程和环境四个要素展开。

基于 PRINCE2 对项目的定义,要想管理好项目,前提是要搭建一个受控的环境。

什么是受控的环境? 需要界定项目的情境结合组织的管理模式,依项目的情境搭建一个受控的环境。

PRINCE2 强调项目的环境是独特的,在遵循原则的基础上,结合项目的特定情境,对项目的管理主题和流程进行适当裁剪,整合成适合特定环境的项目管理方法。

● 首先,基于项目情境进行拆解
○根据项目的复杂度或未知因素,可以从人和事两方面进行拆解 如果人和事都复杂,以项目群来管理;
○把事拆解,降低项目成果的模糊度,可以拆解为项目来管理;
○ 再把人拆解,降低利益相关方的繁杂度,可以拆解为工作包管理;
○工作包可以继续按照阶段、周来管理。
○如果人不复杂,而事复杂,则可以用敏捷的方式来管理。

● 其次,参照最佳实践 3+1 进行整合
三大项目管理体系或方法论
○PMP 项目管理认证 ----> 项目管理知识体系
○PRINCE2 受控环境下的项目管理第二版 ---> 方法论,偏实践,是基于 IT 背景的经验教训总结的一套项目管理方法论
○国际项目管理协会 IPMA 组织的 IPMP 国际项目管理认证 ---> 一套基于项目经理的人员能力基准评定,将人的能力分为不同等级

一个的最佳实践——敏捷
○基于敏捷宣言和敏捷原则,结合敏捷的四大支柱:迭代开发、增量交付、自组织团队和高优先级的需求驱动,整合了业界敏捷的最佳实践。

(二)两种视角、两种产品、两种技术

两种视角:商业和专业

●商业视角
是一种通识,是从组织的层面考虑,项目实际上是为交付一个或多个商业产品而创建的一个临时性组织,考察人的能力,包括软技能和硬技能。

○硬技能包括拆解、整合、解决问题的能力
○软技能包括协商、谈判、冲突解决、自省的能力

●专业视角

是从个人的层面考虑,考察在专业方向的深度钻研程度和对事的处理能力。一般不同行业都有自己的最佳实践或标准,行业是基石,可以作为参考。

两种产品:专业产品、管理产品

●专业产品是实际的项目交付物,是客户最终要验收的东西。项目团队成员在项目中或项目结束后交付一个或多个商业产品,客户通过这些商业产品的使用能带来后续的商业价值。

●管理产品是项目管理团队在管理项目的具体过程中,为保障项目过程顺畅和受控而产生的管理文档。管理产品并不是客户真正需要的,可以作为组织过程资产供未来项目参考,也是总结经验教训的过程。
项目经理要重视项目的管理产品,因为管理产品是为了促进项目能够完整的交付客户需要的专业产品而做的辅助工作产生的文档记录。

两种技术:基于产品的规划技术、质量评审技术

●基于产品的规划技术
○基于产品的规划技术以客户为导向和以结果为导向来制定项目计划,适用于项目不确定性比较高的情况。通过以终为始的原则定义产品,确保客户能够满意地验收项目产品。

定义产品其实是在项目初始由项目团队共同搞清楚客户真正期望什么样的产品,在项目经理的带领下,和项目团队共同寻找如何有效整合客户需求与自身供给能力的最佳解决方案。

○基于产品的规划技术需要先制定一个项目产品描述,用产品规划技术对项目产品描述进行分解,分解后的子产品通过制定子产品描述,这是从最终客户能认可的产品的维度展开的工作。
延伸到项目的具体实施,需要将子产品描述分解为活动,对活动估算时间和资源,给出项目排期,再根据项目排期展开实际的项目实施工作。

●质量评审技术

○质量评审技术是质量控制过程的重要技术。PRINCE2 对质量评审技术给出了如下定义:质量评审技术是其中一种评估方法,以文件评审的形式,评估产品与质量标准的一致性。

质量评审技术以会议形式展开,对产品测试结果的文件进行评估,判断产品测试的结果是否可以接受。

○质量评审技术由四个关键角色展开:
■主席负责控制整个会议,确保会议中大家的讨论话题一致,会议时间受控;
■陈述者通常是负责交付项目子产品的小组经理或关键任务负责人,对项目交付的产品进行陈述;
■评审者是评审委员会的领导或专家们,他们代表项目的各个不同利益相关方,共同评审项目陈述者递交的项目材料,给出评审意见;
■行政人员在整个会议中担任服务支持型角色,负责记录所有达成共识和决定下来的方案,促进后续的行动和跟进。

(三)三方利益 BUS

通常意义上,项目利益相关方一般都被分为三种:

●B(Business):代表项目发起人利益的项目主管
●U(User):代表项目使用者利益的高级用户
●S(Supplier):代表项目交付方利益的高级供应商

优秀的项目经理,当接到一个项目的时候,往往会本能地分析项目的关键利益相关方及他们的诉求与动机,这将会对项目建立秩序和让项目过程受控提供重要的基础

在 PRINCE2 的项目管理团队中,BUS三方代表项目管理委员会的指导层,属于项目管理团队中的高层管理人员,BUS 三方各自代表不同的利益

●项目主管 B
从商业角度出发,确保项目的投资价值,代表整个项目的商业利益。一般是公司的高层领导,指引企业的战略方向。他们拥有资源和权力,站在公司的整体角度考虑问题,具有很好的企业大局观。项目主管负责指明项目的方向,为项目的全生命周期负责,关注项目的收益和价值

●高级用户 U
从用户的角度考虑,确定产品的范围,代表用户的利益。他们关心的问题可能是:

○项目产品是否满足他们的需求,能否解决他们的问题,以及使用产品会不会给他们带来影响。
○项目产品交付给用户,用户能不能、愿不愿意使用产品是对项目成果的极大考验,如果用户并未使用项目产品,那项目的成果不会达成
○项目成果到项目收益的转化又是另一大考验,如果用户使用了项目产品,但是行为习惯或工作方式并未改变,那么也不会产出收益。
因此,项目经理在项目早期,要充分收集与引导用户方的需求,并与用户方就项目产品达成共识至关重要。否则,就会在项目过程中频繁面临需求变更的情况。同时,项目经理要邀请用户方在项目的关键节点参与项目的阶段评审与验收工作,在项目的早期识别项目的分歧并尽早达成共识。

●高级供应商 S
从交付角度考虑,满足用户的需求,代表交付方的利益他们以具体目标和任务为导向,关心在有限的资源与能力限定下能否交付被分派的产品。
一个项目往往不止一个供应商,可能会有多个不同的供应商,他们的利益和诉求也各不相同。
项目经理需要在项目早期,就多个供应商建立沟通与协作机制,促使项目的目标和各自任务达成共识,并能有效地调动他们的积极性参与项目,按期完成各自的工作,为达成项目整体目标提供基础。

项目的高层决策需要 BUS 三方共同决定,但项目主管 B 一般是独裁制的,对项目的成败负有最终责任。PRINCE2 通过在项目管理委员会引入 BUS 三方,确保在项目的高层就项目的各方利益达成共识,有利于项目的实际推进,并且,项目的做完促使项目的做成,使得项目的各方利益都得到平衡与满足

(四)四层项目组织结构、四个要素

01-四层项目组织架构

组织结构

●公司或项目群管理层 ----> 独立于项目管理团队的,属于公司层级
●项目管理委员会
由 BUS 三方组成,指导项目管理工作,为项目提供统一方向,为项目经理提供持续支持和授权,为项目提供资源和资金,促进项目团队内外部的利益相关方沟通。

●项目经理
负责项目日常的管理,在项目管理委员会的授权范围内,行使项目管理委员会的所有职权,项目经理一般由独立的个人担任。

●小组经理
根据项目的规模和性质,项目经理可以任命小组经理负责具体产品的交付管理,小组经理完全向项目经理汇报,但是实际在甲乙双方的项目环境中小组经理的职权不一定低于项目经理,只是作为项目的临时性组织,小组经理接受项目经理的管控。

PRINCE2 中的四层组织结构,是为项目搭建一个受控环境,不论实际的职权高低,在项目的临时性组织中,各个利益相关方在自己的职权范围内管理项目工作,并促进有效沟通和反馈。

02-四个要素

PRINCE2 将原则、主题、流程、项目环境作为项目的四个要素。

●原则为项目提供正确的方向;
●主题作为项目的核心过程,具体在管理项目的过程中,需要管理哪些方面、怎么管,提供正确的做事方法;
●流程贯穿项目始终,解决了谁什么时候做什么事的问题,指导做正确的事。

PRINCE2 强调原则必须遵守,只有遵守了原则才属于 PRINCE2 项目,主题和流程可以根据项目环境裁剪

03-四个环境

●商业地域环境是外部环境,要适应地缘商业环境,比如行业的合规性、地域限制等。
●组织环境是一个永久性环境,需要善用组织环境,借力打力,为项目提供一个支持的组织环境。
●项目环境是一个临时性环境,需要根据实际情况界定具体的项目环境,便于后续项目利益相关方能够在项目环境内协作。
●小组环境是项目内根据不同需要组建的小的团队,在小组环境里,团队成员相互合作,共同朝着同一个项目目标前进。

04-四种计划

PRINCE2 的四层项目组织结构通过向下逐级授权、向上例外管理的机制进行管理。

●向下逐级授权:公司或项目群管理层基于高层计划设定项目容许偏差授权给项目管理委员会;项目管理委员会制定整体项目计划,并设定阶段容许偏差授权给项目经理;项目经理制定阶段计划,并设定工作包容许偏差授权给小组经理;小组经理制定小组计划,负责具体工作包的交付。

●向上例外管理:小组经理监测工作包的进展情况,如果超出工作包容许偏差则通过例外报告的形式上报给项目经理;项目经理监测阶段进展,如果超出容许偏差,则通过例外报告上报给项目群管理委员会;项目管理委员会监测项目进展,如果超出容许偏差,则通过例外报告上报给公司或项目群管理层。

05-四种报告

基于四层项目组织结构的逐层向下授权和逐层向上例外管理机制,有四种对应的进展报告类型,用于下级向上级汇报工作,分别是检查点报告、要点报告、阶段竣工报告、项目竣工报告,表中罗列了四种不同报告的区别

(五)项目的五大特征

PRINCE2认为项目有5 大特征:临时性、独特性、跨职能性、变革性、不确定性。

01-临时性

临时性是指项目有固定的起始时间和结束时间。在固定的期限内完成一件具有创新性的工作。

对于明确起始和结束时间的工作,需要有一定的仪式感,这种仪式感能够促成大家在项目内协作。

●在项目起始时间,项目经理要召集项目团队和领导共同召开一个项目启动会,项目启动会标识着项目的正式开始。项目经理安排领导参与项目启动会并发言,确保领导支持项目,这对所有项目相关方是一个信号的暗示:领导是重视这个项目的,并且授权给项目经理全权管理该项目,这样在项目的过程中,所有相关方才会配合项目经理的工作。

●在项目结束时间,项目经理需要召集相关人员召开项目总结会,项目总结会向大家传递信号:项目完成并交付成功,感谢大家对项目的大力配合。同时,带领大家总结经验教训,为组织储备组织过程资产。一般总结会后也会一起举办一个庆功会,意味着项目的正式结束,释放项目资源。

02-独特性

独特性是指项目是一项创新性的工作。

项目经理在项目开始前要主动识别出项目的创新点,并善于向周围的人,尤其是领导强调项目的创新点在哪里,做该项目能给项目团队、公司及领导带来哪些收益。

这样,大家都知道项目的重要性了,特别是领导意识到项目能给公司带来收益,那么,领导层才会更加重视项目,才会将项目的优先级排高,也会给项目提供资源。

03-不确定性

不确定性是指项目完成一项具有创新性活动会面临很多不确定的因素,比如环境、政策、法律等等,不确定性越高,意味着项目的风险越大,那么,项目成功的概率会大大降低。

面对项目的不确定性,如果项目周期长,可以将项目的周期缩短,短时间内只关注能看得清的部分,随着项目的进行,项目的某些部分会逐渐变得清晰,再着手新的部分。

比如,做一款产品,前期市场等多方面因素都很模糊,那么可以将做产品的想法分成不同的阶段进行,短期内只关注当下看得清的部分,随着时间的推移,某些因素会逐渐变得清晰些,可以逐渐迭代。

另外,也要强调计划的重要性。不确定性越高的项目,虽然计划赶不上变化,但更应该重视项目前期的计划。因为在计划的过程中,能有效地识别风险,认清路径,并且提前研究出应对或规避风险的方案,尽量少走弯路。

04-跨职能性

跨职能性是指项目是多个部门之间协同的一项工作。只有跨职能性的工作才称之为项目,任何只有部门内部的工作都只能称为活动,不能称为项目。

因为PRINCE2 将项目定义为按照一个被批准的商业论证,为了交付一个或多个商业产品而创建的一个临时性组织,就代表了项目是各个不同部门组成的一个临时性组织。

跨职能性的临时性组织都是由人组成的,要想让人协作起来,具有相当大的困难,因为每个人的利益和出发点都不一样,项目经理在这种情况下,需要将项目各个利益相关方协同起来,朝着一个共同的项目目标前进。

05-变革性

变革性是指项目做完后对用户的行为习惯的改变。

项目的做完和做成之间的区别就体现的项目的变革性上。

●项目做完代表项目完成了可交付成果,并且这些可交付成果可以交付给用户;
●项目的做成代表项目完成可交付成果,用户使用了项目的可交付成果,并对自身的行为习惯做出了改变,从而对公司产生出收益。

因此,项目做成的难点在于用户行为改变后的收益实现,用户的行为改变需要对已有的习惯打破,而人的习惯是很难改变的,而且人们往往热衷于自己的习惯,不愿意改变习惯,这就需要从上往下的组织力量,分阶段逐步贯彻,只有用户的行为习惯改变了,才可能产生后续的收益,否则,项目即使做完了也是失败的。

●临时性和独特性是从事的角度分析,项目是一件有时间限制的创新性的事情。临时性可以基于阶段管理来控制;独特性比较高的项目,可以采用敏捷的方法,基于 MVP 先做出最小可行产品,不断验证并迭代。
●跨职能性和变革性是从人的角度分析,项目是由跨职能性的人共同完成的,项目完成后会对人产生变革性的影响。跨职能性利用项目管理委员会 BUS 三种角色平衡不同利益相关方,促使大家朝着同一个项目目标努力;变革性强的项目可以采用项目群管理方式,一波一波逐渐变革。
●不确定性是基于时间维度考虑,可以根据项目的复杂度情况利用时间来达到平衡,比如不确定性很高的项目,可以将项目周期缩短一些,降低不确定性,反之,不确定性比较低的项目,则可以将项目周期适当延长一些,确保在可控范围内。

基于这些特征,可以完成一个项目的画像(例如雷达图)。

分别对五个特征打分

●3 分是临界点,表示中等,
●3 以下表示该维度难度偏低,
●3 以上表示该维度难度偏高,需要重点考虑。

根据雷达图的打分情况可以先判断是人更重要还是事更重要,然后根据项目的特点,有所侧重的管理项目的难点或痛点方向。

(六)项目的受控仪表盘(评价)

项目管理的评价指标通常由收益、时间、成本、范围、质量、风险组成,这六个因素测量起来相对容易,是项目最直接的评价维度,因此,也将这六个指标称为项目的目标达成率。

01-收益

收益是最根本的问题,即为什么要做项目?收益需要在项目立项阶段定义清楚,包括谁衡量,衡量什么,怎么衡量等,如果前期不定义清楚,后续就很难评价。

收益的难点在于大部分项目的收益是项目结束后才产生的,那时候项目团队都已经解散了,怎么能持续地衡量收益?

需要组织层面制定一些机制,在项目结束后,有专门的人对项目进行后评价和跟踪,这样也有助于组织根据项目的收益是否实现和实现程度做出后续的战略调整。

02-时间

时间的评价依据是在立项文档中明确说明的,可以分为项目整体时间目标和阶段时间目标,一般会根据整体和阶段分别定义相关的容许偏差。

项目目标评价时,将实际的完成时间和目标时间对比,

●如果在容许偏差范围,则说明项目符合时间要求,
●如果超出容许偏差范围,则说明项目不符合时间要求。

制定阶段时间目标是为了降低风险,避免项目达不成整体时间目标。如果在阶段目标评价时,已经发现超出阶段容许偏差,就要及时采取纠正性措施,争取项目尽快回到正常轨道上,避免最终项目时间目标达不成。

03-成本

成本是项目目标符合性的重要指标。

项目的总体成本是将所有要花费的资源和钱累加到一起形成的,写在项目立项文档中。如果项目总成本经过审批,则成为项目预算,作为项目考核的依据。

一般会制定项目整体成本目标和阶段成本目标,并对应地设定容许偏差。

项目成本评价时将实际花费成本和项目总预算进行对比,判断项目成本是否超支。阶段成本目标的设定是为了有效控制成本,避免项目整体成本目标达不成。

04-范围

范围是项目的具体内容,项目到底要交付什么?项目范围不容易确定,因为利益相关方对范围的考虑往往不一致。

项目范围一般用 MoSCoW(M:必须有、S:应该有、C:可以有、W:不会有)进行优先级排序。

项目经理一定要养成在项目早期和关键利益相关方确认项目优先级的习惯,因为项目的资源和时间很有限,要确保项目的稀缺资源在有限时间内优先完成优先级高的工作,遵循二八原则。

05-质量

质量是项目要达到什么样的目标,是项目经理在立项阶段和客户就专业产品达成的质量标准。

在立项报告中说明,一般包括项目产品的质量标准、容许偏差、验收方法和验收职责。

质量评审首先要经过内部项目质量评审会的评审,保证产品质量满足内部质量标准;然后要通过客户的验收,确保符合客户的质量期望。

06-风险

风险是伴随项目而产生的,对项目的风险接受程度是多大,一般用风险的预期货币价值来评价。

在项目立项阶段,设定一个风险的预期货币价值目标,比如可以设定为项目预算的 10%,如果风险发生将造成的货币影响累加后超过项目整体预算的 10%,则说明没有达到目标,否则,则说明符合要求。

对于预期货币价值不好估算的项目,可以设定几个关键指标作为风险预期目标,如果将这些指标控制在预期目标内,就说明项目达到了风险评价指标的要求。

07-指标的评价组合

1+4+1

两个 1 分别指风险和收益,4 是质量、范围、成本、时间。

收益最重要,处于最中间,所有其他指标都围着收益而调整;风险贯穿项目始终,随时都可能面临风险,并且任意改变其他四个指标,都可能会面临新的风险,就需要随时做出风险应对方案;时间、成本、范围、质量可以根据项目的性质和类型调整,如互联网面向新市场型项目可以固定时间和成本,弹性调整范围,质量是硬性指标,而传统瀑布型项目则可以固定范围和质量,弹性调整时间和成本。

2x3

将六个指标两两成对,分为三对

●成本和收益,从投资和回报的角度对比项目是否有利可图;
●质量和范围,共同关注的是产品,衡量项目产品的目标达成率;
●风险和时间,从项目的模糊度和复杂度两个维度分析风险,调整项目的周期长短,时间和风险为反比例关系,风险大则可以将时间调短,风险小则可以将时间拉长。

每个项目这六个指标优先级不同,同一项目各利益相关方关注的维度也不同,这也是项目冲突的重大来源,实际上项目就是利益相关方的博弈。

具体项目的六大指标如何衡量,取决于项目的真实情境,一般通过利益相关方的共识来衡量,因为项目的衡量从来都不科学,而且成本很高。

项目经理在具体管理项目的过程中,需要结合项目的具体情境,平衡这六大指标,确保项目在受控范围内展开,同时要达成利益相关方的满意。

(七)7 个原则、7 个主题、7 个流程

7 个原则

PRINCE2 定义项目必须遵循七个原则,只有遵守了原则才算作是 PRINCE2 项目,七个原则分别是:

七个原则按照上下前后进行分类

向后吸取经验教训,项目前期明确定义角色与职责,

依环境剪裁管理方案,向下聚焦产品,

向前按阶段管理,向上做好例外管理,

在前进的过程中,持续进行业务验证,确保项目一直具有投资价值。

●持续业务验证
不断进行商业论证,确保项目是值得做的、是有收益的、并且在过去是有收获的
●吸取经验教训
在项目前、中、后不断吸取并总结经验教训,避免项目闭门造车,通过学习别人踩过的坑,有效减少我们再次踩同样的坑。
●明确定义的角色和职责
在项目前期,充分了解项目的相关方,明确定义不同角色与职责,确保项目人员分工明确,并建立合作机制。
●按阶段管理
将项目分为多个阶段进行管理,制定高层次的项目计划和详细的阶段计划,并逐个阶段进行计划、授权、监督和控制,确保项目的整体可控。
● 例外管理
组织从上向下建立分层次的控制方法,设定绩效指标的允许偏差,如果超出允许偏差,触发例外管理机制,下层向上层汇报偏差,上层基于汇报情况给予指导方案。
●聚焦产品
项目始终要关注要交付的是什么,质量要求是什么,这些都是用户定义的,并且最终要交付的都是给用户具有商业价值的产品。
●依项目环境剪裁
确保方法论与项目的具体环境相关,并且项目控制程度是基于项目的规模、复杂性、重要性、能力和风险等因素量身裁定的。
○首先,界定项目环境;
○其次,整合项目管理方法论;
○再次,自定义适合项目环境的解决方案。

7 个主题

主题定义了管什么的问题,包括商业论证、组织、质量、计划、风险、变更、进展。

●商业论证
强调了做项目的必要性,项目是有投资回报的,在项目前、项目中持续地进行商业论证,对于商业论证后的做法可以有什么都不做、做最少、最一些三种选择,
如果项目在某一时刻不具有投资价值了,那么果断地结束项目比继续做下去更有价值。
●组织
从人的角度分析项目的利益相关方。
○首先,在项目前搭建一个健康的组织环境对项目的成功至关重要
PRINCE2 将项目的组织分为 4 层,每层有具体的角色对应,总共 8 个角色,不同角色具有不同的职责。
○其次,考虑沟通管理方法或策略,采用套路对项目利益相关方进行管理;
○再次,利用冲突解决、谈判、沟通技巧管理;
○最后,利用职能角色和团队角色进行管理。

●质量
从产品的维度出发,PRINCE2 强调产品的重要性,要持续关注产品,通过产品促使项目做完达到项目做成的结果。
●计划
计划在项目中贯穿始终,PRINCE2 通过不同层次的授权管理强调了计划的重要性,不同层次的管理者在不同的管理阶段要制定对应层级的计划,确保项目整体的可控。

●风险
代表了项目的不确定性,不确定性高则代表风险大。
●变更
是项目管理过程中不可避免的情况,PRINCE2 在组织中定义了变更组织,变更组织代表了项目管理委员会的职责,变更组织需要对变更进行审批。
●进展
从时间维度管理项目的进度,不同层级在不同阶段需要将进展情况汇报给上层领导,上层领导针对进展的可控情况或偏差情况授权调整。

7 个流程

PRINCE2 定义了七个流程,分别是项目准备流程、项目指导流程、项目启动流程、阶段控制流程、产品交付管理流程、阶段边界管理流程、项目收尾流程。

七个流程贯穿整个项目,定义了在什么时候由谁来做什么。

●项目准备流程是项目管理委员会在项目前期做的一些准备工作,只有被商业论证证明项目是可行的,才会继续后面的活动。
●项目启动流程代表项目的正式启动,资源和资金将会正式进入项目,项目的活动正式展开。
●阶段控制流程是项目经理对阶段的具体管理。
●产品交付流程是小组经理完成产品交付过程中的活动。
●阶段边界管理流程处理阶段之间的接口问题。
●项目指导流程是项目管理委员会在项目进行中的任何时候指导项目。
●项目收尾流程代表项目的结束,可交付成果的移交、经验教训的总结、资源的解散等。

九宫格流程

将项目从时间和管理层级两个维度分开,通过前中后、上中下可以形成一个九宫格,7 个流程散落在九宫格的不同点上。

●项目准备流程 SU 处于项目的前期,由项目指导层负责。是项目管理委员会在项目前期做的一些准备工作,只有被商业论证证明项目是可行的,才会继续后面的活动。
●项目启动流程 IP 处于项目前期结束的位置,项目指导层授权项目管理层开始项目,处于上中之间。代表项目的正式启动,资源和资金将正式进入项目,项目的活动正式展开。
●阶段管理流程 CS 处于项目中期,由项目管理层负责。是项目经理对阶段的具体管理。
●边界管理流程 SB 处于项目中期,项目指导层授权项目管理层继续项目,处于上中之间。处理阶段之间的接口问题。
●产品交付流程 MP 处于项目中期,项目交付层负责交付产品。是小组经理完成产品交付过程中的活动。
●项目指导流程 DP 贯穿项目前中后,是项目管理委员会在项目进行中的任何时候指导项目。
●收尾流程 CP 处于项目后期,项目指导层授权项目管理层结束项目。代表项目的结束,可交付成果的移交、经验教训的总结、资源的解散等。

(八)8 个角色

PRINCE2将项目管理团队分为三层:项目管理委员会是指导层、项目经理是管理层、小组经理是交付层。

基于项目管理团队的三层组织结构,可以将项目管理团队分为8 个角色。

●指导层的项目主管 B
●高级供应商 S
●高级用户 U
●管理层的项目经理 PM
●项目保证 PA
●变更管理组织 PC
●项目支持 PS
●交付层的小组经理 TM

BUS 属于项目管理委员会,协调 BUS 三方利益,负责项目的高层授权和管理。

●项目主管 B 是项目管理团队中第一个被任命的角色,一般由公司或项目群管理层直接任命。
○项目主管从商业角度出发,确保项目的投资价值,代表整个项目的商业利益。一般是公司的高层领导,指引企业的战略方向。他们拥有资源和权力,站在公司的整体角度考虑问题。
○项目主管负责指明项目的方向,为项目的全生命周期负责,关注项目的收益和价值。
○项目主管在项目前期帮助项目经理搭建项目组织结构和建立项目秩序,在项目过程中监督和指导项目经理的工作,确保项目达到预期目标。

●高级用户 U 从用户的角度考虑,确定产品的范围,代表用户的利益。
他们最关心项目产品
○是否满足他们的需求,
○能否解决他们的问题,
○使用产品会不会给他们带来影响。
项目产品交付给用户,项目的成果和收益转化是项目的两大挑战。因此,项目经理在项目早期,要充分收集与引导用户方的需求,并与用户方就项目产品达成共识。在项目过程中,要邀请用户方在项目的关键节点参与项目的阶段评审与验收工作,尽早识别项目的分歧并达成共识。

●高级供应商 S,从交付角度考虑,满足用户的需求,代表交付方的利益。
他们以具体目标和任务为导向,关心在有限的资源与能力限定下能否交付被分派的产品。
一个项目往往不止一个供应商,他们的利益和诉求也各不相同。项目经理需要在项目早期,就多个供应商建立沟通与协作机制,促使项目的目标和各自任务达成共识,并能有效地调动他们的积极性参与项目,按期完成各自的工作,为达成项目整体目标提供基础。

●项目经理 PM 通常由项目主管任命,在整个项目的生命周期中配合项目主管进行项目定日常组织、协调和管理,通常是被第二个任命的角色,也是项目日常运转的核心。

项目经理也代表项目的投资方向,一定要站在企业整体的角度思考问题。
项目经理起着承上启下的作用,
○一方面,通过汇报的形式让项目主管及项目管理委员会及时获取更多信息帮助做决策,
○另一方面,为小组经理们分配工作包和任务,调动他们的积极性,监督他们的日常工作进展,捕获项目中的问题和风险,协助小组经理们处理问题,确保项目阶段目标和项目整体目标的达成。

●变更管理组织 PC 是项目管理委员会任命的项目变更组织,负责项目中的变更评审与审批。
是由于项目中总会有一些变更请求的出现,有些合理,有些不合理,并且有些变更请求超出项目经理的权限,而项目管理委员会往往都很忙,所以项目管理委员会任命一个变更管理组织来专门处理授权范围内的变更请求的审批。如果超过授权范围,变更请求需要提交给项目管理委员会审批。

●项目保证 PA 代表项目管理委员会为项目提供保证。一般由 BUS 三方各委派一名成员共同担任项目保证。
项目保证一方面监督项目经理的日常管理,确保项目经理不会做出对自己一方不利的事情;另一方面承担专家的角色,站在自己这方,指导项目团队开展工作并解决问题。项目保证为项目的平衡和受控起到至关重要的作用。

●项目支持 PS 是对项目经理提供支持,主要体现在文档配置方面。
通过有效地提供项目文档管理,促使项目各方的信息保持透明和协同,确保项目团队日常沟通顺畅,并保留所有记录以备后续查询。项目支持和项目经理充分配合,共同为项目团队创造和谐高效的项目环境,并确保项目信息透明、沟通顺畅。

●TM 是小组经理,由项目经理授权,负责小组团队的管理,确保工作包的交付。
小组经理往往不止一个,项目经理需要调动小组经理的主观能动性,并帮助不同小组经理之间搭建顺畅的沟通渠道和协同机制。
小组经理作为小组团队的负责人,需要制定小组计划,协调相关资源克服困难,交付任务。小组经理通常具有较强的目标导向。

将项目管理团队分为 8 个角色分别对项目不同层次管理,虽然效率降低了,但更加强调做成的重要性,因为成功是大家共同定义、达成共识的。

终章

项目管理是对项目的各个方面和利益相关方的动机进行计划、授权、监督和控制,从而在预期的时间、成本、质量、范围、收益与风险等各项绩效指标范围内,实现项目的目标。

PRINCE2构建了流程与主题相结合的框架,强调对项目绩效的 6 个方面进行计划、授权、监督和控制。需要界定项目情境(Context),从而基于项目情境,参加最佳实践(3+1),因地制宜,因时而变,因人而异,实现项目组织受控,团队敏捷交付

A
bp(net core)+easyui+efcore实现仓储管理系统目录

有了前一篇文章(
abp(net core)+easyui+efcore实现仓储管理系统——模块管理升级(六十)
),对于模块管理的升级过程中解决升级中出现的问题的一些经验。我们对组织管理这个模块进行升级。

一、添加Profile定义文件

1. 在Visual Studio 2022的“解决方案资源管理器”中,右键单击“ABP.TPLMS.Application”项目,使用鼠标左键展开“Orgs” > “Dto”文件夹

2. 使用鼠标右键单击“Dto”文件夹,然后选择“添加” > “类”。 将类命名为 OrgMapProfile,然后选择“添加”。代码如下。

usingABP.TPLMS.Authorization.Users;usingABP.TPLMS.Entitys;usingABP.TPLMS.Users.Dto;usingAutoMapper;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceABP.TPLMS.Orgs.Dto
{
public classOrgMapProfile:Profile
{
publicOrgMapProfile()

{

CreateMap
<OrgDto, Org>();
CreateMap
<OrgDto, CreateUpdateOrgDto>();
CreateMap
<CreateUpdateOrgDto, Org>();

}
}
}

二、修改OrgAppService类

3.在Visual Studio 2022的“解决方案资源管理器”中,在“Orgs”文件夹中找到OrgAppService.cs文件,双击在文本编辑器中打开,修改代码如下。

usingAbp.Application.Services;usingAbp.Application.Services.Dto;usingAbp.Domain.Repositories;usingAbp.Web.Models;usingABP.TPLMS.Entitys;usingABP.TPLMS.Modules.Dto;usingABP.TPLMS.Orgs.Dto;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceABP.TPLMS.Orgs
{
public class OrgAppService : AsyncCrudAppService<Org, OrgDto, int, PagedOrgResultRequestDto,
CreateUpdateOrgDto, CreateUpdateOrgDto
>, IOrgAppService

{
public OrgAppService(IRepository<Org, int>repository)
:
base(repository)
{

}
[DontWrapResult]
public PagedOrgResultDto<OrgDto>GetAllOrgs(PagedOrgResultRequestDto input)
{
PagedOrgResultDto
<OrgDto> orgs = new PagedOrgResultDto<OrgDto>();
input.SkipCount
= 0;//这里需要进行参数传递
input.MaxResultCount= 1000;var allOrgs=GetAllAsync(input);

IReadOnlyList
<OrgDto> result =AddParentOrgs(input, allOrgs.Result.Items).AsReadOnly();
orgs.Rows
=result;
orgs.Total
=result.Count;returnorgs;
}
private List<OrgDto> AddParentOrgs(PagedOrgResultRequestDto input,IReadOnlyList<OrgDto>list)
{
List
<OrgDto> result = new List<OrgDto>();if (list == null)returnresult;var qry1 = base.CreateFilteredQuery(input);
List
<Org> listParent = new List<Org>();
GetParentOrgs(listParent, list[
0].ParentId, qry1);foreach (var item inlistParent)
{
result.Add(ObjectMapper.Map
<OrgDto>(item));
}
result.AddRange(list.ToArray());
returnresult;
}
protected override IQueryable<Org>CreateFilteredQuery(PagedOrgResultRequestDto input)
{
var qry = base.CreateFilteredQuery(input)
.Where(t
=> t.Name.Contains(input.OrgName == null ? string.Empty : input.OrgName))

.Where(t
=> t.BizCode.Contains(input.OrgCode == null ? string.Empty : input.OrgCode))

.Where(t
=> t.CustomCode.Contains(input.CustomCode == null ? string.Empty : input.CustomCode));returnqry;
}
private void GetParentOrgs(List<Org> orgs, int ParentId, IQueryable<Org>listOrgs)
{

List
<Org> drs = listOrgs.Where(x => x.Id ==ParentId).ToList();if (drs == null || drs.Count <= 0)
{
return;
}
else{for (int i = 0; i < drs.Count; i++)
{
var dr =drs[i];if (!orgs.Contains(dr))
{
orgs.Add(dr);
}
GetParentOrgs(orgs, dr.ParentId, listOrgs);
}
}
}
}
}

4. 上面代码中需要特别注意的一点,是GetAllOrgs方法中的input.SkipCount=0这一行代码,如果将这一行代码注释掉,在进行条件查询时,会报错。在组织管理页面的海关代码中输入“2011”,然后点击“查询”按钮。如下图。

5.Visual Studio 2022会弹出一个用记未处理的异常,错误信息,如下图。

6.在Visual Studio 2022的解决方案资源管理器中,将刚才注释掉的那一条代码“input.SkipCount=0”,还原。按F5运行应用程序。

7.在浏览器中的登录页面中输入管理员用户名和密码进行登录。

8.在主界面的菜单中,选择“Business->组织管理”菜单项,浏览器中呈现一个组织信息列表与四个按钮。组织信息能正常显示。如下图。

9. 在“组织管理”列表页面的海关代码输入框中输入“2011”,然后点击“查询”按钮。如下图。

10.这一次程序运行正常,查询出了结果,结果如下图。

11.在“组织管理”列表页面中使用鼠标点击“添加”按钮,弹出“添加组织信息”界面。如下图。

12.在“添加组织信息”中填写完信息,然后点击“保存”按钮,将新添加的组织信息保存到数据库。如下图。

Ubuntu Server20.04.5 LTS

【参考资料】

Ubuntu官方地址:
https://www.ubuntu.com/

Ubuntu论坛地址:
https://ubuntuforums.org/

Ubuntu Wiki地址:
https://wiki.ubuntu.com/

Ubuntu帮助地址:
https://help.ubuntu.com/

Ubuntu邮件列表地址:
https://discourse.ubuntu.com/t/mailing-lists/
https://ubuntu.com/server/docs
)

1.下载Ubuntu镜像

官网下载:
https://releases.ubuntu.com/

国内镜像下载:

华为镜像:
https://repo.huaweicloud.com/ubuntu-releases/

阿里镜像:
http://old-releases.ubuntu.com/releases/

2.安装

官网安装教程:
https://ubuntu.com/server/docs/install/step-by-step

博客:

http://t.csdn.cn/aDPUu

2.1 网络配置(静态IP配置)

  • 静态IP设置方法,点击ens33 然后选择ipv4、

  • 点击Manual 手动添加ip地址


    • subnet:192.168.x.xxx/24 (子网掩码)
    • address:192.168.x.xxx(静态IP地址)
    • Geteway:192.168.x.1(网关)
    • Name servers:(DNS服务器地址:)
    • search domains:

    华为云DNS    122.112.208.1	139.9.23.90
    			114.115.192.11	116.205.5.1
    			116.205.5.30	122.112.208.175
    

2.2 设置镜像源地址

国内镜像地址:

华为源:
https://mirrors.huaweicloud.com/ubuntu/

阿里源
http://mirrors.aliyun.com/ubuntu/

网易163
http://mirrors.163.com/ubuntu/

2.3 磁盘分区

/boot:这里存放的是启动 Linux 时使用的一些核心文件,包括一些连接文件以及镜像文件。
/home:用户的主目录
/srv:该目录存放一些服务启动之后需要提取的数据。
/usr:应用程序

/boot 	2G
/		其他
/bin:
bin 是 Binaries (二进制文件) 的缩写, 这个目录存放着最经常使用的命令。

/boot:
这里存放的是启动 Linux 时使用的一些核心文件,包括一些连接文件以及镜像文件。

/dev :
dev 是 Device(设备) 的缩写, 该目录下存放的是 Linux 的外部设备,在 Linux 中访问设备的方式和访问文件的方式是相同的。

/etc:
etc 是 Etcetera(等等) 的缩写,这个目录用来存放所有的系统管理所需要的配置文件和子目录。

/home:
用户的主目录,在 Linux 中,每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的,如上图中的 alice、bob 和 eve。

/lib:
lib 是 Library(库) 的缩写这个目录里存放着系统最基本的动态连接共享库,其作用类似于 Windows 里的 DLL 文件。几乎所有的应用程序都需要用到这些共享库。

/lost+found:
这个目录一般情况下是空的,当系统非法关机后,这里就存放了一些文件。

/media:
linux 系统会自动识别一些设备,例如U盘、光驱等等,当识别后,Linux 会把识别的设备挂载到这个目录下。

/mnt:
系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将光驱挂载在 /mnt/ 上,然后进入该目录就可以查看光驱里的内容了。

/opt:
opt 是 optional(可选) 的缩写,这是给主机额外安装软件所摆放的目录。比如你安装一个ORACLE数据库则就可以放到这个目录下。默认是空的。

/proc:
proc 是 Processes(进程) 的缩写,/proc 是一种伪文件系统(也即虚拟文件系统),存储的是当前内核运行状态的一系列特殊文件,这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。
这个目录的内容不在硬盘上而是在内存里,我们也可以直接修改里面的某些文件,比如可以通过下面的命令来屏蔽主机的ping命令,使别人无法ping你的机器:

echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
/root:
该目录为系统管理员,也称作超级权限者的用户主目录。

/sbin:
s 就是 Super User 的意思,是 Superuser Binaries (超级用户的二进制文件) 的缩写,这里存放的是系统管理员使用的系统管理程序。

/selinux:
 这个目录是 Redhat/CentOS 所特有的目录,Selinux 是一个安全机制,类似于 windows 的防火墙,但是这套机制比较复杂,这个目录就是存放selinux相关的文件的。

/srv:
 该目录存放一些服务启动之后需要提取的数据。

/sys:

这是 Linux2.6 内核的一个很大的变化。该目录下安装了 2.6 内核中新出现的一个文件系统 sysfs 。

sysfs 文件系统集成了下面3种文件系统的信息:针对进程信息的 proc 文件系统、针对设备的 devfs 文件系统以及针对伪终端的 devpts 文件系统。

该文件系统是内核设备树的一个直观反映。

当一个内核对象被创建的时候,对应的文件和目录也在内核对象子系统中被创建。

/tmp:
tmp 是 temporary(临时) 的缩写这个目录是用来存放一些临时文件的。

/usr:
 usr 是 unix shared resources(共享资源) 的缩写,这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类似于 windows 下的 program files 目录。

/usr/bin:
系统用户使用的应用程序。

/usr/sbin:
超级用户使用的比较高级的管理程序和系统守护程序。

/usr/src:
内核源代码默认的放置目录。

/var:
var 是 variable(变量) 的缩写,这个目录中存放着在不断扩充着的东西,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日志文件。

/run:
是一个临时文件系统,存储系统启动以来的信息。当系统重启时,这个目录下的文件应该被删掉或清除。如果你的系统上有 /var/run 目录,应该让它指向 run。

2.4 设置主机用户名与密码及服务器名称

2.5 安装 SSH服务

2.6 选择预置服务安装

# 设置root密码
sudo passwd

# 添加用户
adduser -m 【用户名】
# 设置密码
passwd 【用户名】
#修改用户
usermod [参数] 【用户名】
#创建用户组
groupadd【参数】【用户组名】
#修改组
groupmod【参数】【用户组名】
# 删除用户组
groupdel 【用户组名】

#硬盘挂载

3.webmin

【官网】
https://webmin.com/

apt-get install webmin

wget https://sourceforge.net/projects/webadmin/files/webmin/2.021/webmin_2.021_all.deb

dpkg --install webmin_2.021_all.deb

[依赖安装]


Webmin默认安装到/usr/share/webmin
访问地址:ip:10000

配置:

4.ufw

https://blog.csdn.net/fd214333890/article/details/115410168

# 列举出你系统上所有的应用配置
sudo ufw app list

# 在启用 UFW 防火墙之前,你必须显式允许进来的 SSH 连接。否则,你将永远都无法连接到机器上
sudo ufw allow OpenSSH
#开启关闭ufw服务
systemctl start ufw
systemctl stop ufw
#禁用 启用ufw服务
systemctl disable ufw
systemctl enable ufw
# 开启关闭ufw
ufw enable
ufw disable

# 默认禁止
ufw default deny
# 默认允许
ufw default allow

# 状态
ufw status verbose

# 开端口
ufw allow port_number/protocol

5.samba

sudo apt-get update
sudo apt-get install samba
# 配置防火墙
sudo ufw allow Samba
# 创建用户 用配置密码, 密码用专门的smbpasswd命令进行设置
sudo useradd sbuser
sudo smbpasswd -a sbuser
#创建要共享的文件夹
$ sudo mkdir /disk
# 修改文件夹的所有者与上面新建的用户一致, 否则会导致没有权限进行访问
$ sudo chown sbuser /disk
# 配置samba
$ sudo vim /etc/samba/smb.conf

[home] #共享名,该共享标签,可随意取,该名字为在其他电脑上看到的共享名
    comment = home directories #该共享描述
    path = /disk  #共享路径
    public = yes   #指定该共享是否允许guest账户访问
    writable = yes #writable用来指定该共享路径是否可写
	valid users = 用户名   #设置访问用户
	valid users = @组名   #设置访问组
	readonly = no       #读写
	browseable = yes #可以被所有用户浏览到资源名称,
	
# 重启samba服务
sudo systemctl restart smbd

reboot



6.docker

https://hub.docker.com/

7.
aria2

https://hub.docker.com/r/p3terx/aria2-pro

https://zhuanlan.zhihu.com/p/466573640

https://p3terx.com/archives/docker-aria2-pro.html

对以上映射的目录进行用户权限设置,
aria2c
核心进程会以所设定的用户运行。当使用非 root 用户进行管理时非常重要,这关乎到安全性和文件是否能正常访问。你不应该错过这个细节,否则可能导致不必要的麻烦。

  • -e PUID=$UID
    - 用户映射。设置文件管理账户的
    UID
    (用户 ID)。忽略则默认为
    nobady
    用户,并权限最大化。
  • -e PGID=$GID
    - 用户组映射。设置文件管理账户的
    GID
    (用户组 ID)。忽略则默认为
    nogroup
    用户组,并权限最大化。

科普:
在常规的 Linux 发行版中
$UID

$GID
这两个环境变量分别为当前登录账户的
UID

GID
值,所以通过 CLI 启动容器可以直接使用这两个变量。但需要注意可能有部分系统
$GID
没有被定义。

# 替换<TOKEN>字段(RPC密钥)
docker run -d \
    --name aria2-pro \
    --restart unless-stopped \
    --log-opt max-size=1m \
    --network host \
    -e PUID=$UID \
    -e PGID=$GID \
    -e RPC_SECRET=<TOKEN> \
    -e RPC_PORT=6800 \
    -e LISTEN_PORT=6888 \
    -v $PWD/aria2-config:/config \
    -v $PWD/aria2-downloads:/downloads \
    p3terx/aria2-pro
    
    
    
docker run -d \
    --name ariang \
    --log-opt max-size=1m \
    --restart unless-stopped \
    -p 6880:6880 \
    p3terx/ariang
   

8.plex

https://ubunlog.com/zh-CN/plex介质服务器安装ubuntu-20-04/

https://linuxize.com/post/how-to-install-plex-media-server-on-ubuntu-20-04/

https://www.plex.tv/media-server-downloads/#plex-media-server

#[方式1] 使用.deb文件
# 下载
wget https://downloads.plex.tv/plex-media-server-new/1.32.0.6918-6f393eda1/debian/plexmediaserver_1.32.0.6918-6f393eda1_amd64.deb?_gl=1*16kkgdv*_ga*MTAyNzU4MzUzNi4xNjgxNTgxNTI5*_ga_G6FQWNSENB*MTY4MTU5MTA5OC4zLjEuMTY4MTU5MjMzMi4wLjAuMA..
# 安装
sudo dpkg -i 
# 检查程序状态
sudo systemctl status plexmediaserver.service

# 卸载
sudo apt remove plemediaserver

#[方式2]使用Plex存储库
# 从存储库导入GPG密钥
curl https://downloads.plex.tv/plex-keys/PlexSign.key | sudo apt-key add -
# 将存储库添加到系统
echo deb https://downloads.plex.tv/repo/deb public main | sudo tee /etc/apt/sources.list.d/plexmediaserver.list

sudo apt update

sudo apt install plexmediaserver

sudo systemctl status plexmediaserver.service

	
sudo apt remove plexmediaserver

# 访问地址	
http://direccion-ip:32400/web

9.emby

10.NextCloud

11.Kodi

官网:
http://www.kodiplayer.cn/

11.1 Android电视安装Kodi

adb

打开电视的adb调试开关
  进入设置 > 系统 > 系统信息,遥控器依次按下“上”、“下”、“左”、“右”,即可看到页面中跳出adb开关,将ADB设为开启状态.

adb devices

adb connect ip:6666665

adb shell

# 打开第三方应用安装权限
setprop persist.tcl.debug.installapk 1
setprop persist.tcl.installapk.enable 1

exit退出

adb install xxx.apk

11.2 Kodi安装Plex插件

安装Plex插件:
http://www.kodiplayer.cn/plugins/2918.html

FFMpeg

https://blog.csdn.net/annjeff/article/details/105748428


jellyfin

可道云

接下来本来就直接打算分享框架重构的具体环节,但重构的代码其实并没有完成太多,许多的实现细节在我心中还没有形成一个定型。由于最近回归岗位后,新的开发环境需要自己搭建,搭建的时间来说花了我整整一天的时间才勉强搞定。人们常说工欲善其事必先利其器,开发环境和工具是必不可少的,否则你会发现在接下来的过程中遇到困难的时候就会走很多弯路。虽然最后我们仍旧达到了目的,但是我们大概也会心力憔悴、得不偿失。于是我萌生了一个想法,那就是何不自己写一个脚本(该节我会分享,里面有许多有意思的写法,有兴趣的朋友可以阅读研究一下,如有错误希望不吝指正),让脚本把一切安装到位,那么自己就不会因为遗漏一些东西而挠头抓腮。而对于一个开发来说首先就是要搭建开发环境,这个其实是极其重要的,许多的书籍上对搭建开发环境都是简单几笔的带过。虽然网上有许多的资料,可是如果没有做一些系统的介绍或者相应的脚本,那么初学者或者会为此犯难不已。由于这一节开发环境可能篇幅不长,又考虑到不久后就即将迎来毕业季,因此我在这里就稍微将这个环境分为两个部分,它们分别叫做开发环境和工作环境,希望对于各位朋友有所助益。

开发环境

主开发环境

1、系统

plain因为支持跨平台,所以主要的两个操作系统是linux和windows,而linux中我选择了中小企业中常用的
centos 7
(centos 8 已经停止支持了,但是7还有一段时间才会停,估计之后大家可能会被迫使用centos stream)。而对于windows环境下,我选择的版本是目前比较流行的win10系统,毕竟这个系统对老的硬件兼容性强点,新的win11似乎要Intel系列的CPU在8代以后才支持。在windows下我的开发环境是直接使用
Microsoft Visual Studio 2022
进行开发,当然如果不喜欢它的重量级的朋友可以使用其免费的Code进行开发,不过现在Microsoft Visual Studio 2022也有个人免费版,我觉得如果想要专业一些直接使用这个重器吧,调试和各方面都支持的不错。

至于linux选择centos 7的原因,纯粹属于个人比较熟悉而已,如果有其他linux系统经验的朋友可以直接使用自己所熟悉的系统(只不过需要修改一下我的安装脚本来进行开发环境的构建,如果你已经有了成熟的环境,那么使用自己的即可)。我处在的行业中使用该系统的比较多,当然还有另一个叫ubuntu的系统,其实类linux系统的操作都大同小异,熟悉了一个系统后其他系统的差异也估计只在一些系统命令的区别(主要是包管理方面、网络、安全等等)。如果选用的是centos系统,那么你可以使用我的安装脚本,该脚本可以灵活定制编译器的版本,还有可以安装基于vim编辑器的开发环境,同时也有相应的定制镜像进行下载(制作后上传)。

2、编译器

windows上的编译器主要使用Microsoft Visual Studio 2022,所以编译器是自带的,因此在这里不做过多描述。由于要使用新的特性,因此编译器必须为最新的,随着未来的情况,编译器都应该保持最新的状态。有些人会发现如果拿老的项目使用最新的编译器就会遇到一些莫名其妙的错误,就算没有错误也会遇到很多刷屏的警告信息,这都是以前编译器版本对于不规范的代码过于宽松的原因。比如我现在这家公司的这个项目就是,拿最新的编译器的话是编译不过的,而且数不清的警告让人无从下手,所以只能使用旧的指定的编译器版本。

在《Effect C++》中
Item 53: 不要轻忽编译器的警告
,告诉我们不要轻易忽视编译器产生的抱怨,据我所知在google编程规范中就是将所有的警告视为错误,可见警告并非只是编译器的无理取闹,在编译器版本升级后,编译器的作者朋友们都尽可能地给出一些忠告,这样会减少程序在运行时的错误,因为有的一个小的疏忽就可能导致程序崩溃或者异常。这里我举一个简单的例子,一个函数返回Int32_t类型,但实际使用中我们使用了int16_t类型,这时候会发生什么呢?如果看过C++基础知识相关书籍的朋友不难想到,这个叫做宽到窄的转换,形象的说法可以比作原来用大桶装的东西要放到一个小桶里,如果桶里装的是水,假如大桶里的水小桶装得下还好,假如装不下呢?这时候必然有部分的水杯舍弃,在C++中就有数据截断这个概念了。这时候你使用的这个数据,就是部分数据,使用部分数据实际上往往不比越界、悬吊指针造成的灾难小。因此《Effect C++》中
Item 27: 将强制转型减到最少
专门列出该条目,用以说明强转带来的总总坏处,但有些时候我们不得不使用转换,比如接口设计的原因,那么我们也最好使用C++风格的转换方式(static_cast、const_cast等等)。

在plain开发中,重点在于centos系统下的开发,要使用最新的编译器我所知的有两种途径:
gcc-toolset

gcc源码编译
。如果你的yum源支持gcc-toolset12则直接进行安装即可,否则你可能需要使用源码安装了,关于如何进行gcc-toolset的安装,以及gcc源码编译安装网上有太多的文章了,我在这里就不在重复(如果源码安装你可以尝试使用我的安装脚本,目前这个脚本我只在centos下测试过,如果是其他系统估计需要改动才能使用)。今年的gcc 13发布后,我也即将使用最新的gcc 13,可以在gcc的git版本管理中发现gcc 13已经在开发阶段,如下图:

3、编辑器

在windows上我们可以使用其提供的强大的编译编辑一体的专业IDE,所以我在这里就不讨论这个平台了。其实编辑器的选择是靠个人的喜好做选择,并非使用某个编辑器就一定好,只要你用的顺手即可。多年前刚开始进入互联网行业的时候我开始使用的编辑器是
zend studio
,在此之前我在学校只接触过
eclipse、VS
,但eclipse我不是很喜欢,因此到现在我都不愿意使用它,这其实都是正常的事情。刚刚进入行业的时候,听说某某程序员使用记事本来进行开发,听上去很厉害,可是我觉得那样的开发多半是无奈之举,谁不愿意自己的代码多点提示,错误的时候也能够帮我们及时发现?

最后我选择的编辑器为
vim

VS
,至于vim和emacs之间做出了选择vim是因为个人觉得vim更轻量一些,不过你也需要使用插件。对于emacs,其实这个编辑器的功能似乎更强大,它集成的编译环境让我们的调试更加快速,不过这也看个人的喜好了。有人说为什么不用新生代的neovim?因为不少人觉得vim太慢、过时、很久没更新(吃老本),所以才有neovim的出现,可是我想说的是vim走到今天很不容易,而且现在代码的更新也很快了,作者似乎也意识到了大家所指出的那些毛病都是正确的,因此才有了更加快速的vim script等等加快编辑器速度的优化。由于习惯了使用vim,我觉得也没有必要再去尝试别的东西了,编辑器只是编写代码的辅助工具,所以在这个方面个人认为没必要做的本末倒置,只要自己认为用起来得心应手就好。

由于要使用最新的vim,因此我的安装方式也是源码安装,其实也可以去vim网站上下载rpm包进行安装,不过rpm包安装要注意依赖的关系。源码安装vim的脚本在这里:
https://github.com/viticm/cpp_misc/blob/main/script/install_vim.sh

工作环境

职业发展

1、刚工作和工作不久

我本不打算在这里说自己这方面的心得,毕竟自己从来似乎就没有做过职业规划方面的事情,所以该条款仅仅是一点点微不足道的建议(以自身的经历和经验)。想起十多年前(2011)刚毕业在北方那座不大的城市顶着火热的太阳找工作的情形,颇感毕业生想要进入社会生存是多么不易(特别是自己本专业,据我所知90%以上都是从事了和自己专业无关的工作),其实不容易的也还有许许多多的打工人。那时候我还记得在学校的毕业设计,我是用的一个网上弄下来的图书管理系统,其代码是asp写的,刚好是我学校所学,为了完成任务在上面做了一些修改,然后进行一番分析后做出论文。虽然最后通过了答辩拿到了毕业证,可是找工作的时候却四处碰壁,一方面是因为学校所处的城市相关的工作较少,另一方面出来后用asp这个语言的公司几乎没有,其实我想大部分原因是公司不愿意培养一个完全没有经验的人。经过一个多月简历石沉大海,去公司唯唯诺诺的面试毫无结果之后,我开始想要提升一下自己。既然外面生存环境需要自己掌握技能,那么我就只能去提升了,那时候我发现做网站用的比较多的是PHP,因此我在网上搜了一圈后找到了一个培训班(先听我讲完)。我还记得当时的那位授课老师姓候,似乎是一位硕士,当时给了三天免费试听的课程。我到了那里之后听了一天课,发现其实那些内容如果自己找资料同样可以掌握,而且进度会更加快,所以一天以后我没有再去,而是转向图书馆买了三百多的书,这些书有C/C++开发、PHP开发、C/C++算法速查。至于为什么想学PHP却又买了C/C++的书,忘记听那位朋友说的,是自己对该语言产生了一定兴趣的结果。

在购买图书之后,我在网上找了一些视频,开始大约一个月的系统学习,其实每天也没有想象学习的那么满,而且天气也开始又炎热转凉,我只是有计划的慢慢推动自己的学习。对于绝顶聪明的人来说,他们知识消化的速度快,可能要不了多久就可以掌握新的知识,但对于我这样普通的人来说正应了老话”贪多嚼不烂“,因此我总的进度并不快。就算是因为这样,一个月左右我基本上掌握了PHP,算是入了门,毕竟一些高级用法只有在实践中才能慢慢掌握。总算在当年的11月左右我进入了职业生涯的第一家公司,这家公司是一个十人左右的小公司,其业务是外包一些网站产品的开发。所实话当时全没有想过职业发展的事情,认为首先让自己多年所学能够让自己生存下来就满足了,而且那时候工资也就两千左右,哪里像现在有的朋友起薪都过万,虽然说是都是十年前了,可是我想要说的是近两年大家的环境比之前要好很多了,虽然今年的环境似乎变差了一些,但我觉得那总是暂时的。第一份工作其实挺重要的,也许是上天不曾亏待我,第一份工作我遇到了好的工作环境,有一个挺不错的上级。我还记得那位上级其实年龄不小了,当时大概有四五十岁左右的年纪,想一想现在觉得35就过时未免觉得有点儿悲哀,至于年龄的坎大家纷纷认为这是中国产业升级失败的问题,至于真正的原因为何现在还没有定论。我的上级是原因分享和耐心的人,工作上不懂得只要你请教他都能耐心回答,而且也会组织我们一起对项目遇到的问题进行总结和分享,虽然我没有什么太好的建议,但也会对他们所说的问题发出疑问。有人说小公司就可以不注意规范问题,但是我第一个公司就不是,他们极力想要避免规范不一致带来的问题。或许规范这个从根本上来说确实是处于公司和项目上的考量,是为了让你的去留不会对项目造成过多的影响,不过总得来说多人协作开发的时候统一的规范会让组员能够更快地理解彼此所写的代码,在你没事的时候使用code review就能够看出一些问题,所以规范的统一还是有必要的。第二年我来到了南方的沿海城市,其实我还是挺感激第一家公司中我学习到的东西,虽然那时候来到新的城市也还是碰了不少壁。最后在次年大约五月份的时候,我进入了一家创业公司,从此开始了游戏开发之路。

游戏开发在当下并不陌生,不过近两年发展的也是良莠不齐,以及因为本行业的高工作强度为大家所诟病(据我所知软件大部分其实都差不多,否则github上也不会有996icu这个项目了)。一开始我是作为PHP做后台开发,这个后台就是用来对接游戏接口还有就是统计游戏中数据的功能,这一做大概就做了一年。顺嘴提一句,当时那家公司同一层有一个网易著名团队出来自创的公司,在同一层楼我感觉他们的福利确实挺好,而且能看到其作品质量也很不错。在做后台开发的时候,我也兼着做了一些运维的工作,当时忙的焦头烂额,小公司没有运维真的是很难,不过在这一年我确实学习了不少知识,不仅仅学会了许多曾经不熟悉的linux相应的操作和命令、还让我学会了使用vim编辑器,就是从这里开始vim就成为我的常用开发编辑器了(手动狗头,必须带插件)。能够掌握这些知识主要还是得感谢我那位同乡的上级,他不厌其烦甚至还借了一本书给我,并不因为我不了解就嗤之以鼻。在后来新的运维加入之后,我的负担大大降低后,就开始转向了后端开发,这一转就到了现在。后来我从这家创业公司去到一家当地在页游排行前几名的公司,这次其实我是和创业公司的一些小伙伴一起出去的,原因是老板不愿意继续那个项目了。

来到页游的公司,其实实际上我们项目还是手机游戏开发,我们项目也作为未来公司的一个开发方向得到了老板的重视。可是我们的组员并不齐全,特别是核心认为,前端和后端的老大需要从外引入,虽然这时候我们项目过去就有了前端和后端的人员。但是由于经验不足,我们不愿意也不敢去承担那份重任,所以希望从外面招揽人才来带领我们。也不知道什么原因,那种高级别的人才在当年6月份的时候像是特别缺乏,一个月了都未能找到合适的人员,是不是因为薪资问题我就不得而知了。但最后还是进来了一个客户端老大,不过他要求改用他熟悉的引擎(一个国外开源引擎),后来不到一个月似乎没有成效他就离开了。过后不久我们后端才来了一个老大,号称十多年资深的C++开发经验,进来之后也想要使用自己熟悉的代码(但我们项目本来已经正在用之前项目的代码在进行开发),所以他需要将我们以前的代码做一定的移植。然后问题就出现了,他进来不久后似乎是看我们是抱团进入的,不是他亲自招的人,所以甩手就让我们写几个功能,当时我以为是项目需要用到,所以连忙查找资料一边修改调试弄出来了,结果到了他那边不满意说存在问题,但是具体问题在哪里他又不愿意告知,甚至开始有点冷嘲热讽,说这么简单的问题都不会(后来我才发现原来他有可能就是存心要排挤,当时我们由于年轻没有感觉出来)。当时由于这个项目和我们几个人一起跟老板确定面谈下来,所以他只好离开了,后来我们后端的程序还被经理稍微数落了一下,他们其实也明白其中的原因(毕竟他们的年龄和经历比我们丰富)。这个上级对我们来说,我觉得他一点也懂不得分享(或许是我们确实缺乏经验,手动狗头),甚至还有点自高自大(其实看不出来真实水准,就算很厉害吧)。你想如果遇到这样的领导,你还能在项目中得到收获、获得快乐吗?

后来我回到了内地,依旧做后端开发,所遇到的领导都是原因分享的,不过这时候我从那家页游公司的那位上级处看到了其实知识有些时候也需要自己去掌握,所以近几年我都是自己查询资料进行学习。说了自己一大段的经历,其实我想说的是对于刚工作或者工作不久的朋友,在考虑薪资的同时,如果想要职业更好的发展,那么在选择你的上级和公司时,就需要关注他们是否有open精神,如果面对的是close的人那么你需要慎重考虑。
在手里有选择的余地之下,尽量选择一个open的工作环境
,那样可以快速提升自己的技术实力。

举个例子,可以提供大家参考,比如面试过我的一位面试官,他将会作为你的上级,在面试沟通中会问一些技术方面的问题。刚开始聊的都挺好,但是一听到我有开源过项目,并没有得到赞赏,反而变了一副嘲笑的态度,说是那不是很简单的吗?工作几年人人都会开源多少?最重点的一句是,他说其实真正好的东西其实不愿意分享的。当时我就在想,如果公司不用还好,因为站在公司立场它试错的风险是很大的,如果公司愿意使用你的功能和技术,为何不愿意分享出来,藏着掖着怎么能在实践中证明自己所实现的正确和可靠?从这里多多少少就能看出该上级close程度,特别是后来他抓着面试者不熟悉或遗忘的技术穷追猛打,我认为可能是公司大概是不缺人,或者就是想要通过所谓技术碾压来压低你商谈薪资的筹码,我认为这样都是不合适的。一个求职者来说,薪资如果不理想工作的时候总是会缺少一些干劲,就算是大环境不好情况下,也无需做出那么多让人感觉不舒服的举措,毕竟求职就是双向选择的过程。大部分技术面试的时候,你可以询问一下公司状况,
和面试官的交谈中其实可以用技巧性的话术曲折打听出公司的open程度,在你考虑职业发展时尽量不要选择close的公司
(如果薪资水平差别不大的情况下)。

2、不要觉得自己不够聪明

这句话是我从别人那里引来的,我认为这句话十分有道理,如果你觉得自己不够聪明那么你很多时候就会变得畏缩不前,对于未来的发展来说很有阻碍。就拿我自己来说,我曾经就是认为那些深入的软件设计就是高深莫测,所以刚开始的时候根本就不敢涉足。但就我的项目经历来说,我经历过由浅入深的过程,有些特别复杂的系统设计(比如游戏的战斗系统),这些我以前都没有接触过,就连自己维护都没有过,但是我参考了几个游戏的设计后,加上自己的理解,在几个类型不同的项目中仍旧能够游刃有余,那多半是多亏了自己的经验和不断学习的结果。

如果你觉得自己不够聪明,其实有时候往往只是一种经验缺乏的错觉,这时候你只需要补充你不足的经验即可。现在不比以前,现在是信息的时代,许多的技术知识在网上可以免费获取,你只需要花费一点点时间,接下来的就是看你对此的兴趣和坚持了。我相信大部分人都是差不多的,只是他们掌握知识的快慢不同而已,而且掌握的快不一定应用的好,而掌握的慢也不一定应用的不行。就像一个人在面试的时候很多技术问题可能回答的不好,但实际工作的时候表现得反而十分出色。

学历是否很重要?我就在这里说说自己的认知,当然的学历是一个人在以往学习优秀的证明,这一点上是毋庸置疑的,在某种程度上来说它是重要的。因此现在许多人大学毕业之后都选择继续深造,这一点上来说我也十分赞同。但是继续深造,还有为了更好的工作提升学历,就真的是必须的么?笔者并不认为学历是必须的,这不是我因为高考不理想的借口(差几分上本科,却不愿复读)。在这个世界上有许许多多的人,但是人活着并不是非得和学历挂钩,中国为何学历风盛行的原因追根究底其实是因为封建长久的科举制度造成的。特别是许多企业,标榜自己员工的本科率多少多少,其实这都是社会的问题,并不是我们的问题。但是说到这里,为了让自己有更好的生活,或者提升自己的知识水平,在自身条件充足的情况下,我还是比较支持去提升学历(虽然我个人比较懒,但是各位朋友只要有时间读个硕士还是可以的),特别有些知识要到了一定学历高度才会接触,一些高级的算法你没有进行相应的教育上手就比较困难。但如果自己没有条件,特别是家庭环境不好,需要自己考虑生计的事情,那么这时候学历对自己可能无法短时间去获得提升了,那么这时候可以利用零碎的时间多阅读书籍来提升自己的实力。在国外听说许多的企业不在乎学历和年龄,别人眼中就在乎你的skills,这就是他们那边的环境更加尊重人的能力,我相信有一天我们这里也会如此。

假如真的觉得自己不够聪明,就不断提升自己吧。

3、身体第一

本来打算写两个条目就足够,但是上面我说的都是工作上一些令人厌烦的事情,特别是学习,有些人总会觉得枯燥乏味。所以我在最后增加了这一条,一切的一切你都需要有个良好的身体,所以朋友们最需要关心自己的健康。工作是为了更好的生活,学习为了更好的工作,但一切的前提身体要健康、心里要快乐。

写在最后

杂七杂八

1、centos开发环境镜像

地址:待制作上传

2、开发环境脚本

地址:
https://github.com/viticm/cpp_misc/blob/main/script