0%

简介

  • 机器人学中的数学

工业机器人领域使用到的数学

工业机器人领域涉及到多个数学分支,这些数学工具用于机器人的建模、运动规划、控制系统设计等方面。以下是在工业机器人领域常用的数学:

  1. 线性代数(Linear Algebra): 工业机器人中广泛使用线性代数来表示和处理坐标变换、运动学和动力学问题。矩阵和向量的运算在描述机器人的位姿、关节角度以及执行器的运动方面非常有用。

  2. 几何学(Geometry): 机器人的运动学建模涉及到坐标系变换、旋转矩阵、齐次坐标等几何概念。几何学的知识用于描述和计算机器人末端执行器的位置和姿态。

  3. 微积分(Calculus): 运动规划、轨迹生成和优化算法通常需要微积分的方法。例如,对机器人的路径进行优化时,需要计算速度、加速度等。

  4. 数值分析(Numerical Analysis): 工业机器人控制系统通常需要进行数值计算,如逆运动学求解、路径规划、动力学模拟等。数值分析提供了有效和稳定的算法来解决这些问题。

  5. 控制理论(Control Theory): 控制理论用于设计机器人的控制系统,包括反馈控制、PID控制器、状态空间控制等。这些方法有助于保持机器人在目标轨迹上的准确性和稳定性。

  6. 优化理论(Optimization Theory): 优化方法在工业机器人中的应用很广泛,例如路径规划、运动优化、参数优化等。这有助于提高机器人的效率和性能。

  7. 刚体运动学(Rigid Body Kinematics): 刚体运动学用于描述机器人末端执行器的位置、速度和加速度,以及机器人关节的运动学性质。

  8. 机器学习和人工智能(Machine Learning and AI): 近年来,机器学习和人工智能在机器人领域的应用逐渐增多,包括视觉识别、自主导航、智能控制等。

这些数学工具的综合运用使得工业机器人能够执行更复杂、精确和灵活的任务,提高了生产效率和质量。

弧度和角度转换关系

弧度(radians)和角度(degrees)之间的转换关系可以通过以下公式表示:

  1. 从角度到弧度的转换

    弧度 = 角度 × π / 180

    其中,π(pi)是圆周率,约等于3.14159265359。

    例如,将角度 90 度转换为弧度:

    弧度 = 90 × π / 180 = π / 2 弧度

  2. 从弧度到角度的转换

    角度 = 弧度 × 180 / π

    例如,将弧度 π/2 转换为角度:

    角度 = (π / 2) × 180 / π = 90 度

这些公式允许你在弧度和角度之间进行相互转换。这在数学、物理学、工程学以及机器人学等领域中非常常见,因为不同的问题和公式可能使用不同的单位,所以需要进行转换以便正确地处理数据。

机器人学 弧度 角度 转换

在机器人学和计算机图形学中,经常需要在弧度(radians)和角度(degrees)之间进行转换,以便在不同的数学和编程上下文中使用。以下是弧度和角度之间的常见转换方法:

  1. 从角度到弧度的转换

    如果你有一个角度(以度为单位),想要将其转换为弧度(以弧度为单位),可以使用以下公式:

    [ \text{弧度} = \frac{\text{角度} \times \pi}{180} ]

    例如,如果要将角度 90 度转换为弧度:

    [ \text{弧度} = \frac{90 \times \pi}{180} = \frac{\pi}{2} \text{ radians} ]

  2. 从弧度到角度的转换

    如果你有一个弧度(以弧度为单位),想要将其转换为角度(以度为单位),可以使用以下公式:

    [ \text{角度} = \frac{\text{弧度} \times 180}{\pi} ]

    例如,如果要将弧度 (\frac{\pi}{2}) 转换为角度:

    [ \text{角度} = \frac{\frac{\pi}{2} \times 180}{\pi} = 90^\circ ]

这些转换公式是标准的数学关系,用于在角度和弧度之间进行转换。在机器人学和计算机图形学中,通常需要根据具体问题将角度和弧度进行相互转换,以便进行正确的计算和旋转操作。确保在程序中使用适当的单位,以避免单位混淆和错误的计算。

机器人学 轴角为初始姿态 加上欧拉角 最终获取轴角 如何计算

在机器人学中,如果你有一个初始姿态(用轴角表示)和一个欧拉角,然后想要将这个欧拉角旋转添加到初始姿态中,最终获取新的轴角表示,你可以按照以下步骤进行计算:

  1. 将初始轴角(Axis-Angle)表示转换为旋转矩阵(Rotation Matrix)或四元数(Quaternion)。

    • 如果你的初始姿态使用轴角表示为 (AA_{init} = (\mathbf{u}{init}, \theta{init})),其中 (\mathbf{u}{init}) 是旋转轴的单位向量,(\theta{init}) 是旋转的角度,那么你可以使用轴角到旋转矩阵或四元数的转换公式将其转换为旋转矩阵 (R_{init}) 或四元数 (Q_{init})。
  2. 将欧拉角转换为旋转矩阵

    • 如果你有欧拉角表示为 (E = (\alpha, \beta, \gamma)),其中 (\alpha) 是滚动角,(\beta) 是俯仰角,(\gamma) 是偏航角,那么你可以使用欧拉角到旋转矩阵的转换公式将其转换为旋转矩阵 (R_{E})。
  3. 计算最终的旋转矩阵

    • 将初始的旋转矩阵 (R_{init}) 与欧拉角的旋转矩阵 (R_{E}) 相乘,得到最终的旋转矩阵 (R_{final} = R_{init} \cdot R_{E})。
  4. 将最终的旋转矩阵转换为轴角

    • 最后,你可以使用旋转矩阵到轴角的转换公式,将最终的旋转矩阵 (R_{final}) 转换为轴角表示 (AA_{final} = (\mathbf{u}{final}, \theta{final}))。

需要注意的是,转换公式的具体形式取决于你使用的坐标系约定和数学库(例如,Eigen、Mathematics Toolbox等)。因此,在实际应用中,请查阅相应的文档以确保正确的转换。

通过这个过程,你可以将初始轴角姿态与欧拉角旋转相结合,获得最终的轴角姿态。这种方法允许你在不同表示之间进行转换,并有效地管理机器人的姿态。

机器人学 旋转矩阵 运算 详解

在机器人学中,旋转矩阵是一种常用的表示方法,用于描述三维空间中的旋转操作。旋转矩阵是一个3x3的矩阵,其中每一列和每一行都是一个单位向量,用来表示旋转后的坐标系的方向。通过旋转矩阵,可以非常有效地表示和计算物体的旋转。

以下是关于机器人学中旋转矩阵运算的详细解释:

  1. 旋转矩阵的表示

    一个通用的旋转矩阵通常表示为:

    [ R = \begin{bmatrix} r_{11} & r_{12} & r_{13} \ r_{21} & r_{22} & r_{23} \ r_{31} & r_{32} & r_{33} \end{bmatrix} ]

    其中,( R ) 是旋转矩阵,( r_{ij} ) 表示矩阵的元素,表示旋转后的坐标系的方向。

  2. 旋转矩阵的性质

    • 旋转矩阵是正交矩阵(orthogonal matrix),即它的列向量和行向量都是单位向量,并且相互垂直。这意味着旋转矩阵的转置等于其逆。

    • 旋转矩阵的行和列表示了新坐标系的基向量。

    • 旋转矩阵的行(或列)的长度不变,即 ( |r_i| = 1 )。

  3. 旋转矩阵的运算

    • 旋转矩阵可以用于将一个点从一个坐标系转换到另一个坐标系。给定一个点的坐标 ( \mathbf{p} ),通过乘以旋转矩阵 ( R ),可以得到旋转后的坐标 ( \mathbf{p}’ ):

      [ \mathbf{p}’ = R \cdot \mathbf{p} ]

    • 旋转矩阵之间可以进行矩阵乘法来表示复合旋转。如果有两个旋转矩阵 ( R_1 ) 和 ( R_2 ),它们分别表示两个旋转操作,那么它们的复合旋转可以表示为:

      [ R = R_1 \cdot R_2 ]

    • 旋转矩阵的逆矩阵表示相反的旋转。如果 ( R ) 表示一个旋转,那么 ( R^{-1} ) 表示相反的旋转,即将物体旋转回初始位置。

  4. Euler角到旋转矩阵

    通常,可以使用欧拉角(滚动、俯仰、偏航)来构建旋转矩阵。不同的欧拉角顺序会产生不同的旋转矩阵。例如,在XYZ顺序下,可以使用以下方式构建旋转矩阵:

    [ R = R_z(\text{偏航角}) \cdot R_y(\text{俯仰角}) \cdot R_x(\text{滚动角}) ]

    其中,( R_x )、( R_y ) 和 ( R_z ) 分别表示绕X、Y和Z轴的旋转矩阵。

旋转矩阵是机器人学中非常重要的工具,因为它们允许精确描述和计算旋转操作,这对于机器人的定位、导航和运动控制非常关键。通过旋转矩阵,机器人可以准确地执行各种复杂的旋转操作。然而,需要注意的是,旋转矩阵的运算可能比其他表示方法(如四元数)稍显复杂,因此在实际应用中需要小心处理。

轴角 详解

轴角(Axis-Angle)表示一种在三维空间中描述旋转的方式。它使用一个轴向量和一个角度来表示旋转操作。轴角常用于计算机图形学、机器人学以及三维游戏开发等领域,因为它可以更直观地描述旋转操作,而不像欧拉角那样容易出现万向锁问题。

轴角由以下两个要素组成:

  1. 轴向量(Axis Vector):这是一个单位向量,用于定义旋转的轴线方向。轴向量通常表示为单位长度的三维向量,例如 (x, y, z),其中 (x, y, z) 是轴的方向向量。

  2. 旋转角度(Angle):这是绕轴线旋转的角度,通常以弧度(radians)为单位表示。角度可以是正数或负数,表示旋转的方向,通常在 0 到 2π(360度)之间。

轴角表示一个旋转操作,其效果是绕轴向量指定的轴线旋转一定的角度。旋转角度的方向由轴向量的方向确定,旋转的大小由旋转角度表示。

轴角的表示方式可以用以下公式表示:

[ \text{Rotation} = \theta \cdot \mathbf{u} ]

其中:

  • ( \theta ) 是旋转角度,以弧度表示。
  • ( \mathbf{u} ) 是单位轴向量,表示旋转的轴。

轴角的使用步骤通常如下:

  1. 定义轴向量(单位向量),表示旋转的轴线方向。
  2. 指定旋转的角度(以弧度为单位)。
  3. 使用轴向量和旋转角度构建轴角表示。

轴角的优点之一是它没有欧拉角的万向锁问题,因此在某些情况下更容易处理。然而,它相对较难以直观地理解,因此在实际应用中,通常会使用其他表示方法,如四元数(Quaternions),以更方便地进行旋转计算。

总之,轴角是一种用于描述三维空间中旋转的方法,它使用轴向量和旋转角度来表示旋转操作。

欧拉角 详解

欧拉角(Euler Angles)是一种用于描述物体在三维空间中旋转的方法。它是以数学家Leonhard Euler的名字命名的,用于将旋转运动分解为三个连续的旋转操作,通常分别绕X轴、Y轴和Z轴进行旋转。欧拉角是一种常见的旋转表示方法,用于计算机图形学、航空航天、机器人学、三维动画等领域。

欧拉角通常由三个角度组成,分别是:

  1. 滚动角(Roll):也称为Bank角,表示绕X轴的旋转。滚动角度用来描述物体绕其自身前后轴的旋转,通常以弧度(radians)为单位表示。正角度表示顺时针旋转,负角度表示逆时针旋转。

  2. 俯仰角(Pitch):也称为Elevation角,表示绕Y轴的旋转。俯仰角度用来描述物体绕其自身左右轴的旋转,通常以弧度为单位表示。正角度表示向上旋转,负角度表示向下旋转。

  3. 偏航角(Yaw):也称为Heading角,表示绕Z轴的旋转。偏航角度用来描述物体绕其自身垂直轴的旋转,通常以弧度为单位表示。正角度表示顺时针旋转,负角度表示逆时针旋转。

欧拉角的顺序很重要,因为它们定义了旋转的顺序。常见的欧拉角顺序包括:

  • XYZ:首先绕X轴旋转,然后绕Y轴旋转,最后绕Z轴旋转。
  • ZYX:首先绕Z轴旋转,然后绕Y轴旋转,最后绕X轴旋转。
  • YXZ:首先绕Y轴旋转,然后绕X轴旋转,最后绕Z轴旋转。

不同的欧拉角顺序可能导致不同的旋转结果,因此在使用欧拉角时必须确保选定了正确的顺序。

尽管欧拉角在许多情况下非常直观,但它们也存在一些问题,例如万向锁问题,即在某些情况下无法唯一表示旋转。为了避免这些问题,有时会使用其他旋转表示方法,如四元数(Quaternions)。

总之,欧拉角是一种用于描述三维空间中旋转的常见方法,它由三个角度组成,表示绕X、Y和Z轴的旋转。欧拉角的顺序非常重要,并且在某些情况下可能存在问题,因此在使用时需要谨慎选择。

简介

  • NVIDIA 相关理论基础知识

NVIDIA 驱动卸载

  • 运行命令:
    • sudo apt-get autoremove --purge nvidia-*

最新驱动安装

安装依赖

  • 安装驱动之前,必须要更新软件列表和安装依赖
    1
    2
    3
    4
    sudo apt-get update      #更新软件列表
    sudo apt-get install g++
    sudo apt-get install gcc
    sudo apt-get install make

禁用nouveau

  • nouveau是Ubuntu自带的显卡驱动,但他是核显,我这里想安装独显,就得把他禁掉。

  • 创建文件,如果没有下载vim编辑器,将vim换成gedit即可

    1
    $ sudo vim /etc/modprobe.d/blacklist-nouveau.conf
  • 在文件中插入以下内容,将nouveau加入黑名单,默认不开启

    1
    2
    blacklist nouveau
    options nouveau modeset=0
  • 输入以下命令使禁用生效然后重启

    1
    2
    sudo update-initramfs -u   #更新系统
    sudo reboot
  • 重启后验证

    1
    lsmod | grep nouveau
  • 如果回车后无反应,则禁用成功

先完全卸载之前的显卡驱动

  • ppa源文件卸载(方式一):

    1
    $ sudo apt-get remove --purge nvidia*
  • runfile源文件卸载(方式二):

    1
    $ sudo ./NVIDIA-Linux-x86_64-384.59.run --uninstall

安装显卡驱动

  • 查询电脑最适合的显卡驱动版本

    1
    ubuntu-drivers devices
  • 随后用命令行进行安装

    1
    2
    3
    4
    sudo add-apt-repository ppa:graphics-drivers/ppa
    sudo apt-get update
    sudo apt-get install nvidia-driver-525 #此处数字要对应上面查询到的版本号
    sudo apt-get install mesa-common-dev
  • 注意: 如果前面没有禁用secure boot,则在安装过程中会提示设置一个密码,在重启时需要输入密码验证以禁用secure boot,重启后会出现蓝屏,这时候不能直接选择continue,而应该按下按键,选择Enroll MOK, 确认后在下一个选项中选择continue,接着输入安装驱动时设置的密码,开机。

  • 安装完成后重启

    1
    sudo reboot
  • 重启后在终端验证

    1
    nvidia-smi

NVIDIA 驱动安装

  • Ubuntu下安装NVIDIA驱动的三种方法:

    • 使用标准Ubuntu仓库进行自动安装
    • 使用PPA仓库进行自动化安装
    • 使用官方的NVIDIA驱动进行手动安装
  • 第一种方法操作最为简单,方便,第三种方法是最稳定,最常用的。

  • 使用标准Ubuntu 仓库进行自动安装

    1
    2
    3
    4
    5
    sudo ubuntu-drivers devices

    sudo ubuntu-drivers autoinstall

    # 完成后重启 就可完成安装NVIDIA驱动
  • 使用PPA仓库进行自动安装

    1
    2
    3
    4
    5
    6
    7
    sudo add-apt-repository ppa:graphics-drivers/ppa      //添加ppa库到系统中
    sudo apt update // 更新

    sudo ubuntu-drivers devices // 显示可以安装的nvidia驱动


    sudo apt install nvidia-xxx // xxx 代表你想安装的nVidia驱动的版本号
  • 使用官方的NVIDIA驱动进行手动安装

    • 先要搞清楚你的nvidia显卡是什么什么型号
      1
      2
      3
      4
      5
      lshw -numeric -C display

      或者

      lspci -vnn | grep VGA // 查看nvidia显卡型号
    • 然后到NVIDIA官网下载对应你显卡型号的最新版本驱动进行下载 保存到你自己的路径文件夹
    • NVIDIA官网驱动下载地址: https://www.nvidia.com/zh-cn/ 进入后选择最上面的驱动程序 就可以自行选择自己的显卡
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      //   这种方法安装nvidia驱动需要先停止图形界面

      sudo telinit 3

      // 之后进入一个新的命令行会话,使用当前的用户名密码登陆

      cd 进入你放nvidia驱动的路径

      用 ./ 或者 bash 进行安装

      安装的过程如下:(按照以下步骤)

      Accept License

      The distribution-provided pre-install script failed! Are you sure you want to continue?
      CONTINUE INSTALLATION

      Would you like to run the nvidia-xconfig utility?
      YES

      之后执行
      sudo reboot // 重启
  • 上面三种方法结束后,需要检验是否安装好了nvidia驱动。

    1
    2
    3
    sudo reboot  // 安装完了驱动需要重启

    sudo nvidia-smi // 检验是否安装好驱动

查看显卡驱动

  • 查看显卡,在终端输入以下命令:

    1
    2
    lspci | grep -i vga
    lspci | grep -i nvidia
  • 查看显卡驱动在终端输入以下命令:

    1
    lsmod | grep -i nvidia

简介

nvjpegBackend_t

  • 简述:
    • NVJPEG_BACKEND_DEFAULT – 默认值
    • NVJPEG_BACKEND_HYBRID – 使用CPU进行霍夫曼解码
    • NVJPEG_BACKEND_GPU_HYBRID – 使用GPU辅助霍夫曼解码。nvjpegDecodeBatched将使用GPU对基线JPEG比特流进行解码,当批量大小大于100时进行交错扫描
    • NVJPEG_BACKEND_HARDWARE – 单扫描支持基线JPEG比特流。不支持410和411个子样本
  • 声明:
    1
    2
    3
    4
    5
    6
    7
    typedef enum 
    {
    NVJPEG_BACKEND_DEFAULT = 0,
    NVJPEG_BACKEND_HYBRID = 1,
    NVJPEG_BACKEND_GPU_HYBRID = 2,
    NVJPEG_BACKEND_HARDWARE = 3
    } nvjpegBackend_t;

nvjpegDevAllocator_t

  • 简述:内存分配器使用提到的原型,提供给nvjpegCreateEx
    • 这个分配器将用于库中的所有设备内存分配
    • 无论如何,库都在进行智能分配(仅在需要时重新分配内存)
  • 声明:
    1
    2
    3
    4
    5
    typedef struct 
    {
    tDevMalloc dev_malloc;
    tDevFree dev_free;
    } nvjpegDevAllocator_t;

nvjpegImage_t

  • 简述:输出描述符。根据输出格式,被写入平面的数据
  • 声明:
    1
    2
    3
    4
    5
    typedef struct
    {
    unsigned char * channel[NVJPEG_MAX_COMPONENT];
    size_t pitch[NVJPEG_MAX_COMPONENT];
    } nvjpegImage_t;

英伟达API

nvjpegCreateSimple()

  • 简述:使用默认后端和默认内存分配器(cudaMalloc/cudaFree)初始化nvjpeg句柄
  • 声明:nvjpegStatus_t NVJPEGAPI nvjpegCreateSimple(nvjpegHandle_t *handle);
  • 参数:
    • handle – 编解码器实例,用于其他调用 – Input/Output
  • 返回值:
    • 成功 –
    • 失败 –

nvjpegCreate()

  • 简述:初始化nvjpeg句柄。此句柄用于所有连续调用
  • 声明:nvjpegStatus_t NVJPEGAPI nvjpegCreate(nvjpegBackend_t backend, nvjpegDevAllocator_t *dev_allocator, nvjpegHandle_t *handle);
  • 参数:
    • backend – 要使用的后端。目前支持默认或混合(目前相同)。 – Input
    • dev_allocator – 指向nvjpegDevAllocator的指针。如果为NULL - 使用默认cuda调用(cudaMalloc/cudaFree) – Input
    • handle – 编解码器实例,用于其他调用 – Input/Output
  • 返回值:
    • 成功 –
    • 失败 –

nvjpegDestroy()

  • 简述:释放句柄和资源
  • 声明:nvjpegStatus_t NVJPEGAPI nvjpegDestroy(nvjpegHandle_t handle);
  • 参数:
    • handle – 要释放的实例句柄 – Input/Output
  • 返回值:
    • 成功 –
    • 失败 –

nvjpegJpegStateCreate()

  • 简述:解码状态的初始化
  • 声明:nvjpegStatus_t NVJPEGAPI nvjpegJpegStateCreate(nvjpegHandle_t handle, nvjpegJpegState_t *jpeg_handle);
  • 参数:
    • handle – 编解码器实例 – Input
    • jpeg_handle – 解码的jpeg图像状态句柄 – Input/Output
  • 返回值:
    • 成功 –
    • 失败 –

nvjpegJpegStateDestroy()

  • 简述:释放jpeg图像句柄
  • 声明:nvjpegStatus_t NVJPEGAPI nvjpegJpegStateDestroy(nvjpegJpegState_t jpeg_handle);
  • 参数:
    • jpeg_handle – 解码的jpeg图像状态句柄 – Input/Output
  • 返回值:
    • 成功 –
    • 失败 –

nvjpegGetImageInfo()

  • 简述:检索图像信息,包括通道、每个图像层的宽度和高度,以及色度下采样。
    • 如果编码的通道小于NVJPEG_MAX_COMPONENT,那么零将被设置为缺失通道信息
    • 如果图像是三通道的,则所有三组都有效
    • This function is thread safe.
  • 声明:
    1
    2
    3
    4
    5
    6
    7
    8
    nvjpegStatus_t NVJPEGAPI nvjpegGetImageInfo(
    nvjpegHandle_t handle,
    const unsigned char *data,
    size_t length,
    int *nComponents,
    nvjpegChromaSubsampling_t *subsampling,
    int *widths,
    int *heights);
  • 参数:
    • handle – 编解码器实例 – Input
    • data – 指向缓冲区的指针,其中包含要解码的jpeg流数据。 – Input
    • length – jpeg图像缓冲区的长度。 – Input
    • nComponent – 图像的组件数(层数),目前只支持1通道(灰度)或3通道。 – Output
    • subsampling – 在这个JPEG中使用的色度下采样,参见nvjpegChromaSubsampling_t – Output
    • widths – 指向NVJPEG_MAX_COMPONENT的指针,返回每个通道的宽度。如果信道未编码,则为0 – Output
    • heights – 指向NVJPEG_MAX_COMPONENT的指针,返回每个通道的高度。如果信道未编码,则为0 – Output
  • 返回值:
    • 成功 –
    • 失败 –

nvjpegDecode()

  • 简述:解码单幅图像
    • API是后端不可知的。
    • 它将决定在内部使用哪个实现。目标缓冲区应该足够大,能够存储指定格式的输出。
    • 对于每个颜色平面,可以使用nvjpegGetImageInfo()检索图像大小,每个平面所需的最小内存缓冲区是nPlaneHeight*nPlanePitch
    • 其中nPlanePitch >= nPlaneWidth用于平面输出格式,
    • nPlanePitch >= nPlaneWidth*nOutputComponents用于交错输出格式
  • 声明:
    1
    2
    3
    4
    5
    6
    7
    8
    nvjpegStatus_t NVJPEGAPI nvjpegDecode(
    nvjpegHandle_t handle,
    nvjpegJpegState_t jpeg_handle,
    const unsigned char *data,
    size_t length,
    nvjpegOutputFormat_t output_format,
    nvjpegImage_t *destination,
    cudaStream_t stream);
  • 参数:
    • handle – 编解码器实例 – Input/Output
    • jpeg_handle – 解码的jpeg图像状态句柄 – Input/Output
    • data – 指向包含要解码的jpeg图像的缓冲区的指针。 – Input
    • length – jpeg图像缓冲区的长度。 – Input
    • output_format – 输出数据格式。有关描述,请参阅nvjpegOutputFormat_t – Input
    • destination – 指向结构的指针,包含输出缓冲区的信息。参见nvjpegImage_t描述。 – Input/Output
    • stream – CUDA流在哪里提交所有GPU工作 – Input/Output
  • 返回值:
    • 成功 –
    • 失败 –

cudaStreamSynchronize()

  • 简述:阻塞任务流,直到流完成所有操作。如果 device 设置了cudaDeviceScheduleBlockingSync标识,主机线程在它完成所有的任务之前,会一直阻塞
  • 声明:cudaError_t cudaStreamSynchronize(cudaStream_t stream);
  • 参数:
    • stream – 流标识符
  • 返回值:
    • 成功 – 返回cudaSuccess
    • 失败 – 返回cudaErrorInvalidResourceHandle

cudaStreamCreateWithFlags()

  • 简述:创建一个新的异步的流,通过参数flags来设置流的属性
    • Create an asynchronous stream Creates a new asynchronous stream.
    • The flags argument determines the behaviors of the stream.
  • 声明:cudaError_t cudaStreamCreateWithFlags(cudaStream_t *pStream, unsigned int flags);
  • 参数:
    • pStream – 指向流标识符的指针
    • flags – 创建流的参数,有效的参数为:
      • cudaStreamDefault – 默认标识
      • cudaStreamNonBlocking – 异步流,异步于NULL流
  • 返回值:
    • 成功 – cudaSuccess
    • 失败 – cudaErrorInvalidValue

cudaGetDeviceCount()

  • 简述:获取可用算能设备的数量
  • 声明:cudaError_t cudaGetDeviceCount(int *count);
  • 参数:
    • count – 具有计算能力的设备数字
  • 返回值:
    • 成功 – cudaSuccess

cudaGetDevice()

  • 简述:返回当前正在使用的设备
  • 声明:cudaError_t cudaGetDevice(int *device);
  • 参数:
    • device – 正在工作的主机线程所执行的设备代码
  • 返回值:
    • 成功 – cudaSuccess
    • 失败 – cudaErrorInvalidValue

cudaSetDevice()

  • 简述:设置GPU运行的设备
  • 声明:cudaError_t cudaSetDevice(int device);
  • 参数:
    • device – 调用这个函数的主机线程要执行设备代码的设备
  • 返回值:
    • 成功 – cudaSuccess
    • 失败 – cudaErrorInvalidDevice | cudaErrorDeviceAlreadyInUse
  • 注意:
    • 随后任何设备由cudaMalloc(), cudaMallocPitch(), cudaMallocArray()申请的设备内存都会分配到对应device的物理设备
    • 任何主机线程通过cudaMallocHost(), cudaHostAlloc(), cudaHostRegister()申请的主机内存都会将它们的生命周期与设备device关联起来
    • 任何通过主机线程创建的流或事件都会和设备device关联起来
    • 任何通过主机线程由cudaLaunchKernel()发生的内核调用都会在设备device上执行
    • 这个调用可能在任何时间,由任何主机线程在任何设备上调用。
  • 返回值:
    • 成功 – cudaSuccess
    • 失敗 – cudaErrorInvalidDevice | cudaErrorDeviceAlreadyInUse

简介

  • HTTP协议理论基础知识

分块传输编码

  • 分块传输编码(Chunked transfer encoding)是超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由网页服务器发送给客户端应用( 通常是网页浏览器)的数据可以分成多个部分。分块传输编码只在HTTP协议1.1版本(HTTP/1.1)中提供。

  • 通常,HTTP应答消息中发送的数据是整个发送的,Content-Length消息头字段表示数据的长度。数据的长度很重要,因为客户端需要知道哪里是应答消息的结束,以及后续应答消息的开始。然而,使用分块传输编码,数据分解成一系列数据块,并以一个或多个块发送,这样服务器可以发送数据而不需要预先知道发送内容的总大小。通常数据块的大小是一致的,但也不总是这种情况。

  • 分块传输编码的原理

    • HTTP分块传输编码允许服务器为动态生成的内容维持HTTP持久链接。通常,持久链接需要服务器在开始发送消息体前发送Content-Length消息头字段,但是对于动态生成的内容来说,在内容创建完之前是不可知的
    • 分块传输编码允许服务器在最后发送消息头字段。对于那些头字段值在内容被生成之前无法知道的情形非常重要,例如消息的内容要使用散列进行签名,散列的结果通过HTTP消息头字段进行传输。没有分块传输编码时,服务器必须缓冲内容直到完成后计算头字段的值并在发送内容前发送这些头字段的值。
    • HTTP服务器有时使用压缩 (gzip或deflate)以缩短传输花费的时间。分块传输编码可以用来分隔压缩对象的多个部分。在这种情况下,块不是分别压缩的,而是整个负载进行压缩,压缩的输出使用本文描述的方案进行分块传输。在压缩的情形中,分块编码有利于一边进行压缩一边发送数据,而不是先完成压缩过程以得知压缩后数据的大小。
  • 分块传输编码的格式

    • 如果一个HTTP消息(包括客户端发送的请求消息或服务器返回的应答消息)的Transfer-Encoding消息头的值为chunked,那么,消息体由数量未定的块组成,并以最后一个大小为0的块为结束
    • 每一个非空的块都以该块包含数据的字节数(字节数以十六进制表示)开始,跟随一个CRLF (回车及换行),然后是数据本身,最后块CRLF结束。在一些实现中,块大小和CRLF之间填充有白空格(0x20)。
    • 最后一块是单行,由块大小(0),一些可选的填充白空格,以及CRLF。最后一块不再包含任何数据,但是可以发送可选的尾部,包括消息头字段
    • 消息最后以CRLF结尾

HTTP Content-Type

  • Content-Type(内容类型),一般是指网页中存在的 Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件,这就是经常看到一些 PHP 网页点击的结果却是下载一个文件或一张图片的原因。

  • Content-Type 标头告诉客户端实际返回的内容的内容类型。

  • 语法格式:

    1
    2
    Content-Type: text/html; charset=utf-8
    Content-Type: multipart/form-data; boundary=something
  • 常见的媒体格式类型如下:

    • text/html : HTML格式
    • text/plain :纯文本格式
    • text/xml : XML格式
    • image/gif :gif图片格式
    • image/jpeg :jpg图片格式
    • image/png:png图片格式
  • 以application开头的媒体格式类型:

    • application/xhtml+xml :XHTML格式
    • application/xml: XML数据格式
    • application/atom+xml :Atom XML聚合格式
    • application/json: JSON数据格式
    • application/pdf:pdf格式
    • application/msword : Word文档格式
    • application/octet-stream : 二进制流数据(如常见的文件下载)
    • application/x-www-form-urlencoded :
      中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
  • 另外一种常见的媒体格式是上传文件之时使用的:

  • multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式

HTTP 请求报文

HTTP 请求报文由请求行(Request Line)、请求头部(Headers)和请求主体(Body)三部分组成。下面是 HTTP 请求报文的一般格式:

1
2
3
4
5
6
<请求方法> <请求目标> <协议版本>
<请求头部字段>: <值>
<请求头部字段>: <值>
...
<空行>
<请求主体>

其中,各部分的含义如下:

  1. 请求方法(Request Method):表示客户端请求的动作类型,常见的方法有 GET、POST、PUT、DELETE 等。
  2. 请求目标(Request Target):指定请求的目标资源的位置,可以是一个 URL 或绝对路径。
  3. 协议版本(Protocol Version):指定所使用的 HTTP 协议的版本,通常是 HTTP/1.1 或 HTTP/2。
  4. 请求头部字段(Headers):包含了关于请求的附加信息,每个字段都以字段名和对应的值组成,每个字段占据一行。
  5. 空行:表示请求头部结束的标志,用于与请求主体进行分隔。
  6. 请求主体(Body):可选的,包含了实际要发送给服务器的数据,比如表单数据或上传的文件内容。

以下是一个示例 HTTP 请求报文:

1
2
3
4
5
6
POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 48

{"username": "john_doe", "password": "secretpassword"}

在上面的示例中:

  • 请求方法为 POST,请求目标为 /api/users,协议版本为 HTTP/1.1
  • 请求头部包含了 HostContent-TypeContent-Length 等字段,用于指定主机名、请求体的类型和长度等信息。
  • 空行表示请求头部结束。
  • 请求主体为一个 JSON 格式的字符串,包含了用户名和密码的数据。

请注意,请求报文中的每一行都应该以回车符(\r)和换行符(\n)作为行结束符号。请求头部字段和值之间使用冒号和空格进行分隔(例如 Content-Type: application/json)。

以上是 HTTP 请求报文的基本结构,实际的请求报文内容和格式会根据具体的请求需求和要求而有所不同。


HTTP 协议文档

HTTP协议的官方文档是由互联网工程任务组(IETF)发布的一系列文档,主要包括以下两个规范:

  1. HTTP/1.1规范:HTTP/1.1是当前广泛使用的HTTP协议版本。其规范文档定义了HTTP/1.1协议的语义、语法、请求方法、状态码、首部字段、缓存机制等各个方面的内容。HTTP/1.1的规范文档由RFC 2616定义。

    可以通过以下链接访问HTTP/1.1的规范文档:

  2. HTTP/2规范:HTTP/2是HTTP协议的下一代版本,旨在提供更高的性能和效率。它引入了二进制协议、多路复用、头部压缩、服务器推送等新特性。HTTP/2的规范文档由RFC 7540定义。

    可以通过以下链接访问HTTP/2的规范文档:

除了上述主要的HTTP协议规范文档外,IETF还发布了其他与HTTP相关的文档,包括扩展协议、安全性、代理、缓存等方面的规范和建议。

可以通过IETF的官方网站访问这些文档的在线版本:

注意:HTTP/1.1的规范文档(RFC 2616)发布于1999年,并于2014年被废弃。后续对HTTP/1.1的修订和更新工作由HTTPbis工作组负责,并将最新的规范文档发布为一系列独立的RFC文档。因此,最新的HTTP/1.1规范文档应该参考HTTPbis工作组发布的相关文档。


HTTP 表单是什么

HTTP表单(HTTP form)是一种用于在Web应用程序中收集和提交用户数据的机制。它是基于HTTP协议的一种数据传输方式,通过在Web页面上展示给用户一组输入字段(例如文本框、复选框、下拉列表等),用户可以在这些字段中输入数据,并将数据提交到服务器进行处理。

HTTP表单常用于实现用户注册、登录、搜索、提交评论等交互性操作。用户在表单中输入数据后,通过点击提交按钮,表单数据将被封装为HTTP请求发送给服务器。服务器接收到请求后,可以解析表单数据,并根据需要进行相应的处理,例如保存数据到数据库、执行搜索操作、生成动态内容等。

HTTP表单通过使用HTML(Hypertext Markup Language)和一些特定的表单元素来定义和呈现表单。HTML表单元素包括<form>标签、<input>标签、<select>标签、<textarea>标签等,它们用于定义表单的结构、各种输入字段以及提交按钮。

在提交表单时,可以使用不同的HTTP请求方法,常见的有GET和POST方法。GET方法将表单数据附加在URL的查询字符串中,而POST方法将表单数据包含在请求的主体中。这取决于表单的性质和数据的敏感性。

在服务器端,可以使用不同的技术(如PHP、Python、Java等)来处理接收到的表单数据。这些技术提供了解析和处理表单数据的函数、类或库,使开发人员能够轻松地处理表单提交的数据,并进行相应的业务逻辑操作。

总结起来,HTTP表单是一种用于在Web应用程序中收集和提交用户数据的机制,它利用HTML表单元素定义和呈现表单,通过HTTP协议将用户输入的数据发送到服务器进行处理。


HTTP协议 表单数据

HTTP 协议中的表单数据是通过 POST 请求或 GET 请求来传输的,具体的格式和处理方式如下:

  1. GET 请求传输表单数据:

    • 表单数据会被附加在 URL 的查询字符串中,即通过 URL 参数传递。
    • 数据以键值对的形式出现,使用key=value的格式。
    • 多个键值对之间使用&符号进行分隔。
  2. POST 请求传输表单数据:

    • 表单数据会被放置在请求体中,并通过 Content-Type 头部指定数据的编码方式,常见的编码方式有 application/x-www-form-urlencoded 和 multipart/form-data。
    • application/x-www-form-urlencoded 编码方式:
      • 表单数据以键值对的形式出现,使用key=value的格式。
      • 多个键值对之间使用&符号进行分隔。
    • multipart/form-data 编码方式:
      • 表单数据会以多部分的形式进行传输。
      • 每个部分都有自己的头部信息,包括 Content-Disposition 和 Content-Type。
      • 表单字段会出现在各自的部分中,以字段名作为标识。
      • 文件上传时,文件数据会以二进制形式出现在对应的部分中。

对于服务器端的处理,常见的 Web 框架会提供相应的解析和处理表单数据的功能,开发者可以根据框架的文档和要求来编写处理表单数据的代码。

需要注意的是,HTTP 协议的表单数据传输并不加密,因此在传输敏感信息时应使用安全的 HTTPS 协议来保护数据的安全性。

application/x-www-form-urlencoded 详解

application/x-www-form-urlencoded是一种常见的MIME类型,用于在HTTP请求中传输表单数据。它是一种URL编码的数据格式,适用于通过HTTP POST请求将表单数据发送到服务器。

详细解释application/x-www-form-urlencoded的含义如下:

  1. 数据格式:application/x-www-form-urlencoded表示表单数据以URL编码的形式进行传输。它使用特定的编码规则将表单字段和值进行编码,并使用”&”符号分隔字段。例如,假设有一个表单字段name的值为John Doe,编码后的数据格式将是name=John%20Doe

  2. 字符编码:application/x-www-form-urlencoded使用URL编码对特殊字符进行转义。这样可以确保数据能够在HTTP请求中正确传输,不会被解析为URL的特殊字符或者参数分隔符。

  3. 请求方法:application/x-www-form-urlencoded通常与HTTP POST请求方法一起使用。表单数据会被封装在请求的主体部分,并以key=value的形式进行传输。服务器端可以根据具体的编程语言或框架,解析这些键值对数据并进行处理。

  4. Content-Type头部:在HTTP请求中,Content-Type头部用于指定请求主体的媒体类型。当使用application/x-www-form-urlencoded传输表单数据时,可以设置Content-Type头部为application/x-www-form-urlencoded来标识数据格式。

使用示例:

1
2
3
4
5
POST /submit-form HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

name=John%20Doe&email=johndoe%40example.com&message=Hello%20World

在上述示例中,我们通过HTTP POST请求将表单数据发送到example.com/submit-form路径。请求头部指定了Content-Type: application/x-www-form-urlencoded,表示表单数据以application/x-www-form-urlencoded格式进行传输。请求主体部分包含了编码后的表单数据。

总结:application/x-www-form-urlencoded是一种URL编码的数据格式,常用于HTTP POST请求中传输表单数据。它使用特定的编码规则对字段和值进行编码,并以key=value的形式传输数据。服务器端可以根据Content-Type头部为application/x-www-form-urlencoded来解析和处理这些数据。


HTTP协议 响应报文

HTTP协议中的响应报文包含多个字段,每个字段都有特定的作用和含义。以下是HTTP响应报文中常见的字段及其详细解释:

  1. 状态行(Status Line):状态行包含了HTTP协议的版本号、状态码和状态消息。它的格式如下:

    1
    HTTP/1.1 200 OK

    其中,HTTP/1.1表示使用的HTTP版本号,200是状态码,OK是状态消息。

  2. 响应头(Response Headers):响应头包含了关于响应的附加信息。它的格式为字段名: 值,每个字段占据一行。常见的响应头字段包括:

    • Content-Type:指定响应体的媒体类型,例如text/html表示HTML文档。
    • Content-Length:指定响应体的长度,以字节为单位。
    • Date:指定响应发送的日期和时间。
    • Server:指定服务器的软件名称和版本号。
    • Set-Cookie:用于在客户端存储会话信息的HTTP Cookie。
  3. 空行(Blank Line):空行用于分隔响应头和响应体。

  4. 响应体(Response Body):响应体包含了实际的响应数据,例如网页的HTML内容或者文件的内容。

需要注意的是,除了以上常见的字段之外,HTTP响应报文还可以包含其他自定义的字段,具体的字段内容和含义可以根据应用程序和服务器的需求进行定义和解析。


HTTP Cache-Control

HTTP的Cache-Control字段用于控制缓存的行为,指示缓存如何处理响应以及如何在将来的请求中使用缓存。Cache-Control字段可以在HTTP请求头和响应头中使用。

在HTTP请求头中,Cache-Control字段用于指示客户端对服务器的请求希望如何进行缓存。常见的指令包括:

  • no-cache:表示客户端要求服务器每次都提供最新的响应,不使用缓存副本。
  • no-store:表示客户端和中间缓存都不应该存储请求或响应的任何副本。
  • max-age=<seconds>:表示响应的有效时间,以秒为单位。客户端可以在这个时间内使用缓存副本而不向服务器发起新的请求。
  • min-fresh=<seconds>:表示客户端希望在指定的时间内获取新的响应,而不使用缓存。如果缓存的响应的新鲜度低于指定的时间,客户端将向服务器发起新的请求。
  • max-stale[=<seconds>]:表示客户端允许使用过期的缓存副本,即使超过了缓存的有效时间。可选的秒数表示允许的最大过期时间。
  • only-if-cached:表示客户端只接受缓存的响应,不向服务器发起新的请求。

在HTTP响应头中,Cache-Control字段用于指示缓存如何处理响应。常见的指令包括:

  • public:表示响应可以被任何缓存(包括客户端和中间缓存)缓存。
  • private:表示响应只能被客户端缓存,中间缓存不能缓存该响应。
  • no-cache:表示响应可以被缓存,但必须先与服务器确认其有效性。
  • no-store:表示响应不能被缓存,客户端和中间缓存都不应该存储该响应。
  • max-age=<seconds>:表示响应的有效时间,以秒为单位。
  • s-maxage=<seconds>:表示响应在共享缓存(如代理服务器)中的有效时间,以秒为单位。

以上是Cache-Control字段的一些常见指令和用法,可以根据具体的需求和情况进行灵活设置,以实现更好的缓存控制和性能优化。


HTTP Cache-control must-revalidate

HTTP头字段”Cache-Control: must-revalidate”用于指示客户端在使用缓存响应之前必须与服务器进行重新验证,即使缓存的响应具有新鲜的过期时间。

当响应中包含”Cache-Control: must-revalidate”指令时,意味着缓存的响应在未经服务器重新验证之前不应被视为有效。客户端必须向服务器发送一个条件请求(通常是带有”If-Modified-Since”或”If-None-Match”头字段),以检查缓存的响应是否仍然有效。

如果服务器以304 Not Modified状态码响应,表示缓存的响应仍然有效,客户端可以使用缓存副本。然而,如果服务器响应了新版本的资源或不同的状态码,客户端需要相应地更新其缓存。

“Cache-Control: must-revalidate”指令在确保缓存的响应是最新且准确的情况下非常有用。通过要求重新验证,它有助于保持客户端和服务器之间的数据一致性。

以下是带有”Cache-Control: must-revalidate”指令的HTTP响应头的示例:

1
2
3
4
HTTP/1.1 200 OK
Cache-Control: must-revalidate
Content-Type: text/html
Content-Length: 1024

在上述示例中,”Cache-Control: must-revalidate”头字段指示客户端在使用缓存响应之前必须重新验证。

需要注意的是,”must-revalidate”只是Cache-Control头字段的一个指令,还可以有其他指令,如”max-age”或”no-cache”等,用于修改缓存行为。这些指令的组合可以提供对特定资源的缓存处理进行精细控制。


HTTP Cache-control max-age

HTTP头字段”Cache-Control: max-age”用于指定缓存的响应在被认为过期之前的最长时间(以秒为单位)。

“max-age”指令用于定义响应的新鲜度期限,即客户端可以在该期限内使用缓存的响应而无需向服务器发送请求。如果一个资源的缓存副本在”max-age”指定的时间内仍然有效,则客户端可以使用该缓存副本而无需向服务器进行请求。

以下是一个使用”Cache-Control: max-age”的HTTP响应头的示例:

1
2
3
4
HTTP/1.1 200 OK
Cache-Control: max-age=3600
Content-Type: text/html
Content-Length: 1024

在上述示例中,”Cache-Control: max-age=3600”指示客户端可以在3600秒(1小时)内使用该缓存的响应而无需向服务器发送请求。如果在此期限内发起的请求与此资源相关,则客户端可以直接使用缓存副本。

“max-age”指令是相对于响应的日期和时间来计算的。当客户端接收到带有”max-age”指令的响应时,它会根据响应的日期和时间以及”max-age”指定的秒数来计算出响应的有效期限。

需要注意以下几点:

  1. “max-age”指令优先级高于其他指令,如”no-cache”或”must-revalidate”。如果同时存在这些指令,”max-age”会覆盖它们。

  2. “max-age”指令不依赖于服务器的时间,而是依赖于响应中的日期和时间。这可以避免因为客户端和服务器之间的时钟不一致而导致缓存失效。

  3. 如果同时存在”Expires”头字段和”max-age”指令,”max-age”优先级更高。”max-age”用于指定相对时间,而”Expires”用于指定绝对时间。

总结起来,”Cache-Control: max-age”指令用于指定缓存的响应在被认为过期之前的最长时间。客户端可以在指定的时间内使用缓存副本而无需发送请求。这可以提高性能并减轻服务器负载,特别是对于不经常更改的静态资源。


HTTP Pragma

HTTP Pragma字段是一种HTTP头字段,用于向服务器传递特定的指令或控制信息。它是HTTP/1.0版本中引入的,目的是为了提供与缓存相关的指令。

在HTTP请求头中,Pragma字段可以用于向服务器发送请求指令。在实践中,Pragma字段很少被使用,因为在HTTP/1.1中引入了更强大和灵活的Cache-Control字段来管理缓存。常见的Pragma指令包括:

  • no-cache:表示客户端要求服务器每次都提供最新的响应,不使用缓存副本。与Cache-Control中的no-cache指令功能类似。

在HTTP响应头中,Pragma字段用于向客户端传递响应的指令或信息。在实践中,Pragma字段同样很少被使用,因为Cache-Control字段已经提供了更广泛和强大的缓存控制功能。

需要注意的是,HTTP/1.1规范中建议不再使用Pragma字段来控制缓存,而是使用Cache-Control字段。因此,当处理HTTP协议时,应优先考虑Cache-Control字段,而将Pragma字段视为过时和不推荐使用的。


HTTP Expires

HTTP Expires字段是一种响应头字段,用于指定响应的过期时间。它告诉客户端在过期时间之前可以直接使用缓存的响应,而无需向服务器发起新的请求。

Expires字段的值是一个日期时间,表示响应的过期时间点。客户端可以在该时间点之前使用缓存的响应。如果客户端在过期时间之后发起请求,缓存将被视为无效,客户端需要向服务器获取最新的响应。

例如,下面是一个使用Expires字段的响应头示例:

1
2
3
HTTP/1.1 200 OK
Content-Type: text/html
Expires: Thu, 17 Jun 2023 12:00:00 GMT

在这个例子中,Expires字段的值是”Thu, 17 Jun 2023 12:00:00 GMT”,表示响应的过期时间为2023年6月17日12:00:00 GMT。在过期时间之前,客户端可以直接使用缓存的响应。

需要注意的是,Expires字段的缺点是它使用的是服务器的时间,而客户端的时间可能与服务器的时间不一致。为了解决这个问题,HTTP/1.1引入了Cache-Control字段,其中的max-age指令提供了更可靠的缓存过期时间控制,并以秒为单位指定相对时间。相比之下,Expires字段更适用于在HTTP/1.0环境下进行缓存控制。在HTTP/1.1中,Cache-Control字段被认为是更优先和更可靠的缓存控制机制。


HTTP Content-Type

HTTP Content-Type是一种HTTP头字段,用于指示传输的实体(如请求体或响应体)的媒体类型(Media Type)。它告诉接收方如何解析和处理实体的内容。

Content-Type字段通常出现在HTTP请求头和响应头中。在请求头中,它指示客户端发送的实体的媒体类型。在响应头中,它指示服务器返回的实体的媒体类型。

Content-Type字段的值通常由两部分组成:

  1. 主类型(Main Type):表示实体的大类,例如文本(text)、图像(image)、音频(audio)、视频(video)、应用程序(application)等。
  2. 子类型(Sub Type):表示主类型下的具体细分,例如文本可以是纯文本(plain)或HTML文档(html),图像可以是JPEG(jpeg)或PNG(png)等。

Content-Type字段的格式如下:

1
Content-Type: 主类型/子类型

例如,下面是一些常见的Content-Type值示例:

  • 文本类型:
    • 纯文本:text/plain
    • HTML文档:text/html
    • XML文档:text/xml
  • 图像类型:
    • JPEG图像:image/jpeg
    • PNG图像:image/png
    • GIF图像:image/gif
  • 音频类型:
    • MP3音频:audio/mpeg
    • WAV音频:audio/wav
  • 视频类型:
    • MPEG视频:video/mpeg
    • MP4视频:video/mp4
  • 应用程序类型:
    • JSON数据:application/json
    • PDF文档:application/pdf

通过Content-Type字段,客户端和服务器可以彼此了解和解释实体的内容类型,从而正确处理和解析数据。这对于正确显示网页、处理文件上传、进行API通信等非常重要。

HTTP Content-Type multipart/x-mixed-replace

HTTP Content-Type字段中的multipart/x-mixed-replace是一种特殊的媒体类型,用于在单个HTTP响应中连续发送多个部分(或实体)。它常用于实时流式传输或服务器推送,其中每个部分都代表一个独立的数据块或事件。

multipart/x-mixed-replace的工作原理是,服务器发送一系列的部分,每个部分都有自己的Content-Type和内容。接收方(通常是浏览器)会逐个解析和处理这些部分,并按照其各自的Content-Type进行相应的处理。

每个部分由一个唯一的分隔符(boundary)分隔。分隔符是一个随机生成的字符串,用于标识部分的起始和结束。在响应中,Content-Type字段中的boundary参数指定了分隔符。

下面是一个示例HTTP响应头,展示了使用multipart/x-mixed-replace的格式:

1
2
HTTP/1.1 200 OK
Content-Type: multipart/x-mixed-replace; boundary=boundary123

在上述示例中,multipart/x-mixed-replace指定了响应使用该媒体类型。boundary=boundary123指定了分隔符为”boundary123”。

响应体的内容将按照以下格式进行发送:

1
2
3
4
5
6
7
8
9
--boundary123
Content-Type: image/jpeg

<JPEG image data>
--boundary123
Content-Type: text/plain

Some text data
--boundary123--

在这个示例中,首先发送了一个JPEG图像部分,然后是一个纯文本部分。每个部分都以--boundary123开头,并以--boundary123--表示结束。

客户端会解析每个部分,并根据各自的Content-Type进行相应的处理,例如显示图像或显示文本数据。

multipart/x-mixed-replace的特点是,在接收到一个部分后,客户端会立即丢弃之前接收到的部分。这使得它适用于实时更新的场景,如视频流、监控摄像头等,因为客户端只处理最新的部分,而不会保留之前的部分。

注意:由于multipart/x-mixed-replace在HTTP/1.1中没有官方标准,不同的实现可能会有差异。因此,对于具体使用情况,最好查阅相关文档或参考实现的要求。


HTTP Content-Length

HTTP Content-Length是一个HTTP响应头字段,用于指示响应体的长度(以字节为单位)。它告诉接收方在接收完指定长度的数据后停止接收,可以用于确定完整的响应体的大小。

Content-Length字段的值是一个十进制整数,表示响应体的字节长度。例如,Content-Length: 1024表示响应体的长度为1024字节。

使用Content-Length字段的好处是接收方可以根据指定的长度来正确读取和处理响应体。这在处理固定长度的数据时非常有用,如文件下载、二进制数据传输等。

以下是一个使用Content-Length字段的HTTP响应头示例:

1
2
3
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 4096

在这个示例中,Content-Length字段的值为4096,表示响应体的长度为4096字节。

需要注意的是,Content-Length字段仅适用于具有确定长度的响应体。对于动态生成的或以流式传输的方式提供的响应,Content-Length字段可能无法准确指示响应体的总长度。在这种情况下,通常使用分块传输编码(chunked transfer encoding)或其他适当的机制来指示响应体的传输方式和结束。

另外,Content-Length字段通常不会出现在HTTP请求头中,因为请求体的长度往往由客户端动态确定,并在请求头中使用Transfer-Encoding或其他字段进行传输长度的指示。


HTTP Connection

HTTP Connection字段(或头字段)是一个HTTP请求头和响应头中的字段,用于指示是否需要在请求或响应完成后关闭TCP连接或保持连接打开。

在HTTP/1.0中,Connection字段的值可以是”keep-alive”或”close”,分别表示保持连接打开或关闭连接。如果使用”keep-alive”,则表示客户端或服务器希望保持TCP连接打开,以便在后续请求或响应中复用该连接。如果使用”close”,则表示请求或响应完成后关闭连接。

以下是一个示例,在HTTP/1.0中使用Connection字段的请求头和响应头:

请求头:

1
2
3
GET /example HTTP/1.0
Host: www.example.com
Connection: keep-alive

响应头:

1
2
3
4
HTTP/1.0 200 OK
Content-Type: text/html
Content-Length: 1024
Connection: close

在HTTP/1.1中,Connection字段的语义有所变化。它成为一个逐跳(hop-by-hop)头字段,用于指示仅对单个连接有效,而不是整个传输链路。常见的Connection字段值包括:

  • “keep-alive”:表示请求或响应后保持连接打开,以便进行后续请求或响应的复用。
  • “close”:表示请求或响应完成后关闭连接。
  • 其他特定的头字段:表示请求或响应中有特定的头字段需要逐跳处理,如”Upgrade”、”Transfer-Encoding”等。

以下是一个示例,在HTTP/1.1中使用Connection字段的请求头和响应头:

请求头:

1
2
3
GET /example HTTP/1.1
Host: www.example.com
Connection: keep-alive

响应头:

1
2
3
4
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1024
Connection: close

需要注意的是,HTTP/1.1默认使用持久连接(persistent connection),即默认情况下会保持连接打开。如果不希望保持连接打开,可以在请求头或响应头中使用”Connection: close”指示关闭连接。

在HTTP/2中,Connection字段被废弃,取而代之的是使用专门的帧(frame)来管理连接的生命周期。连接的打开和关闭由协议自身管理,而不需要应用层显式地指示。

总之,HTTP Connection字段用于指示是否保持连接打开或关闭,具体的语义和行为取决于HTTP协议版本和字段的值。


HTTP 响应报文字段Server

HTTP响应报文中的Server字段是一个可选的响应头字段,用于指示提供HTTP响应的服务器软件或应用程序的名称和版本信息。

Server字段的值通常是服务器软件的名称和版本号的组合。例如,Server: Apache/2.4.29表示使用的是Apache HTTP Server软件的2.4.29版本。

这个字段可以提供有关服务器的一些信息,但并不是强制要求的,因此服务器可以选择是否在响应中包含Server字段。

以下是一个示例HTTP响应头,展示了使用Server字段的格式:

1
2
3
4
HTTP/1.1 200 OK
Server: Apache/2.4.29
Content-Type: text/html
Content-Length: 1024

在上述示例中,Server: Apache/2.4.29指示服务器使用的是Apache HTTP Server软件的2.4.29版本。

需要注意的是,由于Server字段提供了有关服务器的信息,因此在安全性方面需要谨慎处理。恶意用户可能会利用这些信息来进行攻击或针对特定的服务器漏洞。

出于安全性的考虑,一些服务器管理员可能选择隐藏或修改Server字段的值,以减少被攻击的风险。这可以通过配置服务器软件或使用专门的安全模块来实现。

总结:Server字段是HTTP响应报文中的一个可选字段,用于指示提供响应的服务器软件或应用程序的名称和版本信息。它提供了有关服务器的一些信息,但在安全性方面需要注意保护。


HTTP Access-Control-Allow-Origin

HTTP Access-Control-Allow-Origin是一个HTTP响应头字段,用于指示允许访问资源的跨域请求源。

在跨域资源共享(CORS)机制中,浏览器会在发送跨域请求时向服务器发送一个预检请求(OPTIONS请求),以确定是否允许该跨域请求。服务器在预检请求的响应中可以包含Access-Control-Allow-Origin字段,用于指定允许访问资源的来源。

Access-Control-Allow-Origin字段的值可以是以下三种情况之一:

  1. 具体的源:可以指定一个具体的来源,例如Access-Control-Allow-Origin: https://www.example.com,表示只允许来自https://www.example.com的请求访问资源。

  2. 通配符(*):可以使用通配符来表示允许任何来源的请求访问资源,例如Access-Control-Allow-Origin: *

  3. 不包含该字段:如果响应中不包含Access-Control-Allow-Origin字段,或者该字段的值为空,浏览器会阻止跨域请求访问资源。

需要注意的是,服务器返回的Access-Control-Allow-Origin字段仅在预检请求的响应中才起作用。对于实际的跨域请求,浏览器会根据预检请求中的结果来判断是否允许访问资源。

以下是一个示例,展示了Access-Control-Allow-Origin字段的使用:

1
2
3
4
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.example.com
Content-Type: text/html
Content-Length: 1024

在上述示例中,Access-Control-Allow-Origin字段的值为https://www.example.com,表示只允许来自该来源的请求访问资源。

通过设置Access-Control-Allow-Origin字段,服务器可以控制哪些跨域请求被允许访问资源,提供了一种基于服务器端的跨域访问控制机制。


HTTP Access-Control-Allow-Methods

HTTP Access-Control-Allow-Methods是一个HTTP响应头字段,用于指示服务器支持的跨域请求方法。

在跨域资源共享(CORS)机制中,浏览器会发送一个预检请求(OPTIONS请求)到服务器,以确定是否允许特定跨域请求。预检请求中会包含一个Access-Control-Request-Method字段,用于指示实际请求所使用的方法(如GET、POST、PUT、DELETE等)。

服务器在预检请求的响应中可以包含Access-Control-Allow-Methods字段,用于指示服务器支持的跨域请求方法。

Access-Control-Allow-Methods字段的值是一个逗号分隔的HTTP方法列表,表示服务器允许的跨域请求方法。例如,Access-Control-Allow-Methods: GET, POST, PUT表示服务器允许使用GET、POST和PUT方法的跨域请求。

以下是一个示例,展示了Access-Control-Allow-Methods字段的使用:

1
2
3
4
5
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Methods: GET, POST, PUT
Content-Type: text/html
Content-Length: 1024

在上述示例中,Access-Control-Allow-Methods字段的值为GET, POST, PUT,表示服务器支持GET、POST和PUT方法的跨域请求。

通过设置Access-Control-Allow-Methods字段,服务器可以明确指定支持的跨域请求方法,从而对跨域请求进行细粒度的控制。

需要注意的是,Access-Control-Allow-Methods字段只在预检请求的响应中起作用。对于实际的跨域请求,浏览器会根据预检请求的结果来判断是否允许使用特定的请求方法。

此外,服务器还可以使用其他相关的响应头字段,如Access-Control-Allow-Headers和Access-Control-Allow-Credentials,来进一步控制和配置跨域资源共享。

总结:HTTP Access-Control-Allow-Methods是一个HTTP响应头字段,用于指示服务器支持的跨域请求方法。通过设置该字段,服务器可以明确指定允许的跨域请求方法,实现跨域资源共享的细粒度控制。


简介

  • TensorRT 常用函数

C++ createInferBuilder() 函数 详解

在C++中,createInferBuilder() 函数通常是与NVIDIA TensorRT库相关的,用于创建一个 TensorRT 的推理构建器(InferBuilder)。TensorRT是一个用于深度学习推理的高性能推理引擎,由NVIDIA提供。

以下是对 createInferBuilder() 函数的详解:

1
nvinfer1::IBuilder* createInferBuilder(nvinfer1::ILogger& logger);

在这里,createInferBuilder() 函数返回一个 nvinfer1::IBuilder* 指针,它指向 TensorRT 推理构建器(InferBuilder)。让我们对参数和返回值进行详细解释:

  • 参数:

    • nvinfer1::ILogger& logger:一个 TensorRT 提供的日志记录器(ILogger)引用。日志记录器用于在 TensorRT 运行时记录各种信息,包括警告、错误等。通过传递一个日志记录器引用,您可以捕获 TensorRT 的运行时消息。
  • 返回值:

    • nvinfer1::IBuilder*:返回一个指向 TensorRT 推理构建器的指针。该指针可以用于配置和构建推理引擎。

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <NvInfer.h>

int main() {
// 创建一个简单的日志记录器
nvinfer1::ILogger* logger = new nvinfer1::Logger(nvinfer1::ILogger::Severity::kINFO);

// 使用 createInferBuilder() 创建 TensorRT 推理构建器
nvinfer1::IBuilder* builder = createInferBuilder(*logger);

// 在这里可以配置和构建推理引擎

// 释放资源
builder->destroy();
delete logger;

return 0;
}

在上面的示例中,首先创建了一个简单的日志记录器,然后使用 createInferBuilder() 函数创建了一个 TensorRT 推理构建器。接下来,您可以使用该构建器配置和构建推理引擎。最后,记得释放资源,包括销毁构建器和释放日志记录器。

简介

  • tensorrt库

tensorrt GA和EA的区别

  • EA版本代表抢鲜体验,在正式发布之前
  • GA代表通用性,表示稳定版,经过全面测试。

TensorRT加速

  • TensorRT是英伟达开发针对自身显卡来优化的推理加速框架,TensorRT主要做了两件事情,来提升模型的运行速度
    • TensorRT降精度推理支持INT8和FP16的计算。深度学习网络在训练时,通常使用 32 位或 16 位数据。TensorRT则在网络的推理时选用不这么高的精度,达到加速推断的目的。
    • TensorRT对于网络结构进行了重构,把一些能够合并的运算合并在了一起,针对GPU的特性做了优化。因为显卡是英伟达出的没有谁比英伟达更懂自己的显卡,自然就推出了针对自己GPU的加速工具TensorRT。一个深度学习模型,在没有优化的情况下,比如一个卷积层、一个偏置层和一个reload层,这三层是需要调用三次cuDNN对应的API,但实际上这三层的实现完全是可以合并到一起的,TensorRT会对一些可以合并网络进行合并。

C++ tensorrt是什么

TensorRT(Tensor Runtime)是由 NVIDIA 开发的用于高性能深度学习推理(inference)的库。它主要用于加速深度学习模型在 NVIDIA GPU 上的推理阶段,以提高模型的实时性能。

TensorRT 提供了许多优化技术,以减少深度学习模型推理的计算和内存开销。它通过使用精确的数值计算、层融合(layer fusion)、动态 Tensor 网络(dynamic tensor network)、深度学习加速库(cuDNN)、自动混合精度(automatic mixed precision)等技术,提供高效的推理加速。

TensorRT 支持多种深度学习框架,包括 TensorFlow、PyTorch、ONNX(Open Neural Network Exchange)等。你可以使用 TensorRT 将经过训练的深度学习模型转换为 TensorRT 可以高效执行的格式,以利用 GPU 进行快速推理。

以下是 TensorRT 的一些主要特性:

  1. 快速推理: TensorRT 通过 GPU 加速深度学习推理,提供高性能的模型执行。

  2. 精确数值计算: TensorRT 支持对模型进行精确数值计算,以在不牺牲模型精度的情况下提高推理速度。

  3. 层融合: TensorRT 可以自动融合相邻层,减少计算和内存开销。

  4. 支持多种框架: TensorRT 提供用于与多种深度学习框架集成的工具,包括 TensorFlow、PyTorch、ONNX 等。

  5. 动态 Tensor 网络: TensorRT 支持构建动态的 Tensor 网络,适用于需要在推理期间动态改变形状的模型。

TensorRT 的使用通常涉及到以下几个步骤:

  1. 创建和训练模型: 使用深度学习框架创建和训练深度学习模型。

  2. 模型转换: 使用 TensorRT 提供的工具将训练好的模型转换为 TensorRT 可以高效执行的格式。

  3. 加载和推理: 在 C++ 或其他支持的语言中加载 TensorRT 格式的模型并进行推理。

TensorRT 是用于加速深度学习推理的强大工具,尤其在实时应用、嵌入式系统和边缘计算等场景中具有重要作用。

C++ tensorrt 库 详解

TensorRT 是 NVIDIA 提供的深度学习推理库,专为在 NVIDIA GPU 上进行深度学习模型的加速而设计。TensorRT 提供了一系列工具和优化技术,以在推理阶段获得高性能、低延迟的模型执行。以下是关于 TensorRT 库的一些详细信息:

TensorRT 的主要特性:

  1. 快速推理: TensorRT 通过 GPU 加速深度学习推理,提供高性能的模型执行。它针对 NVIDIA GPU 的架构进行了优化,充分利用了 GPU 的并行计算能力。

  2. 精确数值计算: TensorRT 支持深度学习模型的精确数值计算,同时考虑到模型推理过程中的计算精度和效率。

  3. 层融合: TensorRT 可以自动融合相邻层,减少计算和内存开销。这种层融合技术有助于减小模型的计算图,提高推理性能。

  4. 多精度计算: TensorRT 支持多种精度计算,包括 FP32、FP16 和 INT8。可以根据模型的需求选择合适的精度,以在保持精度的同时提高计算性能。

  5. 层和操作库: TensorRT 提供了包括卷积、归一化、激活函数等在内的一系列层和操作库,以满足不同模型结构的推理需求。

  6. 支持多种框架: TensorRT 支持多种深度学习框架,包括 TensorFlow、PyTorch、ONNX 等。通过支持多种框架,TensorRT 提供了灵活性,使用户能够在不同框架之间无缝转换和使用模型。

  7. 动态 Tensor 网络: TensorRT 支持构建动态的 Tensor 网络,适用于需要在推理期间动态改变形状的模型。

TensorRT 的使用流程:

  1. 创建和训练模型: 使用深度学习框架(例如 TensorFlow、PyTorch)创建和训练深度学习模型。

  2. 模型转换: 使用 TensorRT 提供的工具将训练好的模型转换为 TensorRT 可以高效执行的格式。这通常涉及到使用 TensorRT 的 Python API 进行模型转换。

  3. TensorRT 推理引擎构建: 使用 C++ 或其他支持的语言,在运行时加载 TensorRT 格式的模型并构建 TensorRT 推理引擎。推理引擎是 TensorRT 用于高效执行模型的核心组件。

  4. 输入数据传递和推理: 将输入数据传递给 TensorRT 推理引擎,并执行推理操作。TensorRT 会在 GPU 上对输入数据进行并行计算,并输出模型的推理结果。

  5. 清理资源: 在推理完成后,释放分配的 GPU 和 CPU 资源,以确保良好的系统资源管理。

TensorRT C++ API 使用示例:

以下是一个简化的 TensorRT C++ API 使用示例,展示了加载 TensorRT 模型并进行推理的基本步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <fstream>
#include <NvInfer.h>

int main() {
// 初始化 TensorRT
nvinfer1::IRuntime* runtime = nvinfer1::createInferRuntime(gLogger);

// 从文件中加载 TensorRT 模型
const char* trtModelPath = "path/to/your/model.plan";
std::ifstream trtModelStream(trtModelPath, std::ios::binary);
trtModelStream.seekg(0, trtModelStream.end);
const int modelSize = trtModelStream.tellg();
trtModelStream.seekg(0, trtModelStream.beg);
std::vector<char> modelData(modelSize);
trtModelStream.read(modelData.data(), modelSize);

nvinfer1::ICudaEngine* engine = runtime->deserializeCudaEngine(modelData.data(), modelSize, nullptr);

// 创建执行上下文
nvinfer1::IExecutionContext* context = engine->createExecutionContext();

// 准备输入数据和输出缓冲区
float inputData[INPUT_SIZE]; // INPUT_SIZE 是模型期望的输入大小
float outputData[OUTPUT_SIZE]; // OUTPUT_SIZE 是模型期望的输出大小

// 分配 GPU 内存并将输入数据传输到 GPU
void* gpuInputBuffer;
cudaMalloc(&gpuInputBuffer, INPUT_SIZE * sizeof(float));
cudaMemcpy(gpuInputBuffer, inputData, INPUT_SIZE * sizeof(float), cudaMemcpyHostToDevice);

// 分配 GPU 内存用于输出
void* gpuOutputBuffer;
cudaMalloc(&gpuOutputBuffer, OUTPUT_SIZE * sizeof(float));

// 执行推理
context->execute(1, &gpuInputBuffer, &gpuOutputBuffer, nullptr, nullptr);

// 将输出数据从 GPU 复制回主机
cudaMemcpy(outputData, gpuOutputBuffer, OUTPUT_SIZE * sizeof(float), cudaMemcpyDeviceToHost);

// 处理输出数据...

// 清理资源
cudaFree(gpuInputBuffer);
cudaFree(gpuOutputBuffer);
context->destroy();
engine->destroy();
runtime->destroy();

return 0;
}

请注意,实际的使用场景可能会更加复杂,具体的实现可能需要更多的代码,特别是在处理不同类型和形状的输入数据时。确保查阅 TensorRT 的文档和示例,以获得详细的使用说明。

简介

计算机网络协议是在计算机网络中进行通信和数据交换的规则和约定集合。它定义了计算机网络中数据的格式、传输方式、错误检测和纠正、网络设备的工作方式以及网络中各个实体之间的通信流程等。

下面是一些常见的计算机网络协议:

  1. TCP/IP协议:TCP/IP协议是互联网的核心协议,它包括TCP(传输控制协议)和IP(Internet协议)两个主要协议。TCP协议提供可靠的、面向连接的数据传输,而IP协议负责在网络中寻址和路由数据包。

  2. HTTP协议:HTTP(超文本传输协议)是应用层协议,用于在Web浏览器和Web服务器之间传输超文本文档。它是无状态的,通过请求-响应模型进行通信。

  3. HTTPS协议:HTTPS(安全超文本传输协议)是在HTTP基础上加入了安全层的协议,使用SSL/TLS加密算法保证通信的安全性。

  4. FTP协议:FTP(文件传输协议)用于在客户端和服务器之间传输文件。它支持文件上传、下载、删除和重命名等操作。

  5. SMTP协议:SMTP(简单邮件传输协议)用于在网络中发送和传输电子邮件。它定义了电子邮件的格式和传输方式。

  6. POP3协议:POP3(邮局协议版本3)是用于接收电子邮件的协议,它允许用户从邮件服务器上下载邮件。

  7. DNS协议:DNS(域名系统)协议用于将域名解析为相应的IP地址。它提供了域名到IP地址之间的映射服务。

  8. ICMP协议:ICMP(Internet控制消息协议)用于在IP网络中传输错误报文和状态信息。它用于网络故障诊断和管理。

以上只是一小部分常见的计算机网络协议,实际上还有许多其他的协议和标准,用于不同的网络通信需求和场景。这些协议共同构成了计算机网络的基础,使得不同设备和系统能够进行有效的通信和数据交换。

Web服务

Web服务原理和技术

  • Web Service,是面向服务计算模式的一部分,用于互联网上的信息交换

  • Web Service的主题非常广泛,非常复杂,涉及许多概念,协议和技术,而且它们源自不同的学科,诸如分布式计算系统,计算机网络,计算机体系结构,中间件,软件工程,编程语言,数据库系统,安全性和知识表示等,并且它们以各种错综复杂的方式组合在一起。

  • 此外,还需要一些处理业务流程与组织的新技术,这些新技术既要发现企业存在的问题,又要在实际应用中解决这些问题

维基百科

  • Web服务是一种服务导向架构的技术,通过标准的Web协议提供服务,目的是保证不同平台的应用服务可以互操作

  • 根据W3C的定义,Web服务(Web service)应当是一个软件系统,用以支持网络间不同机器的互动操作

  • 网络服务通常是许多应用程序接口(API)所组成的,它们透过网络,例如国际互联网(Internet)的远程服务器端,执行客户所提交服务的请求

  • 尽管W3C的定义涵盖诸多相异且无法介分的系统,不过通常我们指有关于主从式架构(Client-server)之间根据SOAP协议进行传递XML格式消息

  • 无论定义还是实现,Web服务过程中会由服务器提供一个机器可读的描述(通常基于WSDL)以辨识服务器所提供的WEB服务

    • SOAP, 一个基于XML的可扩展消息信封格式,需同时绑定一个网络传输协议。这个协议通常是HTTP或HTTPS,但也可能是SMTP或XMPP。
    • WSDL, 一个XML格式文档,用以描述服务端口访问方式和使用协议的细节。通常用来辅助生成服务器和客户端代码及配置信息。
    • UDDI, 一个用来发布和搜索WEB服务的协议,应用程序可借由此协议在设计或运行时找到目标WEB服务。
    • 这些标准由这些组织制订:W3C负责XML、SOAP及WSDL;OASIS负责UDDI。

阮一峰网络日志

  • 想要理解Web service,必须先理解什么是Service(服务)

  • 传统上,我们把计算机后台程序(Daemon)提供的功能,称为”服务”(service)

  • 比如,让一个杀毒软件在后台运行,它会自动监控系统,那么这种自动监控就是一个”服务”。

  • 通俗地说,”服务”就是计算机可以提供的某一种功能

  • 根据来源的不同,”服务”又可以分成两种:

    • 一种是”本地服务”(使用同一台机器提供的服务,不需要网络)
    • 另一种是”网络服务”(使用另一台计算机提供的服务,必须通过网络才能完成)
  • 举例来说

    • 我现在有一批图片,需要把它们的大小缩小一半。那么,我们可以把”缩放图片”看成是一种服务。
    • 你可以使用”本地服务”,在自己计算机上用软件缩小图片,也可以使用”网络服务”,将图片上传到某个网站,让服务器替你缩小图片,完成后再通过网络送回给你。
    • 这就好比,一件事你可以自己做,也可以交给另一个人去做。肚子饿了,你可以自己做饭,也可以打电话去订一份比萨,让店家替你做好送上门。
  • “网络服务”(Web Service)的本质,就是通过网络调用其他网站的资源

  • 如果一个软件的主要部分采用了”网络服务”,即它把存储或计算环节”外包”给其他网站了,那么我们就说这个软件属于Web Service架构

  • Web Service架构的基本思想,就是尽量把非核心功能交给其他人去做,自己全力开发核心功能。

使用Web服务的方式

  • Web服务实际上是一组工具,并有多种不同的方法调用之。

  • 三种最普遍的手段是:远程过程调用(RPC),服务导向架构(SOA)以及表述性状态转移(REST)。

  • 远程过程调用

    • Web服务提供一个分布式函数或方法接口供用户调用,这是一种比较传统的方式。通常,在WSDL中对RPC接口进行定义(类似于早期的XML-RPC)。
    • 尽管最初的Web服务广泛采用RPC方式部署,但针对其过于紧密之耦合性的批评声也随之不断。这是因为RPC式WEB服务实质上是利用一个简单的映射,以把用户请求直接转化成为一个特定语言编写的函数或方法。
    • 如今,多数服务提供商认定此种方式在未来将难有作为,在他们的推动下,WS-I基本协议集(WS-I Basic Profile)已不再支持远程过程调用。
  • 服务导向架构

    • 现在,业界比较关注的是遵从服务导向架构(Service-oriented architecture,SOA)概念来构筑WEB服务。
    • 在服务导向架构中,通讯由消息驱动,而不再是某个动作(方法调用)。这种WEB服务也被称作面向消息的服务
    • SOA式WEB服务得到了大部分主要软件供应商以及业界专家的支持和肯定。
    • 作为与RPC方式的最大差别,SOA方式更加关注如何去连接服务而不是去特定某个实现的细节。WSDL定义了联络服务的必要内容
  • 表述性状态转移

    • 表述性状态转移式(Representational state transfer,REST)Web服务类似于HTTP或其他类似协议,它们把接口限定在一组广为人知的标准动作中(比如HTTP的GET、PUT、DELETE)以供调用。
    • 此类WEB服务关注与那些稳定的资源的互动,而不是消息或动作
    • 此种服务可以通过WSDL来描述SOAP消息内容,通过HTTP限定动作接口;或者完全在SOAP中对动作进行抽象。

WebSocket

维基百科

  • WebSocket是一种网络传输协议,可在单个TCP连接上进行全双工通信,位于OSI模型的应用层。

  • WebSocket协议在2011年由IETF标准化为RFC 6455,后由RFC 7936补充规范。Web IDL中的WebSocket API由W3C标准化

  • WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。

  • 在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输

简介

  • WebSocket是一种与HTTP不同的协议。两者都位于OSI模型的应用层,并且都依赖于传输层的TCP协议

  • 为了实现兼容性,WebSocket握手使用HTTP Upgrade头从HTTP协议更改为WebSocket协议。

  • WebSocket协议支持Web浏览器(或其他客户端应用程序)与Web服务器之间的交互,具有较低的开销,便于实现客户端与服务器的实时数据传输

  • 服务器可以通过标准化的方式来实现,而无需客户端首先请求内容,并允许消息在保持连接打开的同时来回传递。

  • 通过这种方式,可以在客户端和服务器之间进行双向持续对话。

  • 通信通过TCP端口80或443完成,这在防火墙阻止非Web网络连接的环境下是有益的。

  • 另外,Comet之类的技术以非标准化的方式实现了类似的双向通信

    • Comet是一种用于web的推送技术,能使服务器实时地将更新的信息传送到客户端,而无须客户端发出请求,
    • 目前有两种实现方式,长轮询和iframe流。
  • 与HTTP不同,WebSocket提供全双工通信。

  • 此外,WebSocket还可以在TCP之上实现消息流。TCP单独处理字节流,没有固有的消息概念。

  • 在WebSocket之前,使用Comet可以实现全双工通信。

  • 但是Comet存在TCP握手和HTTP头的开销,因此对于小消息来说效率很低。WebSocket协议旨在解决这些问题。

  • WebSocket协议规范将ws(WebSocket)和wss(WebSocket Secure)定义为两个新的统一资源标识符(URI)方案,分别对应明文和加密连接。

  • 除了方案名称和片段ID(不支持#)之外,其余的URI组件都被定义为此URI的通用语法。

背景

  • 早期,很多网站为了实现推送技术,所用的技术都是轮询

  • 推送技术(英语:Push technology),或者说是是一种基于Internet通信方式的服务器推送,其中要求通信的请求是由发布者或中央服务器发起。与 pull/get 形成对比,额外消息传输的相应一般由接收者或客户端发起。

  • 轮询,是指由浏览器每隔一段时间(如每秒)向服务器发出HTTP请求,然后服务器返回最新的数据给客户端。

  • 这种传统的模式带来很明显的缺点,即:

    • 浏览器需要不断的向服务器发出请求,然而HTTP请求与回复可能会包含较长的头部,其中真正有效的数据可能只是很小的一部分,所以这样会消耗很多带宽资源
  • 比较新的轮询技术是Comet。这种技术虽然可以实现双向通信,但仍然需要反复发出请求。而且在Comet中普遍采用的HTTP长连接也会消耗服务器资源

  • 在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯

  • Websocket与HTTP和HTTPS使用相同的TCP端口,可以绕过大多数防火墙的限制。默认情况下,Websocket协议使用80端口;运行在TLS之上时,默认使用443端口。

握手协议

  • WebSocket 是独立的、创建在TCP上的协议。

  • Websocket 通过 HTTP/1.1 协议的101状态码进行握手。

  • 为了创建Websocket连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称握手(Handshaking)。

  • 典型的WebSocket握手请求

    • 客户端请求:
      1
      2
      3
      4
      5
      6
      7
      8
      GET /chat HTTP/1.1
      Host: server.example.com
      Upgrade: websocket
      Connection: Upgrade
      Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
      Origin: http://example.com
      Sec-WebSocket-Protocol: chat, superchat
      Sec-WebSocket-Version: 13
    • 服务器回应:
      1
      2
      3
      4
      5
      HTTP/1.1 101 Switching Protocols
      Upgrade: websocket
      Connection: Upgrade
      Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
      Sec-WebSocket-Protocol: chat
  • 字段说明:

    • Connection必须设置Upgrade,表示客户端希望连接升级。
    • Upgrade字段必须设置Websocket,表示希望升级到Websocket协议。
    • Sec-WebSocket-Key是随机的字符串,服务器端会用这些数据来构造出一个SHA-1的信息摘要。
      • 把“Sec-WebSocket-Key”加上一个特殊字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,然后计算SHA-1摘要,之后进行Base64编码,将结果做为“Sec-WebSocket-Accept”头的值,返回给客户端。
      • 如此操作,可以尽量避免普通HTTP请求被误认为Websocket协议。
    • Sec-WebSocket-Version 表示支持的Websocket版本。RFC6455要求使用的版本是13,之前草案的版本均应当弃用。
    • Origin字段是必须的。如果缺少origin字段,WebSocket服务器需要回复HTTP 403 状态码(禁止访问)。
    • 其他一些定义在HTTP协议中的字段,如Cookie等,也可以在Websocket中使用

阮一峰网络日志

  • 已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?

  • 因为 HTTP 协议有一个缺陷:通信只能由客户端发起。

  • 举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。

  • 这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。

  • 我们只能使用”轮询“:每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室

  • 轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。

  • 因此,工程师们一直在思考,有没有更好的方法。WebSocket 就是这样发明的

简介

  • WebSocket 协议在2008年诞生,2011年成为国际标准。所有浏览器都已经支持了

  • 它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种

  • 其他特点包括:

    • 建立在 TCP 协议之上,服务器端的实现比较容易。
    • 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器
    • 数据格式比较轻量,性能开销小,通信高效。
    • 可以发送文本,也可以发送二进制数据。
    • 没有同源限制,客户端可以与任意服务器通信。
    • 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL

Web3和区块链

  • 互联网迄今有两个阶段:Web 1.0 和 Web 2.0

  • 下一个阶段自然就是 Web 3.0(简称 Web3)

  • Web 1.0 阶段,用户是单纯的内容消费者,内容由网站提供,网站让你看什么,你就看什么,典型例子就是新闻门户网站。

  • Web 2.0 阶段,用户是内容的生产者,网站只是一个向用户提供服务的平台,典型的 Web 2.0 平台有维基百科、抖音、微信等等

  • Web3 的很多特征还不明确,但是国外很多文章认为,它跟区块链有关。

    • Web 1.0 是用户读取互联网,Web 2.0 是用户写入互联网,Web3 是用户生活在互联网
    • 娱乐、工作、学习、消费、交际,都在网上发生。网站不仅提供服务,还是一个生活空间,人们的一部分生活可以在网上完成
    • 在教育网站学习,在会议网站开会,在社交网站交友,在游戏网站玩乐。所有网站共同构成了一个无所不包的网络世界
  • 所有网站的生活功能,如果能够连在一起,让用户无缝地从一个场景进入另一个场景,那就构成了一个虚拟世界。这大概就是最近很热门的元宇宙(metaverse)的样子

  • 到了那个阶段,用户不再是访问网站,而是进入虚拟世界,过着虚拟的线上生活

  • 这样的虚拟世界,显然不能被一家或几家巨头垄断,否则我们就会依赖这些巨头,不得不遵守它制定的规则。当你的生活都在虚拟世界里面,某一天巨头突然决定关闭你的账号,你的虚拟人生岂不嘎然而止了!

  • 这就是很多人提出 Web3 应该是分布式的原因。这有两层含义:

    • 它不是集中式的,就没有单一的公司可以控制它;
    • 任何一种服务都有多家提供商,通过分布式协议连起来,用户可以极小的成本,从一个提供商转移到另一个服务商。
  • 如果 Web3 确定是分布式的,那么区块链简直就是天然的基础设施。因为区块链是分布式数据库的一种实现,本身就是分布式的,而且信息一旦上链,就无法修改

  • 这解决了 Web3 的核心问题:不同网站的数据交换。

  • 不同网站都可以自由读写同一个用户的数据,并且这些数据是可以信赖的,从而保证用户进入另一个网站,就好像进入同一个世界的不同地区

  • 一旦 Web3 构建于区块链之上,按照区块链的设计,用户需要有一个数字钱包,它是你在虚拟世界的身份证和银行账户。

  • 你的身份、财产、消费,都通过这个数字钱包来标识。网站通过数字钱包的 ID,来识别你是谁

  • 我翻开谷歌一查,这WEB3.0就没有一个正常的解释, 歪歪斜斜的搜索结果每页上都写着 “去中心化” “分布式” “用户拥有” “区块链” “虚拟经济” “价值重塑” “Token” 几个大词,我横竖睡不着,仔细看了半夜,才从字缝里看出来,满本上都写着两个字“炒币”

简介

  • 网络基础知识和基础理论

网关是什么

在计算机网络中,网关(Gateway)是连接两个不同网络的设备或软件。它充当连接不同网络之间的桥梁,使得数据可以在这些网络之间传输。网关可以是硬件设备,如路由器,也可以是运行特定网络协议的计算机或服务器。

网关的作用是转发数据包,根据目标地址将数据从一个网络传输到另一个网络。它还可以执行一些额外的功能,如网络地址转换(NAT)、防火墙安全过滤、代理服务等。网关在网络通信中扮演着重要的角色,使得不同网络之间能够有效地通信和交换信息。

网关详解

网关是指在计算机网络中连接两个不同网络的设备或软件。它在网络中扮演着转换数据、连接不同网络并进行数据交换的重要角色。

以下是关于网关的详细解释:

  1. 连接不同网络: 网关允许不同类型或不同协议的网络进行通信。它可以连接局域网(LAN)与广域网(WAN)、不同厂商的设备、不同网络协议(如以太网、Wi-Fi、蓝牙等)的网络之间。

  2. 数据转发: 网关接收从源网络发来的数据包,并根据目标地址的信息将这些数据包转发到目标网络中。它根据特定的路由规则和网络协议进行数据包的转发。

  3. 协议转换: 网关可以执行协议转换的功能,将一个网络协议的数据转换为另一个网络协议的数据。这种转换允许不同类型的网络进行交流,即使它们使用不同的通信标准和协议。

  4. 安全性: 网关通常包含安全功能,比如防火墙和网络地址转换(NAT)。防火墙可以监控和控制数据包的流量,确保网络安全。NAT 可以隐藏网络内部设备的真实 IP 地址,增强网络的安全性。

  5. 路由功能: 网关可以根据路由表或配置的路由规则来决定数据包的最佳传输路径,以便有效地将数据包从源网络传输到目标网络。

  6. 代理服务: 网关可以提供代理服务,允许客户端通过网关访问互联网。代理服务还可以对互联网上的请求进行缓存和过滤,提高网络性能和安全性。

总的来说,网关在计算机网络中扮演着非常重要的角色,它连接和协调不同网络之间的通信,同时提供了一些安全和管理功能,确保网络通信的顺畅和安全。

uri 详解

URI(Uniform Resource Identifier)是一种用于标识和定位资源的字符串表示形式。它是互联网上广泛使用的标准,用于唯一地标识资源,包括网页、图片、视频、文件等。URI 是由 RFC 3986(通用资源标识符:通用语法)定义的。

URI 的一般格式为:scheme:[//authority]path[?query][#fragment]

其中各部分的含义如下:

  1. Scheme(协议):表示资源的访问协议,如 httphttpsftp 等。它通常用于指定资源的访问方式。例如:http://www.example.com

  2. Authority(权限):表示资源的权限部分,包括主机名和可选的端口号。它通常用于指定资源所在的服务器或主机。例如:www.example.com:8080

  3. Path(路径):表示资源在服务器上的路径。它通常用于指定资源在服务器文件系统中的位置。例如:/path/to/resource

  4. Query(查询):表示资源的查询部分,用于传递参数给资源。它通常用于向服务器传递额外的信息。例如:?id=123&name=example

  5. Fragment(片段):表示资源的片段标识符,用于指定资源的某个特定片段。它通常用于定位 HTML 页面中的某个锚点。例如:#section1

示例:

下面是几个 URI 的示例:

  1. https://www.example.com/index.html

    • Scheme: https
    • Authority: www.example.com
    • Path: /index.html
  2. ftp://ftp.example.com/files/data.zip

    • Scheme: ftp
    • Authority: ftp.example.com
    • Path: /files/data.zip
  3. https://www.example.com/search?q=uri+explanation

    • Scheme: https
    • Authority: www.example.com
    • Path: /search
    • Query: q=uri+explanation
  4. https://www.example.com/index.html#section2

    • Scheme: https
    • Authority: www.example.com
    • Path: /index.html
    • Fragment: #section2

URI 的重要性在于它提供了一种标准的方式来标识和定位互联网上的资源,使得用户可以通过统一的格式来访问和处理各种不同类型的资源。


url 详解

URL(Uniform Resource Locator)是一种具体的 URI(Uniform Resource Identifier),用于定位和标识互联网上的资源。URL 是由 RFC 3986(通用资源标识符:通用语法)定义的,它是 URI 的一种常见形式。

URL 的一般格式为:scheme://username:password@host:port/path?query#fragment

其中各部分的含义如下:

  1. Scheme(协议):表示资源的访问协议,如 httphttpsftp 等。它通常用于指定资源的访问方式。例如:https://www.example.com

  2. Username 和 Password(用户名和密码):表示资源的认证信息,用于访问受限资源时进行身份验证。它们是可选的,并用于提供访问资源所需的用户名和密码。例如:ftp://user:password@example.com

  3. Host 和 Port(主机名和端口号):表示资源所在的主机名和可选的端口号。它通常用于指定资源所在的服务器或主机。例如:https://www.example.com:8080

  4. Path(路径):表示资源在服务器上的路径。它通常用于指定资源在服务器文件系统中的位置。例如:/path/to/resource

  5. Query(查询):表示资源的查询部分,用于传递参数给资源。它通常用于向服务器传递额外的信息。例如:?id=123&name=example

  6. Fragment(片段):表示资源的片段标识符,用于指定资源的某个特定片段。它通常用于定位 HTML 页面中的某个锚点。例如:#section1

示例:

下面是几个 URL 的示例:

  1. https://www.example.com/index.html

    • Scheme: https
    • Host: www.example.com
    • Path: /index.html
  2. ftp://ftp.example.com/files/data.zip

    • Scheme: ftp
    • Host: ftp.example.com
    • Path: /files/data.zip
  3. https://www.example.com/search?q=url+explanation

    • Scheme: https
    • Host: www.example.com
    • Path: /search
    • Query: q=url+explanation
  4. https://www.example.com/index.html#section2

    • Scheme: https
    • Host: www.example.com
    • Path: /index.html
    • Fragment: #section2

URL 是互联网上资源的标准定位方式,它允许用户通过特定的地址来访问和处理不同类型的资源,如网页、图片、视频、文件等。

RPC 工作方式 详解

RPC(Remote Procedure Call,远程过程调用)的工作方式如下:

  1. 客户端调用: 客户端应用程序调用本地的客户端存根(Client Stub),就像调用本地函数一样。客户端存根负责将函数调用转化为网络消息。

  2. 消息传输: 客户端存根将封装好的消息通过网络发送到远程服务器。

  3. 服务器端接收: 远程服务器接收到客户端发送的消息。

  4. 服务器端存根处理: 服务器端存根(Server Stub)接收到消息后,解析出远程调用的函数、参数和其他必要信息。

  5. 函数调用: 服务器端存根调用本地的服务器函数,执行请求的操作。

  6. 结果返回: 服务器函数执行完毕后,将结果打包成消息发送回客户端。

  7. 客户端接收: 客户端接收到服务器返回的消息。

  8. 客户端存根处理: 客户端存根解析服务器返回的消息,提取结果数据。

  9. 结果返回给应用程序: 客户端存根将结果返回给客户端应用程序,应用程序继续执行后续的逻辑。

在这个过程中,RPC 的关键是将本地的函数调用转换为网络消息,并在远程服务器上执行相应的函数,然后将结果返回给客户端。这使得客户端和服务器之间的远程调用过程像本地函数调用一样简单和透明。

RPC 的实现通常包括以下几个组件:

  • 接口定义: 定义可远程调用的函数接口、参数和返回值的数据类型。这些接口通常使用 IDL(Interface Definition Language,接口定义语言)来描述。

  • 存根生成: 根据接口定义生成客户端和服务器端的存根(Stub)代码。存根代码负责将本地函数调用转换为网络消息,并将消息发送到对应的远程服务器。

  • 序列化和反序列化: 在远程调用过程中,参数和返回值需要在网络传输前进行序列化(编码),并在接收后进行反序列化(解码)。序列化将数据转换为可传输的格式,反序列化将传输的数据还原为可处理的形式。

  • 网络传输: 使用底层的网络通信协议(如 TCP/IP)在客户端和服务器之间进行消息传输。这通常涉及消息的封装、发送、接收和解析。

  • 错误处理: RPC 也包含错误处理机制,例如处理网络故障、超时、服务不可用等情况。当远程调用失败或出现异常时,错误信息可以被传递回客户端进行处理。

需要注意的是,具体的 RPC 实现可能有所不同,不同的 RPC 框架和协议会有各自的特点和机制。这些框架提供了更高级的抽象和功能,使得分布式系统开发更加方便和高效。

希望这些详解能够帮助您更好地理解 RPC 的工作方式!如果您有更多问题,请随时提问。

RPC 详解

RPC(Remote Procedure Call,远程过程调用)是一种通信协议和编程模型,用于实现分布式系统中不同节点之间的远程调用。它允许在不同计算机或进程之间像调用本地函数一样调用远程函数,隐藏了底层网络通信的细节。

以下是关于 RPC 的详解:

  1. 远程调用: RPC 允许客户端应用程序调用位于远程服务器上的函数,就像调用本地函数一样。客户端应用程序不需要关心底层的网络通信和远程函数的具体实现细节。

  2. 编程模型: RPC 提供了一种编程模型,使得开发人员能够以类似本地函数调用的方式编写分布式应用程序。开发人员可以定义接口和函数签名,并在客户端和服务器上实现相应的逻辑。

  3. 接口定义: 在 RPC 中,接口定义起着关键的作用。接口定义描述了可供远程调用的函数及其参数和返回值的数据类型。接口定义通常使用 IDL(Interface Definition Language,接口定义语言)来描述,如 Protocol Buffers、IDL、Thrift 等。

  4. 存根和代理: 在使用 RPC 时,需要生成客户端和服务器端的存根(Stub)和代理(Proxy)代码。存根代码负责将远程调用转换为网络消息并发送给服务器,而代理代码负责接收远程调用请求并将其转发给本地函数。

  5. 序列化和反序列化: 在进行远程调用时,参数和返回值需要进行序列化和反序列化。序列化将数据转换为可以在网络上传输的格式,而反序列化将接收到的数据还原为可处理的形式。

  6. 网络传输: RPC 使用底层的网络通信协议(如 TCP/IP)来实现远程调用的传输。客户端通过网络发送请求消息给服务器,服务器接收请求消息并执行相应的函数,然后将结果返回给客户端。

  7. 错误处理: RPC 也涉及错误处理机制。当远程调用失败或出现异常时,RPC 会返回适当的错误码或异常信息给客户端,以便进行错误处理和恢复。

RPC 在分布式系统中广泛应用,用于实现不同节点之间的协作和通信。它提供了一种方便和透明的方式来调用远程函数,使得分布式应用程序开发更加简化和高效。

常见的 RPC 框架包括 gRPC、Apache Thrift、JSON-RPC、XML-RPC 等。这些框架提供了不同的功能和特性,可以根据具体需求选择合适的 RPC 框架。

希望这些详解能帮助您更好地理解 RPC!如果您有更多问题,请随时提问。

RPC 是什么

RPC(Remote Procedure Call,远程过程调用)是一种通信协议和编程模型,用于实现分布式系统中不同节点之间的远程调用。它使得在不同计算机或进程之间能够像调用本地函数一样调用远程函数,隐藏了底层网络通信的细节。

以下是关于 RPC 的一些详解:

  1. 远程调用:RPC 允许应用程序在不同的计算机或进程之间进行远程调用。客户端应用程序可以像调用本地函数一样调用远程服务器上的函数,而无需了解底层的网络通信细节。

  2. 编程模型:RPC 提供了一种编程模型,使得开发人员能够以类似本地函数调用的方式编写分布式应用程序。开发人员可以定义接口和函数签名,并在客户端和服务器上实现相应的逻辑。

  3. 通信协议:RPC 使用特定的通信协议来实现远程调用。常见的 RPC 协议包括 gRPC、Apache Thrift、JSON-RPC、XML-RPC 等。这些协议定义了消息的格式、序列化和网络传输的方式。

  4. 序列化:在 RPC 中,参数和返回值需要在客户端和服务器之间进行序列化和反序列化。序列化是将数据转换为可传输的格式,反序列化是将传输的数据还原为可处理的形式。

  5. 网络通信:RPC 通过底层的网络通信实现远程调用。客户端通过网络发送请求消息给服务器,服务器接收请求消息并执行相应的函数,然后将结果返回给客户端。

  6. 跨语言支持:RPC 可以支持多种编程语言之间的远程调用。通过使用通用的 RPC 协议和序列化机制,不同语言的应用程序可以相互通信和调用。

  7. 分布式系统:RPC 在分布式系统中广泛应用,用于实现不同节点之间的协作和通信。它可以用于构建大规模、高可靠性的分布式应用程序架构。

RPC 是一种常见的分布式系统通信模型,它简化了分布式应用程序的开发过程,使得不同节点之间的远程调用更加方便和透明。

希望这些详解对 RPC 有所帮助!如果您有更多问题,请随时提问。

TLS 详解

TLS(Transport Layer Security)是一种用于保护网络通信安全性的加密协议。它建立在传输层协议(如 TCP)之上,用于在客户端和服务器之间创建安全的通信通道。以下是关于 TLS 的详解:

  1. 安全通信:TLS 的主要目标是确保通信的机密性、完整性和身份验证。它使用加密算法对数据进行加密,以防止未经授权的访问者获取敏感信息。同时,TLS 还使用消息摘要和数字签名等技术来保证数据的完整性,防止数据被篡改。

  2. 握手过程:TLS 使用握手过程来建立安全连接。在握手过程中,客户端和服务器之间进行协商,包括选择加密算法、交换密钥、进行身份验证等。握手过程涉及多个步骤,例如协议版本协商、证书交换、密钥协商和密钥确认等。

  3. 证书和公钥基础设施(PKI):TLS 使用数字证书来实现身份验证和密钥交换。数字证书由受信任的证书颁发机构(CA)签发,包含服务器的公钥和其他身份信息。客户端可以验证服务器证书的有效性,以确保与合法服务器建立连接。

  4. 加密算法:TLS 支持多种加密算法,用于保护通信数据的机密性。常见的加密算法包括对称加密算法(如AES)、非对称加密算法(如RSA)和哈希算法(如SHA)。在握手过程中,客户端和服务器协商选择适合的加密算法和密钥长度。

  5. 版本和演进:TLS 有多个版本,包括 TLS 1.0、TLS 1.1、TLS 1.2 和 TLS 1.3。每个版本都有不同的功能和安全性。TLS 1.3 是最新的版本,引入了许多改进和安全增强,提供更快的握手速度和更强的密码套件。

  6. 应用场景:TLS 广泛应用于各种安全通信场景,如网上银行、电子商务、电子邮件、VPN(虚拟私人网络)等。它为通信双方提供了保护数据隐私和确保通信安全的机制,防止数据泄露、篡改和中间人攻击。

  7. HTTPS:TLS 在 Web 安全中起着重要的作用,它与 HTTP 协议结合形成 HTTPS(HTTP Secure)。HTTPS 使用 TLS 加密和身份验证来保护 Web 浏览器和服务器之间的数据传输,确保网站的安全性和用户的隐私。

TLS 是一种重要的安全协议,被广泛应用于保护网络通信的安全性。它提供了加密、身份验证和数据完整性保护的功能,为通信双方提供了安全可靠的通信通道。

希望这些详解对 TLS 有所帮助!如果您有更多问题,请随时提问。

TLS 是什么

TLS(Transport Layer Security)是一种用于保护网络通信安全性的加密协议。它是 SSL(Secure Sockets Layer)协议的继任者,并被广泛应用于互联网上的各种安全通信场景。

以下是关于 TLS 的一些详解:

  1. 安全通信:TLS 用于在网络通信中实现安全和私密的数据传输。它通过加密通信内容,确保数据在传输过程中不被窃听、篡改或伪造。

  2. 协议层:TLS 位于网络通信的传输层之上,与传输层协议(如 TCP)一起工作,为上层应用提供安全的通信通道。

  3. 加密和身份验证:TLS 使用加密算法对通信内容进行加密,确保数据的保密性。同时,TLS 还提供身份验证机制,用于验证通信双方的身份,并防止中间人攻击。

  4. 证书和密钥交换:TLS 使用数字证书来验证服务器的身份,并协商加密密钥。证书由受信任的证书颁发机构(CA)签发,包含服务器公钥和相关信息。

  5. 握手过程:TLS 通过握手过程建立安全连接。在握手过程中,客户端和服务器之间进行协议版本协商、身份验证、密钥交换和协商加密算法等操作,以建立共享密钥和参数。

  6. 支持的应用协议:TLS 不仅可以保护基于 TCP 的应用层协议(如 HTTP、SMTP、IMAP),还可以保护其他传输层协议,如 UDP 的 DTLS(Datagram Transport Layer Security)。

  7. 版本和演变:TLS 有多个版本,包括 TLS 1.0、TLS 1.1、TLS 1.2 和 TLS 1.3。每个版本都有不同的功能和安全性,随着时间的推移,TLS 协议不断演进以修复漏洞并提供更好的安全性。

TLS 在互联网上广泛应用于保护敏感数据的传输,如网上银行、电子商务、电子邮件等。它为通信双方提供了一种安全、私密和可靠的通信机制,防止数据泄露和篡改,保护用户隐私和信息安全。

希望这些详解对 TLS 有所帮助!如果您有更多问题,请随时提问。

SNTP server 详解

SNTP(Simple Network Time Protocol)服务器是一种用于提供时间同步服务的网络服务器。它基于网络通信协议,允许计算机和其他网络设备通过网络获取准确的时间信息。

以下是 SNTP 服务器的一些详解:

  1. 时间同步服务:SNTP 服务器的主要功能是提供时间同步服务。它接收来自客户端的时间同步请求,并返回准确的时间戳作为响应。客户端可以通过与 SNTP 服务器通信,获取服务器上的当前时间,并将本地时间与服务器时间进行校准,以确保计算机和网络设备的时间与参考时间保持一致。

  2. 网络时间协议:SNTP 服务器基于网络时间协议(NTP)标准或其简化版本。NTP 是一种用于在计算机网络中同步时间的协议,而SNTP 则是 NTP 的简化版本,去除了一些复杂的功能和算法,主要用于提供基本的时间同步服务。

  3. 时间源:SNTP 服务器通常连接到一个时间源,以获取准确的时间信息。时间源可以是国家时间标准机构(如NIST)的服务器,也可以是互联网上的其他可靠时间服务器。服务器通过与时间源进行通信,获取准确的时间,并将其提供给客户端。

  4. 时间精度:SNTP 服务器的时间精度取决于所使用的时间源和服务器的硬件和软件配置。一般情况下,SNTP 服务器可以提供较高的时间精度,通常在毫秒或亚毫秒级别。

  5. 应用场景:SNTP 服务器被广泛应用于需要时间同步的各种网络设备和系统中。它们包括计算机网络、服务器、路由器、交换机、工业自动化系统等。这些设备和系统需要保持时间一致性,以确保协调的操作、事件记录和一致的时间戳。

  6. 配置和管理:SNTP 服务器的配置和管理可以通过设置服务器软件或设备上的相关参数来完成。可以指定时间源、同步频率、服务器身份验证、时间校准方式等。

需要注意的是,SNTP 服务器是一种基本的时间同步服务,如果需要更高精度和更复杂的时间同步功能,可以考虑使用更强大的 NTP 服务器。

希望这些详解对 SNTP 服务器有所帮助!如果您有更多问题,请随时提问。

SNTP server 是什么

SNTP(Simple Network Time Protocol)服务器是一种提供时间同步服务的网络服务器。SNTP 是一种基于网络的时间同步协议,它允许计算机和其他网络设备通过网络获取准确的时间信息。

SNTP 服务器的主要功能是响应客户端的时间同步请求,并向客户端提供准确的时间戳。客户端可以通过与 SNTP 服务器进行通信,获取服务器上的当前时间,并将本地时间与服务器时间进行校准,以确保计算机和网络设备的时间与参考时间保持一致。

SNTP 服务器通常连接到一个时间源(如国家时间标准机构或互联网上的其他可靠时间服务器),以获取准确的时间信息。服务器可以使用各种时间同步方法,如网络协议(如NTP、SNTP)、GPS(全球定位系统)或其他时钟源,来确保提供精确的时间。

SNTP 服务器的应用场景包括网络中的各种设备和系统,例如计算机网络、服务器、路由器、交换机、工业自动化系统等,它们需要时间同步以进行协调的操作和事件记录。

需要注意的是,SNTP 是 NTP(Network Time Protocol)的简化版本,去除了一些复杂的功能和算法,主要用于提供基本的时间同步服务。如果需要更高精度和更复杂的时间同步功能,可以考虑使用 NTP 协议。

希望对 SNTP 服务器有了更好的理解!如果您有更多问题,请随时提问。

http://info.cern.ch/

http://info.cern.ch/ 是一个网站,它被认为是世界上第一个公开的网站。它由欧洲核子研究组织(CERN)的计算机科学家蒂姆·伯纳斯-李(Tim Berners-Lee)于1991年创建。这个网站最初是为了分享关于CERN项目的信息和文档,以及介绍万维网(World Wide Web)的概念和原理。

蒂姆·伯纳斯-李是万维网的发明者之一,他在CERN工作期间创建了第一个网页浏览器和服务器,并且将这些技术开放给了公众。这个网站的主页上展示了一些简单的超链接,以及一些关于万维网的介绍性文本。

虽然这个网站的内容相对简单,但它标志着万维网的起源,并且对互联网的发展产生了深远的影响。如今,CERN的网站已经发展成为一个包含大量科学研究和实验信息的综合性门户网站,而http://info.cern.ch/则作为万维网的历史遗迹被保留下来,以纪念万维网的诞生。

TCP 服务 和 HTTP 服务

TCP服务和HTTP服务都是基于TCP协议的网络服务,但它们在协议和功能上有一些区别。

TCP服务

  • TCP(传输控制协议)是一种面向连接的协议,用于在网络上可靠地传输数据。
  • TCP服务通过在服务器和客户端之间建立持久的双向通信连接来传输数据。
  • TCP服务通常基于自定义的应用层协议,可以通过定义特定的数据格式和通信规则来进行数据交换。
  • TCP服务可以是自定义的、专用的服务,用于在应用程序之间进行数据传输和通信。

HTTP服务

  • HTTP(超文本传输协议)是一种应用层协议,用于在 Web 上传输超文本文档和其他资源。
  • HTTP服务使用TCP作为传输协议,通过建立连接并使用HTTP协议进行通信。
  • HTTP服务使用请求-响应模型,客户端发送HTTP请求,服务器返回HTTP响应。
  • HTTP服务遵循特定的语法和规范,定义了请求方法(GET、POST等)、头部字段(如Content-Type、User-Agent等)和响应状态码(如200 OK、404 Not Found等)等。

总结:
TCP服务是一种通用的、自定义的数据传输服务,而HTTP服务是一种基于TCP的特定协议,用于在Web上进行文档和资源的传输。TCP服务可以用于构建各种自定义的应用程序通信,而HTTP服务则专注于Web应用程序的数据交换和传输。

简介

  • 常用的网络设备基础知识

网络交换机

  • 网络交换机(Network switch)是一种网络硬件,通过报文交换接收和转发数据到目标设备,它能够在计算机网络上连接不同的设备。一般也简称为交换机

  • 交换机是一种多端口的网桥,在数据链路层使用MAC地址转发数据。通过加入路由功能,一些交换机也可以在网络层转发数据,这种交换机一般被称为三层交换机或者多层交换机。

  • 以太网交换机是网络交换机最常见的形式。第一个以太网交换机由Kalpana公司(1994年被思科收购)推出。在其他类型的网络中,交换机也普遍存在,如光纤通道、异步传输模式和InfiniBand。

  • 中继器会在其所有端口转发相同的数据,让设备自行判断哪些是自己需要的数据,交换机则不同,它只会将数据转发到需要接收的设备

  • 工作原理

    • 交换机工作于OSI参考模型的第二层,即数据链路层。交换机内部的CPU会在每个端口成功连接时,通过将MAC地址和端口对应,形成一张MAC表。在今后的通讯中,发往该MAC地址的数据包将仅送往其对应的端口,而不是所有的端口。因此交换机可用于划分数据链路层广播,即冲突域;但它不能划分网络层广播,即广播域。
    • 交换机对数据包的转发是建立在MAC地址——物理地址基础之上的,对于IP网络协议来说,它是透明的,即交换机在转发数据包时,不知道也无须知道信源机和信宿机的IP地址,只需知其物理地址。
    • 交换机在操作过程当中会不断的收集资料去建立它本身的一个地址表,这个表相当简单,它说明了某个MAC地址是在哪个端口上被发现的,所以当交换机收到一个TCP/IP 数据包时,它便会查看该数据包的目的MAC地址,核对自己的地址表以确认应该从哪个端口把数据包发出去。由于这个过程比较简单,加上这功能由一崭新硬件进行——ASIC,因此速度相当快。一般只需几十微秒,交换机便可决定一个IP数据包该往哪里送
    • 如果目的地MAC地址不能在地址表中找到时,交换机会把IP 数据包“扩散”出去,即把它从每一个端口中提交去,就如交换机在处理一个收到的广播数据包时一样。二层交换机的弱点正是它处理广播数据包的手法不太有效,比方说,当一个交换机收到一个从TCP/IP工作站上发出来的广播数据包时,他便会把该数据包传到所有其他端口去,哪怕有些端口上连的是IPX或DECnet工作站。这样一来,非TCP/IP节点的带宽便会受到负面的影响,就算同样的TCP/IP节点,如果他们的子网跟发送那个广播数据包的工作站的子网相同,那么他们也会无缘无故地收到一些与他们毫不相干的网络广播,整个网络的效率因此会大打折扣
  • 工作方式

    • 收到某网段(设为A)MAC地址为X的计算机发给MAC地址为Y的计算机的数据包。交换机从而记下了MAC地址X在网段A。这称为学习(learning)。
    • 交换机还不知道MAC地址Y在哪个网段上,于是向除了A以外的所有网段转发该数据包。这称为泛洪(flooding)。
    • MAC地址Y的计算机收到该数据包,向MAC地址X发出确认包。交换机收到该包后,从而记录下MAC地址Y所在的网段
    • 交换机向MAC地址X转发确认包。这称为转发(forwarding)
    • 交换机收到一个数据包,查表后发现该数据包的来源地址与目的地址属于同一网段。交换机将不处理该数据包。这称为过滤(filtering)
    • 交换机内部的MAC地址-网段查询表的每条记录采用时间戳记录最后一次访问的时间。早于某个阈值(用户可配置)的记录被清除。这称为老化(aging)。
  • 对于全交换(full-switch)局域网,交换机每个端口只连接一台设备,因此不会发生碰撞。交换机也不需要做过滤

  • 工作在OSI不同层级的交换技术

  • 现代商业交换机主要使用以太网接口。提供多端口的二层桥接是以太网交换机的核心功能,而很多交换机也提供其他层级的服务,这种不仅仅提供了桥接功能的交换机也被称为多层交换机。多层交换机可以在许多层级上学习拓扑结构,也可以在一层或多层上进行转发。

  • 一层

    • 一层网络设备传输数据而不控制任何流量,比如集线器。任何进入端口数据包会被转发到除进入端口之外的其他所有端口。具体而言,即每个比特或码元被转发时是原封不动的。由于每个数据包被分发到所有端口,其冲突会影响到整个网络,进而限制了它的整体的能力。 到21世纪初,集线器和低端交换机的价格差异很小。[1]对于特定应用,集线器在一段时间内还是能够发挥作用的,比如给数据包分析器提供网络流量的副本。网络分流器还有交换机的端口镜像也可以实现同样功能
  • 二层

    • 二层交换机依据硬件地址(MAC 地址)在数据链路层(第二层)传送网络帧。 二层交换机对于路由器和主机是“透明的”,主要遵从802.1d 标准。该标准规定交换机通过观察每个端口的数据帧获得源MAC 地址,交换机在内部的高速缓存中建立MAC 地址与端口的映射表。当交换机接受的数据帧的目的地址在该映射表中被查到,交换机便将该数据帧送往对应的端口。如果它查不到,便将该数据帧广播到该端口所属虚拟局域网(VLAN)的所有端口,如果有回应数据包,交换机便将在映射表中增加新的对应关系。当交换机初次加入网络中时,由于映射表是空的,所以,所有的数据帧将发往虚拟局域网内的全部端口直到交换机“学习”到各个MAC 地址为止。这样看来,交换机刚刚启动时与传统的共享式集线器作用相似的,直到映射表建立起来后,才能真正发挥它的性能。这种方式改变了共享式以太网抢行的方式,如同在不同的行驶方向上铺架了立交桥,去往不同方向的车可以同时通行,因此大大提高了流量。从VLAN的角度来看,由于只有子网内部的节点竞争带宽,所以性能得到提高。主机1 访问主机2 同时,主机3 可以访问主机4 。当各个部门具有自己独立的服务器时,这一优势更加明显。但是这种环境正发生巨大的变化,因为服务器趋向于集中管理,另外,这一模式也不适合Internet的应用。不同VLAN之间的通讯需要通过路由器来完成,另外为了实现不同的网段之间通讯也需要路由器进行互连。
  • 三层

    • 三层交换机则可以处理第三层网络层协议,用于连接不同网段,通过对缺省网关的查询学习来建立两个网段之间的直接连接
    • 三层交换机可以实现路由器的全部或部分功能,但只能用于同一类型的局域网子网之间的互连。这样,三层交换机可以像二层交换机那样通过MAC地址标识数据包,也可以像传统路由器那样在两个局域网子网之间进行功能较弱的路由转发,它的路由转发不是通过软件来维护的路由表,而是通过专用的ASIC芯片处理这些转发;
  • 四层

    • 四层交换机可以处理第四层传输层协议,可以将会话与一个具体的IP地址绑定,以实现虚拟IP
  • 七层

    • 更加智能的交换器,可以充分利用频宽资源来过滤,识别和处理应用层数据转换的交换设备
  • 网络交换机带宽分为: 10Mb/s、100Mb/s、1Gb/s、10Gb/s、40Gb/s、100Gb/s。Mbps换算MB/s:1Mbps=0.125MB/s。

路由器

  • 路由器(Router)是将运算设备(例如电脑)及网络连线至其他网络的联网设备。路由器有三个主要功能,分别是

    • 确定路径:路由器可以决定从来源到目的地所采用的路径,这个作业称为路由。
    • 资料转传:路由器会将资料转传至所选路径的下一个设备,重复这个过程,最终资料可以抵达目的地。运算设备和路由器可能位于相同的网络或不同的网络。
    • 负载平衡:路由器有时会用多个不同路径,发送相同资料报文副本。其目的是为了减少因资料丢失而造成错误、并建立备援及管理流量。
  • 比较技术性的解释是路由器是种电信网络设备,提供路由与转送两种重要机制,

    • 可以决定报文由来源端到目的端所经过的路径(host到host之间的传输路径),这个过程称为路由;
    • 将路由器输入端的报文移送至适当的路由器输出端(在路由器内部进行),这称为转送。
  • 路由工作在OSI模型的第三层——即网络层,例如网际协议(IP)。

  • 路由器可连接两个以上个别网络的设备。

  • 由于位于两个或更多个网络的交汇处,从而可在它们之间传递分组(一种数据的组织形式)。路由器与交换机在概念上有一定重叠但也有不同:

    • 交换机泛指工作于任何网络层次的数据中继设备(尽管多指网桥),
    • 而路由器则更专注于网络层
  • 路由器与交换机有四个主要差别

    • 第一,路由器是OSI第三层的产品,而交換机则是第二层,第二层主要功能是将网络上各个电脑的MAC地址记在MAC地址表中,当局域网中的电脑要经过交換机去交换传递资料时,就查询交換机上的MAC地址表中的信息,并将报文发送给指定的电脑,而不会像第一层的产品(如集线器)发送给每台在网络中的电脑。
    • 第二,路由器能在多条路径中选择最佳的路径,提升交换数据的传输速率。在发送报文时,路由表会被一同发送,该表存储了前往某一网络的最佳路径,如该路径的“路由度量值”,参考路由表可获得这个过程的详细描述。
    • 第三,路由器可连接超过两个以上不同的网络,而交換机只能连接两个。
    • 第四,路由器具有IP分享器功能,主要是让多台设备用同一条ADSL/光纤宽带线路来上网,功能包括共享IP,宽带管理,自动分配IP等等,如在共享IP功能中,不同设备可共享同一个公共IP同时上网;在局域网中,路由器则会指定一组的Class C的私有IP,可让254台设备同时上网。
  • 路由器的种类

    • 边缘路由器(edge router)
      • 将设备连接到互联网的路由器。
    • 核心路由器
      • 如在ISP网络中,只负责与其他路由器之间传递数据
    • 单臂路由器(one-armed-router)
      • 一种特殊类型的路由器,可用来在多个虚拟局域网(Virtual LAN)之间传递数据包
      • 在无线ad-hoc网络中的每台主机自己进行路由和数据转发,而在有线网络中通常一个广播域就有一台路由器。
      • 近来,许多路由的功能被加入到局域网交换机(实质是高速网桥)上,从而创造出“三层交换机”,可以以接近线速的速度来转发流量。
      • 路由器也被当作Internet网关,主要用在小型网络中如家庭或小型办公室。这种设备使用的Internet连接往往是互联网宽带连接如线缆调制解调器和DSL。这种路由器连接两个网络,WAN和LAN并有自己的路由表。尽管在家庭应用中并不需要太多路由功能(因为只存在WAN和LAN),但这些小型路由器仍然支持路由信息协议。额外地,这种路由器还支持DHCP、网络地址转换、DMZ和防火墙功能,也有一些支持内容过滤和VPN。通常这种路由器和线缆或DSL调制解调器协同工作,但调制解调功能也可以内置在这种路由器中。这种路由器往往同时具有阻止特定外部请求的安全特性。
      • 大型的路由器一般安装在数据中心、电信公司或ISP的机房内。这些路由器将许多网络用大量的带宽连接起来。根据分工的不同,这些路由器可以支持路由协议中的几种,包括IS-IS、OSPF、IGRP、EIGRP、RIP、BGP。
    • 无线网络路由器
      • 无线网络路由器是一种用来连系有线和无线网络的通讯设备,它可以通过无线方式(如,Wi-Fi)连接终端设备(如,手机、笔记本电脑),进而建立计算机网络。
      • 有的电信运营商为客户安装宽带时会提供含有Wi-Fi的路由器,通过简单地设置拨号可以实现宽带的共享。
      • 无线方式较有线方式更易受环境影响。如,在户外使用无线,其速度可能受天气影响。
      • 其它的无线方式有:红外线、蓝牙、卫星微波等
    • 策略路由
      • 策略路由比常规路由更灵活,常规路由基于目标网络进行的数据包转发,策略路由则额外定义数据转发规则,包含策略与操作(路由图),如会检查该接口接收到的所有数据包,是否符合路由图中的策略。对不符合的进行处理;符合的则按路由图策略中,对应的操作进行处理

网关

  • 网关(Gateway)是计算机网络中的一种设备或服务器,用于连接不同网络或协议之间进行数据转发和处理。

  • 网关是一种能够在不同网络或协议之间进行数据交换的设备或服务器。网关可以实现不同网络之间的互联互通,也可以实现不同协议之间的转换和适配。网关可以根据不同的功能和层次进行分类,例如物理层网关、数据链路层网关、网络层网关、传输层网关、应用层网关等[1]。网关可以提供多种服务,例如路由、安全、负载均衡、缓存、压缩、加密、认证、授权、过滤、转码等

  • 网关的工作机制

    • 网关的工作机制与代理非常相似,它能够接收客户端的请求,并像拥有资源的源服务器一样对请求进行处理或转发。客户端可能无法察觉到通信目标是一个网关,而不是一个源服务器。网关可以根据不同的需求,对请求和响应进行不同的处理,例如修改请求头或响应头,改变请求方法或响应状态码,增加或删除请求参数或响应内容等[3]。网关还可以根据不同的协议,对数据进行编码或解码,例如将HTTP协议转换成FTP协议,或将TCP协议转换成UDP协议等。
  • 应用场景

    • 家庭或小型企业网络中的网关:这种网关通常用于连接局域网和互联网,实现内外网的通信。它可以提供路由、防火墙、NAT、DHCP等功能,保证网络的安全和稳定。
    • 物联网中的智能网关:这种网关用于连接物联网设备和云端平台,实现数据的采集、处理和传输。它可以提供协议转换、数据压缩、数据分析、数据安全等功能,提高物联网系统的性能和效率
    • 语音通信中的语音网关:这种网关用于连接传统电话网络和IP网络,实现语音信号的转换和传输。它可以提供模拟/数字信号转换、编解码器选择、信令协商等功能,保证语音通信的质量和兼容性

简介

Linux C/C++技术栈的一些思考

  • 参考链接

  • Linux C/C++更接近底层机器,自然而言效率比Java,Python效率高的很多,但是各有各的优势。想要更深入了解操作系统,控制系统,选择Linux C/C++最好不过了

  • 最近学这个方向,过一段时间又学习另一个方向,这是兵家大忌。不管走哪一个方向,一定要沉稳,选择了就坚持走下去,除非这个技术栈没落了。

  • 大厂喜欢考:

    • 计算机组成原理
    • 操作系统
    • 计算机网络
    • 数据库
    • 设计模式
    • 数据结构
    • 算法
  • 大厂很注重基础和算法,不管走什么技术栈,都要稳扎稳打,基础打牢。

  • 大厂= 基础 + 算法 + 项目。

  • 要走能够拿得出手的项目,能够讲出:

    • 为什么要做这个项目
    • 做这个项目有什么作用,目的性
    • 用的是什么技术
    • 项目存在那些缺点
    • 那些访问还可以提高

专业术语

  • 技术栈(Tech Stack),某项工作或某个职位需要掌握的一系列技能组合的统称。一般来说,是指将N中技术互相组合在一起,作为一个有机的整体来实现某种目的或功能。
  • 指在软件开发过程中所使用的各种技术和工具的集合,包括编程语言,开发框架,数据库,操作系统,云服务等等。
  • 不同的应用场景和项目需求会对技术栈的选择产生不同的影响,因此选择合适的技术栈是保证项目开发顺利进行的重要因素之一

编程思想

  • 功能是功能,业务是业务,两者不要掺杂在一起
  • 分层和分模块
    • 分层,上一层和下一层有依赖关系
    • 分模块,模块之间是并列关系

机械臂项目

  • 设计一个或多个类,用来描述一个机械臂的物理特性和功能

    • 先完成机械臂的封装,每个功可以单独调用,这就是将物理的机器虚拟成一个对象
    • 然后对该对象提供的属性和功能进行设计,完成业务逻辑的实现
  • 维护两组中间变量:读空间和写空间

    • 读空间,是上行数据,从电机中读取当前状态,写入到中间变量,并向外提供数据,封装为read
    • 写空间,是下行数据,从外部接收指令,存储到中间变量,写入电机,封装为write
  • 读操作和写操作

  • 电机,有三种模式:速度,力矩,位置。

  • 三个元素,缺一不可

C++

  • 在C++里,所有的原生类型,枚举,结构体,联合体,类都代表 值类型;只有引用(&)和指针(*)才是引用类型

  • 流媒体开发

    • 跨平台软件开发组件
    • 深度学习模型加载,前处理,后处理,模型管理
  • 比特币

  • 下一份工作,就是要拿着现在的工作经验来谈

2022 全球C++及系统软件技术大会

陈硕

  • 程序,代码语句级的性能优化已经没多少空间,SIMD(Single instruction, multiple data)除外 –> 硬件加速才是王道

    • 买块好网卡,胜过调代码
    • https://blog.csdn.net/conowen/article/details/7255920 – SIMD等关键词简介
  • 推荐书籍

    • 程序设计实战 – Kernighan &Pike
    • 性能之巅 – Brendan Gregg
  • 编程工具

    • clang-format
    • clang-tidy
    • clang-rename
  • 建议

    • 开阔思路。编译器是一个程序,系统也是一个程序,只要是程序,就可以使用或修改
    • 逢山开路,遇水架桥。会使用工具,更会制造工具
  • 关键词

    • CPU
    • GPU
    • TPU
  • 总结:

    • 性能,靠硬件加速 – offload
    • 代码,编译器工具优化 – clang

作为一个程序员,有什么想对新人说的吗?

  • 程序员最应该钻研的是赚钱能力,业务,产品,前端,后端,ios,安卓,都要学一点,技术够用就行,然后去找赚钱的机会。
  • 切记不要钻研技术底层,好多为此花了无数的下班时间,结果还是30多岁被淘汰了,这个行业大多数工作单纯就是不需要你很牛的技术。老板只关心人力成本,你把底层设计成花也没有用。过了30每年淘汰一批,千万不要以为你能卷的过别人,如果你本身学历不高,没有大公司,大项目经历,更应该如此。

源码时代-源哥

  1. 编程重在实践,而不是只靠看书与表面
  2. 重在学习基础和原理,不要急功近利
  3. 编程的学习,重在修炼内功。技术的更新迭代很快,但是他们更新迭代的再快,也是外表的框架,计算机最基本的原理一般没怎么变化
  4. 程序员这个行业不是吃青春饭,每个行业都会讨论35岁这个坎,不仅仅程序员这个行业,如果能力不行,其实不论在哪个行业也不好混
  5. 作为程序员,不应该仅仅只关注技术,还应该跳出技术的空间,来世界发展的角度看一下世界,才能把握技术发展趋势
  6. 程序员前期要学会注重技术的积累,后期发展空间才大。既要专且深,也要广
  7. 基础越牢,你会发现计算机技术更新快并不可怕;基础不牢,你会发现你一直在学习,一直很累。

Linux C/C++ 程序员毕业工作一年多来的感想

工作和在学校写代码的不同

  • 在学校写代码,很少有规模特别大的,最多也就是几千行,代码规范全凭个人喜好,没有规范的测试,没有缺陷跟踪,持续集成。
  • 正式工作,工作面对的产品是用C/C++开发,10多年的历史,上百万行的code base。产品代码有规范的编码风格,清晰的模块划分,统一的编程范式。代码提交有严格的code review,特性功能有完整的设计文档和完整的测试用例,当然,持续集成,缺陷跟踪都一应俱全

关键的知识和技能

  • 个人感觉最重要的知识是操作系统方面的知识。工作这一年多以来最长看的书也是UNIX环境高级编程,TCP/IP协议详解,UNIX网络编程卷1:SocketAPI这三本书

  • 常见的设计模式和数据结构也是非常重要的,产品代码很多地方都体现出了设计模式的应用,依赖倒转,代理模式,观察者都是经常见到的。工作最常用的数据结构和算法有:链表,哈希,各种树,排序和状态机。在学校往往只重视了数据结构而忽略了设计模式,到了工作中就会发现设计模式在大型软件开发中的精妙之处

  • 汇编也是很有必要再复习下的,有的地方用到了内联汇编,而且调试代码也经常进行汇编级的调试

  • 至于语言方面的注意点,着重强调一下编程规范,严格按照产品的规范来,没有规定的可以参考业界公认最好的编程规范

常用工具的使用

  • 常用工具的熟练使用是高效开发的一个重要前提。高效的写代码,规范的提交,快速的调试查log,快速编写一些必要的脚本都是必备的技能。
  • 个人在工作中用到工具如下:
    • 版本管理:git
    • 代码编辑:Source Insight,Sublime, Vim
    • 产品构建:GNU Make,Gradle
    • 调试工具:GDB,Valgrind,Perf
    • 持续集成:Jenkins
    • 脚本语言:shell,python
    • 各种常见的Linux命令:grep,send,awk,find,ps…

沟通与团队写作

  • 沟通和团队写作非常重要。尤其是大项目大团队的时候。清晰的表达出自己的想法和意图,理解到位别人的想法是很重要的,因为一个feature往往是多个人共同开发的。而且,有时候还会需要额外协调资源,只是闷头搞也是不行的,沟通很重要

产品code base的快速理解

  • 这一点拿出来单独说是因为感触比较深。不同于平时自己搞项目,公司产品往往有一定规模了,而且通常都还不小。一定要学会看代码,修bug,加feature,往往都要求对已有的code base准确理解。

  • 快速理解code base的方法:

    • 有文档先看文档,然后问老员工,带着对业务的理解去看代码,最后的手段才是从代码反推业务的逻辑
    • 有一定理解后,自己推断程序运行预期,加log,下断电,看call back,看内部运行信息,验证自己的想法
  • 总之,不要上来就闷头看,不要高估自己从代码反推业务逻辑的能力。要知道,有时候别人写的代码真的没有那么容易看懂。用正确的方法才事半功倍

不要过分局限于底层

  • C/C++开发通常是系统级编程,很多知识都是长期不变的经典知识,并且很多相关开发者都有一种越靠近底层越优越的错觉,从而不愿意去了解其他知识,这绝对是不可取的。
  • 故步自封往往是落后的开始。要知道,不同场景不同问题的最佳解决方案绝对是不同的,决定收入与岗位多少的也是市场需求,所以一定要让自己觉有多方面的战斗力,用开放的心态多学习

Linux C/C++ 程序员毕业工作两年多来的感想

学习的态度和方法

  • 编程的学习路径不是完全线性的。陷入毫无头绪状态,不知从何学起很正常。在学习编程路上,要做到:

    • 遇到不明白的知识点,不焦虑有信心
    • 弄清楚道理哪里不懂,做到对症下药
    • 每次学东西不用贪多,当下够用就行
    • 长期保持学习的习惯,量变产生质变
    • 经验和思考要多总结,多记录多总结
  • 技术的积累要在专注于自己领域的同时,再有些横向拓展。例如:做Linux C/C++开发,就多专注学习Linux内核,网络,C++新语言特性,数据结构与算法等方面的知识,还有各种开发与调试中常用的工具 gdb/pref等。横向扩展就可以学习同样是linux后台开发常用的Go/Python/docker等,也可以慢慢学习当下很多的机器学习,跟着自己的兴趣走

  • 最后着重强调一点:每次学习不用贪多。平时看书看视频也好,工作中遇到的新的知识点也好,遇到一个点学一个点,练习记录总结,卡的时间太长可以跳到后面回过来再学。越是想一次掌握很多,越是学不透,学不扎实,还会损害学习的积极性。有时候理解就是需要时间的。

技术与业务的平衡

  • 技术很重要,这点毋庸置疑。技术的积累也是一个长期的系统的工程。这一点在学生时期和刚开始工作的时候大家也能够普遍的认识到。

  • 业务也同要重要,不要轻视业务,除非你马上就要跳槽。技术是服务于业务的,如果对业务没有帮助,纵有屠龙之技也无法对公司做出有用功。被提拔很快的程序员无不是出色的解决了工作中各种实际问题的,例如定位了各种疑难bug,高质量开发了复杂模块,提升了产品的性能等。所以,在工作中不要本末倒置,不要成天钻研各种虚无缥缈的东西,忽略了项目本身对人的锻炼,以及对个人价值的直接体现。要主动在工作中争取承当更大责任,给人一种技术好又出活的印象,这样才能升职加薪

  • 技术方面,数据结构,操作系统,网络看的多些,编译原理也在学习。工作中自己比较注重在项目中积累,业务针对性的自学也很好的解决了工作中遇到的问题,也得到了部门的认可。工作中遇到的技术点(code base里的,产品架构上的,定位问题中遇到的,其他同事用过的等),发现自己有欠缺的,及时补齐,有针对性的学习提高是最快的,明确知道自己哪里不足该学习什么是一件很开心的事情,并且这些技术点还能够请教同事。

技术之外的学习

  • 作为一名程序员,不能除了技术之外其他都不会。国内做技术,大概率是没办法做到退休的,人无远虑必有近忧,中年危机的预防靠的是年轻时的未雨绸缪。从现在开始,学习理财投资与欲望管理

Linux C/C++ 程序员毕业工作三年多来的感想

  • 虽说已经工作三年半,但是自己还是有很重的学生思想。对于技术,依旧是学习,练习,思考,总结的路子;对于工作,仍然是按部就班的完成任务,只是随着经验的积累,承担的工作难度与重要性增加了不少。对于未来的规划自己还没有想的特别清晰,当前的想法还是踏实的学习好技术,与此同时逐渐的去向学习如何带人带项目,向身边的技术专家和领导学习。

  • 在自己的领域技术要积累的专和深,与此同时再做到一定的横向拓展。当然,如果自己的技术领域没有前途,那么一定要早做打算。没有完美的个人,只有完美的团队。技术发展到这个阶段,复杂的产品研发靠的都是团队合作,没有个人可以cover住所有方面。把自己负责的模块特性做好,对产品整体架构和关键技术有一定的把握和见解,再适度的扩展就可以了。学习的广度和深度要把握好,一个人的经历毕竟有限,一定要找好自己的定位。这点,很多公司的路线也是这样的。

  • 今年结合工作,围绕自己的技术领域进一步学习了:Linux C/C++网络编程,Go语言等。我并没有花特别多的时间在C++的使用场景比较少的复杂特性上,学习的重点放在了业务知识,操作系统,虚拟化,分布式等相关技术,而且我觉得这才是正确的学习路线,千万不能跑偏。技术是服务于业务的,要把握好学习的重点,做好时间经历的分配

  • 工作三年多来,我对技术的学习也有了新的思考,从以前什么都想学变成了有选择的学习。围绕自己的技术领域深入研究,再横向拓展,打造自己的核心技术竞争力。当然,还是前面说的,这些要建立在自己的技术领域还有一定前途的基础上。

Linux C/C++ 程序员毕业工作四年多来的感想

  • 对技术已经没有那么狂热,学习新东西变得聚焦,甚至有点功利,少了那么一点纯粹。这种改变如此明显,以至于我看自己之前写的博客和日记都有点惊讶曾经的自己是如此的沉迷和醉心于技术。

  • 在学习上,自己变得非常聚焦,解决问题为第一优先级,并且一定会想一想自己有没有过度发散学习,以至于跑偏了。一个很明显的例子:由于很多场景需要在SSH到Linux服务器上开发,自己比较深度的使用了VIM,再也没有想着整的vim多么完美,而是着重的练习vim各种快速查找编辑操作上,把实际中最常用的几个插件给好好摸索一下。

  • 平时开始看一些人文社科的书籍,开始着重拓展非技术方面的知识,重视建设多元化的自己。

简介

  • C++工程师适合领域深度绑定的,一般初级都称为初级C++工程师,到了后期,分别是音视频高级C++工程师,人工智能高级C++工程师,医疗领域高级C++工程师等等

  • 要有深度和广度。有足够的广度,找到喜欢的一个方向,提高深度,当遇到技术壁垒时,再次回到广度扩展方面,寻找另一个方向,再挖深度

未来10年,C++5个非常有前景的就业方向

后台服务器开发

  • C++后台所需要具备的技能

    • 软件基础(数据结构与算法,设计模式,C++新特性,Linux工程管理)
    • 高性能网络(网络编程,网络原理,协程,用户态协议栈)
    • 基础组件(池式组件,高性能组件,开源组件)
    • 中间件(MySQL,Redis,Nginx,MongoDB, Elasticsearch)
    • 开源框架(Skynet, DPDK, TARS)
    • Rust(Rust特性, 网卡速度监控, OAuth2第三方登陆, tokio, Warp, hyper)
    • 性能分析(测试框架gtest以及内存泄漏检测, 火焰图的生成原理与构建方式)
    • 分布式架构(分布式消息, 分布式服务, 分布式API网关, 分布式存储)
    • 微服务( IM消息服务器/文件传输服务器, 消息服务器/路由服务器, 数据库代理服务器设计, 文件服务器和docker部署)
  • 应用场景

    • 处理大规模用户
    • 分布式计算
    • 处理大容量搜索 大规模响应
  • 企业

    • 当然,我们也关心,正在使用C++在哪些地方有使用,国内的大企业都有C++后台开发,因为他们需要处理大规模用户,分布式计算,大规模响应等。

云原生

  • 云原生其实是一套指导进行软件架构设计的思想。

  • 云原生的最大价值和愿景,就是认为未来的软件,会从诞生起就生长在云上,并且遵循一种新的软件开发、发布和运维模式,从而使得软件能够最大化地发挥云的能力。

  • 云原生的四要素

    • 微服务:
      • 几乎每个云原生的定义都包含微服务,跟微服务相对的是单体应用,微服务有理论基础,那就是康威定律,指导服务怎么切分,很玄乎,凡是能称为理论定律的都简单明白不了,不然就忒没b格,大概意思是组织架构决定产品形态,不知道跟马克思的生产关系影响生产力有无关系。
      • 微服务架构的好处就是按function切了之后,服务解耦,内聚更强,变更更易;另一个划分服务的技巧据说是依据DDD来搞。
    • 容器化:
      • Docker是应用最为广泛的容器引擎,在思科谷歌等公司的基础设施中大量使用,是基于LXC技术搞的,容器化为微服务提供实施保障,起到应用隔离作用,K8S是容器编排系统,用于容器管理,容器间的负载均衡,谷歌搞的,Docker和K8S都采用Go编写,都是好东西。
    • DevOps:
      • 这是个组合词,Dev+Ops,就是开发和运维合体,不像开发和产品,经常刀刃相见,实际上DevOps应该还包括测试,DevOps是一个敏捷思维,是一个沟通文化,也是组织形式,为云原生提供持续交付能力。持续交付:持续交付是不误时开发,不停机更新,小步快跑,反传统瀑布式开发模型,这要求开发版本和稳定版本并存,其实需要很多流程和工具支撑。
  • 云原生关键技术点

    • 如何构建自包含、可定制的应用镜像;
    • 能不能实现应用快速部署与隔离能力;
    • 应用基础设施创建和销毁的自动化管理;
    • 可复制的管控系统和支撑组件。
  • 场景

    • 深度学习应用场景
      • 云原生深度学习方案的基础架构模型
      • 容器化封装深度学习框架
      • 服务目录的形式提供多种板卡驱动
      • GPU 多机多卡的高效调度
    • 区块链应用场景
    • 边缘计算场景
      • 边缘计算按功能角色主要分为三个部分:
        • 云–传统云计算的中心节点
        • 边–又称基础设施边缘(Infrastructure Edge)
        • 端–又称设备边缘(Device Edge)
    • 传统业互联化应用场景
      • 项目周期短,需求快速变化。
      • 互联网高并发,不可预测的承载需求。
      • 兼顾数据安全和用户体验。

音视频流媒体

  • 音视频流媒体所需要具备的技能

    • 音视频基础(FFMPEG环境搭建,音视频基础)
    • FFMPEG编程(FFMPEG命令,音视频渲染,FFmpeg API,音视频编码,音视频封装格式,音视频过滤器,播放器开发,ffplay播放器,ffmpeg录制转码)
    • 流媒体(rtmp流媒体,hls流媒体,http-flv流媒体,RTMP/HLS/HTTP-FLV流媒体服务器,RTSP流媒体)
    • WEBRTC(WebRTC中级开发,WebRTC高级开发,Janus服务器源码)
  • 音视频流媒体应用场景

    • 视频点播
    • 视频会议
    • 远程教育
    • 远程医疗
    • 短视频
    • 在线直播系统
  • 主流的流媒体协议

    • 主流的流媒体协议主要有:RTMP, HLS, RTSP等。

虚拟化

  • 虚拟化所需要具备的技能

    • 两种架构、三个知识点
      • 两种架构
        • 共享存储的传统架构
        • SAN的”超融合”架构
      • 三个知识点
        • 在这两种架构中,主要用到三个设备:服务器、存储、网络交换机与光纤存储交换机,这对应计算、存储、网络三方面的知识。
        • 计算,是指服务器,要了解常用服务器的基础配置、最高配置(CPU、内存、硬盘接口与数量、单个硬盘支持的最大容量、网卡接口、速度,底层管理等),对项目中所需要用的服务器进行选择。
        • 存储,要了解常用存储的接口(iSCSI、SAS或FC)、配置(硬盘类型、数量)、支持的RAID、可扩充性、报价。
        • 网络,要了解常用网络交换机、光纤存储交换机的品牌、型号,了解网络交换机的速度、接口数量、可扩充性等。
  • 虚拟化系统集成

    • 去企业机房,看总体,有多少机柜,每个机柜中有那些设备。机柜中是否有足够的空闲机位、网络剩余接头。
    • 企业现有服务器与存储数量、配置,接口等。
    • 网络拓扑,出口带宽,网络防火墙、路由器、交换机等。
  • 硬件知识

    • 交换机、存储、服务器
  • 网络与软件知识

    • 了解TCP/IP协议、了解IP地址的分类、子网划分等内容。要了解华为交换机的基本配置(划分VLAN、配置LACP等)。
    • 掌握Windows的Active Directory的知识,掌握Windows Server中DHCP、DNS、Active Directory、证书、KMS的知识。
  • 熟悉vSphere产品安装、配置、故障排除

    • vSphere 5.5系列:vCenter Server安装、ESXi安装、配置,创建虚拟机等。虚拟机备份、恢复。
    • vSphere 6.0系列:vCenter Server安装、ESXi安装、VSAN、配置等。
    • vSphere 6.5系列:vCenter Server、ESXi、vCenter HA、VSAN。
    • Horizon View 桌面系列:Horizon View 7.0、6.0。
    • VMware P2V工具、VMware VDP、vCops等。
  • 熟悉或精通VMware Workstation

  • 虚拟化方案应用场景及优劣

    • Xen
      • 应用场景:x86、IA64和AMD、Fujitsu、IBM、Sun等公司的ARM以及x86/64 CPU商家和Intel嵌入式的支持的全虚拟化和半虚拟化解决方案。
      • 优势:Xen支持准虚拟化,需要修改客户机操作系统,而修改过的客户机操作系统能有更好的性能;此外Xen也支持全虚拟化,未经修改的操作系统也可以直接在Xen上运行(如Windows),能让虚拟机有效运行而不需要仿真,因此虚拟机能感知到hypervisor,而不需要模拟虚拟硬件,从而能实现高性能。
      • 劣势:如果你需要更新Xen的版本,你需要重新编译整个内核,而且,稍有设置不慎,系统就无法启动。
    • KVM
      • 应用场景:X86架构且硬件支持虚拟化技术(Intel V或AMD-V)的Linux的全虚拟化解决方案。
      • 优势:不需要重新编译内核,也不需要对当前kernel做任何修改,它只是几个可以动态加载的.ko模块,结构更加精简、代码量更小。所以,出错的可能性更小,并且在某些方面,性能比Xen更胜一筹。
      • 劣势:KVM可以运行在不支持虚拟化的CPU硬件上,但是在这样的话,效率会很低;KVM也可能会和虚拟机virtualbox冲突;KVM只是提供命令行接口,用户可以写脚本来管理KVM,并没有一个友好的GUI。
    • Hyper-v
      • 应用场景:适用于Monolithic Hypervisor 架构服务器虚拟化解决方案。
      • 优势:设备驱动不需要为每个设备都纳入Hypervisor层或者VMM Kernel;由于微软没有提供应用程序编程接口(API)来访问“Hypervisor层”,受到攻击的可能减小,没人可以插入外部代码到+ “Hypervisor层”;设备驱动不需要Hypervisor的感知,所以这种架构可以使用更多的设备;不需要关闭“Hypervisor层”,包括设备驱动程序。
      • 劣势:在操作“Hypervisor层”之前,需要在“控制层”安装操作系统,这是最大的一个缺点;如果在“控制层”正在运行的操作系统任何原因的崩溃,那么所有的虚拟机也都会崩溃;需要花费更多的经费在“控制层”的操作系统与“Hypervisor层”的虚拟机上。
    • VMware vSphere
      • 应用场景:适用于Microkernelized Hypervisor架构服务器虚拟化解决方案。
      • 优势:没有操作系统的要求,来控制所有的组件,这是它最大的优势超过微软的Hyper-V Microkernelized Hypervisor的架构;在“控制层”运行的组件没有安全补丁。
      • 劣势:Vmware的vSphere硬件支持不好;VMware vSphere不安全,因为VMware在“Hypervisor层”提供API的入口,恶意的代码有可能会进入到这层,甚至黑客可以控制“Hypervisor层”之后就可以控制运行在vSphere服务器上所有的虚拟机。

网络安全

  • 网络安全所需要具备的技能

    • 如果想做逆向,那么要掌握汇编
    • 如果想做数据库注入,那么要学SQL
    • 如果想做XSS,那么要学JavaScript
    • 如果想找驱动和内核的漏洞,那么要熟悉内核
  • 网络安全应用场景

    • 园区门禁(网络隔离):工业防火墙、工业网闸
    • 楼宇门禁(区域隔离):工业防火墙
    • 办公室门禁(具体职能单元/主机安全):工业主机安全卫士
    • 摄像头安防系统(网络监测与告警):工业安全审计监测、网络入侵检测
    • 中控室控制大厅(安全管理、安全运维、安全审计):安管平台、日志审计、堡垒机
    • 车联网安全
    • 城市安全
    • 社区安全
    • 家庭安全
    • 移动应用安全
  • 网络安全前景价值

    • 网络安全为数字未来创造的价值。
    • 智能制造时代,工业大数据作为制造企业的核心资产之一,其重要性不言而喻。“工业4.0”浪潮下,制造企业加快了迈向“数字化”和“智能化”的步伐,以云计算、大数据、5G、人工智能为代表的新兴技术正在深度渗透至工业生产领域,在推动工业生产体系与运营模式升级的同时,也带来了新的网络安全挑战。网络安全公司最新发布的报告称,制造业企业已成为网络犯罪分子、勒索软件和国家黑客的首要目标。其中,61%的企业工厂发生过网络安全事件,其中3/4的网络攻击导致线下生产停摆。
    • 随着工业信息安全事件频发和政策标准的落地,单纯的工业信息安全防护产品已无法满足工业企业用户需求。同时,由于工业企业普遍缺乏对工业信息安全防护策略的落地能力,安全体系设计和规划服务需求应运而生。

C++工程师职位要求

学历

  • 本科及以上学历,计算机相关专业毕业
  • 全日制本科及以上学历,计算机,电子信息,软件工程,通信工程等相关专业
  • 计算机,软件工程或力学相关等专业,本科及以上学历。
  • 统招本科或以上,通信工程,电子工程专业,学科基础扎实,有信号分析处理类项目经验者优先
  • 统招本科,计算机,通信专业
  • 全日制硕士及以上学历,5年以上嵌入式软件开发经验 [央企]
  • 统招本科及以上学历,计算机应用,软件工程等相关专业
  • 计算机,数学相关统招本科及以上学历
  • 年龄不大于46岁,Linux下C++从业经验不少于5年,QT经验不算在内,有雷达背景以上不做限制
  • 本科及以上学历,软件开发,通信工程,控制等相关专业
  • 本科及以上学历,具有良好的主动性,团队写作能力
  • 统招全日制本科或以上学历,计算机/软件开发/电子/自动化相关专业比
  • 统招全日制本科或以上学历,计算机软件,通讯相关专业
  • 本科以上学历,5-10年以上工作经历
  • 5年以上相关工作经历,本科以上学历
  • 本科及以上学历,计算机相关专业

编程语言

  • 精通C++语言,对背后的原理有一定了解,熟练使用模板技术,STL标准库以及C++11以上新特性
  • 精通C++编程,包括多线程编程,消息循环,内存分析,数据结构,标准模板库及其算法
  • 精通C++/C#/Java等语言一种或多种,具备面向对象编成思想,熟悉STL标准库中的常用数据结构,算法及容器类,熟悉多线程编程。
  • 精通C/C++,了解常见的数据结构,算法和面向对象的设计模式
  • 精通C/C++语言,熟悉ARM处理器体系架构,良好的编程习惯,逻辑分析能力
  • 有扎实的C/C++基础,熟练使用常见的数据结构
  • 精通C++语言,熟悉Windows和Linux下的软件开发
  • 精通Linux,三年及以上C++编程语言开发经验,有具体项目开发经验,能够独立完成项目需求分析,设计及实现各阶段工作
  • 熟练掌握STL库,C++11及多线程环境编程。
  • 具有良好的编程习惯,熟练掌握C++/java/python
  • 五年及以上C++编程语言开发经验,有具体项目开发经验,能够独立完成项目需求分析,设计及实现各阶段工作
  • 熟练掌握GUI库,STL库,C++11以及高可用,高并发环境编程
  • 具备深入的C++编程知识和经验,能够编写高性能,可维护的代码
  • 良好的数据结构和算法能力,精通C/C++开发。熟练使用QT或JUCE等UI软件编程工具;对OpenGL有了解
  • 熟练使用C,C++,Python,Rust语言,可以进行独立开发
  • 熟练掌握STL库,C++11以及多线程环境的编程。
  • 具有扎实的C/C++语言知识和应用经验,有良好的编程习惯
  • 熟练掌握数据结构和算法
  • 熟练使用C++语言,3年以上C++编程经验

操作系统

  • 熟悉Linux和常见RTOS系统架构,熟悉内核调度,中断,内存管理,文件系统,网络协议栈等原理
  • 掌握操作系统,体系结构,编译原理,计算机网络等基本知识
  • 需要在底层代码开发方便有丰富的经验,熟悉与操作系统,内存管理,多线程编程,性能优化等相关的底层技术
  • 熟悉linux操作系统基本操作,熟练使用linux系统工具
  • 数据结构,操作系统原理,编译器原理等基础知识扎实
  • 熟悉linux平台驱动开发优先,尤其是打印驱动,手写板驱动,扫描驱动等
  • 有扎实的计算机基础,熟悉Linux/Unix环境,熟悉主流开发工具和检测代码,性能监控工具。
  • 熟悉Linux/Unix环境

网络通信

  • 熟练使用socket网络编程以及IO多路复用技术,熟悉HTTP/HTTPS协议以及相关接口开发
  • 熟悉TCP/UDP网络通讯开发
  • 熟练掌握网络编程,以及多线程,多进程和进程间通信等相关技术,熟练使用VS等进行开发
  • 熟悉网络编程,多线程程序设计,熟悉常见设计模式
  • 精通多线程,多进程开发技术
  • 精通tcp,udp网络协议开发,熟悉HTTP,FTP等常用应用层协议
  • 精通TCP/IP,UDP,HTTP协议,熟悉Linux常见网络服务器模型
  • 精通多线程和网络编程,有音视频或流媒体项目开发经验,涉及UDP组播传输,RTP,RTCP传输协议,网络协议,信号传输,音视频监控类项目经验

数据库-缓存

  • 熟悉redis, mysql数据存储系统,熟悉mysql疑难问题解决方案
  • 熟悉MySQL/SqlServer/Access等数据库之一
  • 熟练使用一种现有数据库系统,例如mysql,mongodb等
  • 熟练使用一种缓存系统,例如memcache, redis等
  • 熟悉Linux平台开发,熟悉MySQL数据库,以及国产操作系统,国产数据库等开发者优先
  • 熟练使用mysql,oracle,sqlite等常用数据库
  • 独立完成数据库表设计,熟悉SQL语句优化,表结构设计优化
  • 熟悉数据库,消息中间件,虚拟化工具使用

架构设计能力

  • 具备架构设计能力,熟悉常用的设计模式,有良好的代码编写风格
  • 熟悉面向对象设计思想,熟悉设计模式,具有独立的模块设计能力
  • 精通面向对象开发,熟悉至少三种设计模式
  • 能够定制可扩展,可靠,高性能的软件架构,具备深刻的架构设计理解
  • 熟悉UML,OO设计理论及基本的设计模式
  • 熟练掌握软件设计模式
  • 熟练使用常见设计模式,能使用诸如单例,工厂,策略,模板,代理等模式,构建可重用,易维护的代码

开发经验

  • 有分布式,大数据相关开发经验优先
  • 有SIP,H323协议开发经验优先
  • 熟悉FFmpeg, H.264,H.265开发经验优先,并具备Windows,Linux开发经验优先
  • 具备Electron/Cocos2d-x/Unity3D等跨平台框架开发经验。

行业领域

  • 了解AAC,H264等音视频编解码技术规范;熟悉rtp,rtcp,rtmp,RTSP里的多种传输协议

其他软技能

  • 良好的英语听说能力,技术文档处理能力(需求,设计,使用说明等)
  • 熟练使用osip,xsip,openH323,ptlib,yate等开源库进行不同需求的开发,并可以根据需要对源码进行修改
  • 熟练使用wireshark抓包工具分析问题,对数据库sqlite工具使用熟练
  • 熟练掌握容器,分布式系统,性能分析工具,优先考虑
  • 有产品研发经验,能够理解产品需求,设计相应的解决方案,并推动产品开发的不同阶段
  • 熟悉各种算法和数据结构,能够选择和实现最佳的算法以解决复杂的问题
  • 具备跨不同操作系统和平台进行C++开发的经验,例如Windows,Linux,macOS等
  • 能够使用调试工具和性能分析工具来诊断和解决问题,并进行性能优化
  • 具备卓越的团队合作能力,能够与其他工程师,产品经历和设计师共同协作,共同推动项目的成功
  • 具备出色的口头和书面沟通能力,能够清晰地表达技术观点和解决方案
  • 愿意不断学习新的技术和工具,保持在领域内的领先地位。
  • 学位和认真:计算机科学或相关领域的学士学位,持有相关的认证(例如C++认证)优先
  • 熟练使用GDB,Valgrind等调试工具,有实际调试经验,能够独立完成linux上的问题排查
  • 关注开源社区动态,在上游社区有代码提交者优先。
  • 对基本的开发流程及模式有一定的认识
  • 熟悉openssl等加解密库优先
  • 熟练使用单元测试框架,设计单元测试用例,保障代码质量
  • 熟练使用常见的版本管理工具SVN,Git等
  • 熟悉主流开发工具和监测代码,性能监控工具
  • 能熟练使用单元测试框架,设计单元测试用例,保障代码质量
  • 熟练使用常见的版本管理工具SVN,Git等

现阶段的C++学习建议

  • 重点放在 std::vector, std::map, std::string, 类,模板编程 基础知识的学习

20231005 https://www.zhihu.com/question/537556535/answer/2535800615

  • 真心建议,初学C++,好好学习基础语法、惯用写法、对象模型,从而了解编写高效C++程序的方法,充分发挥C++的优势,学会规避它的劣势和问题。至于模板元编程,初学可以跳过,太容易走偏,走火入魔,最后就成了炫技技巧。

0515 谈话

理论知识

  • 隐藏的工作,这些工作,写不到文档中,但又必须得干。例如:

    • 选择什么样的系统环境,如何去适应操作系统
    • 使用那些依赖组件,这些依赖组件是从哪里来的,怎么安装使用,怎么升级维护
  • 当前,陈总提出的人脸库量集的问题,每一个人脸库最大支持多少张人脸图片,一般来讲,边缘盒子的是十万,服务器主机是一百万。

  • 这个工作涉及到两个方面

    • 第一个,要明白整个任务的流程,如果要测试准确度,需要明确理解人脸识别的流程框架,从技术需求,到开发环境,模型训练要求,测试标准等。
    • 第二个,要知道怎么去和算法工程师配合,不是说,找十万张图片,放入到人脸库中就可以的,而是要看训练的特征提取模型支持多少张图片,如果其本身仅只是五万张的图片,那么放入十万张图片,在进行人脸识别,势必其结果是不准确的。解决方法是,如果在训练模型时,训练集是十万张甚至更多,在进行测试的时候,放入十万张人脸图片,在进行人脸识别,测试识别结果;如果在训练模型时,少于十万张,那么就需要使用低于其训练集数量的图片进行初始化人脸库
  • 在进行人脸识别中,最关键的是两个,格式和比例,在放入到模型中,进行提取时,对这张图片的要求是什么,人脸比例为多少?百分之八十?图像格式是什么?RGB?

2024.01.08

  • 决策能力

  • 带领团队解决问题

  • 问题分析能力,自己作出选择,形成意见并表达

视频结构化方面

  • 视频拉流

    • 用什么拉取视频流?
    • 从什么地方拉取视频流?是从本地实体文件,还是从网络传输,
    • 拉取视频流的工具是什么
    • 这个工具从哪里获取,是手动编译成第三方库,还是通过apt安装,还是其他方式
    • 这个工具怎么升级,
    • 这个工具怎么使用
    • 这个工具可能会和已有的依赖组件冲突吗?如果冲突了怎么办?
  • 视频解码

    • 视频用什么工具解码,支持的视频格式是什么?h264,h265?
    • 这个功能怎么在多个平台使用
  • 效率

    • 如何减少内存使用搬运次数,是搬运一次就可以,还是必须要搬运多次,怎么搬运,如果提升效率
  • 变形

    • 图像变形,resize,怎么缩放
  • 2D图片

    • 如何解码,如何编码
    • 格式如何转换,
    • 尺寸怎么缩放,缩放大致分为等比缩放和非等比缩放
  • 模型

    • 如何加载模型,怎么进行推理
    • 前处理如何去做,一般模型都有前处理,涉及到各个模型特有的前处理数学公式,如何转换成代码实现
    • 推理工作如何完成?
    • 后处理如何实现,一般来说,后处理实现一次,只要模型不做改动,则不会改动
  • 数据结构设计

    • 后处理出来之后的数据怎么存放,怎么设计一个数据结构存放后处理数据,并且可以二次开发和利用
  • 数据传输

    • 如何将结构化数据提供给第三方使用,通过一种方式去传输数据,通过一种方式去接收,解析数据,
    • 传输数据,就涉及到网络通信,是使用zmq,还是kafka,还是redis,还是实体文件
    • 存储数据的格式,这个格式是需要第三方可以使用的,一般来说分为两种格式:
      • 与语言无关的,例如JSON,XML,HTTP等等
      • 与语言相关的,
  • vca项目

    • contrib,这个目录下存放的是与平台无关的接口,与业务无关的,其内存实现是各个平台的代码
    • util,这个目录下存放的是业务相关的接口

简介

  • RFID考勤系统设计

已有信息

  • 题目:

    • 基于RFID的考勤管理系统设计与实现
  • 物理环境要求

    • 硬件:
      • RFID阅读器
      • RFID读写器
      • RFID卡片
    • 软件:
      • C 编程语言 | C++ 编程语言
      • 硬件比较少,软件多做几张表
  • 导师指导:

    • 和功能有关,只是收读卡器信息,计算机上写程序即可

系统环境设计

  • 编程语言:

    • C++
  • 数据读写工具

    • RFID读写器
    • RFID卡片
  • 系统运行环境

    • Ubuntu

系统流程设计

  • 注册:

    • RFID卡片存储用户的唯一ID,通过RFID读写器将用户的ID写入到RFID卡片中
  • 签到

    • 通过RFID读写器,读取RFID卡片存储的数据,在本地用户列表中查找,如果存在,即签到成功;否则,签到失败
  • 签退

    • 通过RFID读写器,读取RFID卡片存储的数据,在本地用户已登录列表查找,如果存在,即签退成功;否则,签退失败
  • 注销

    • 通过RFID读写器,读取RFID卡片存储的数据,在本地用户列表查找,如果存在,删除该数据,返回成功;否则,返回失败
  • 其他模块

    • 待完善

简介

  • RFID考勤管理系统设计

价格

  • 1200 – 多人
  • 1500 – 单人

初步规划

  • 系统从功能上分为前端和后端

    • 前端: 使用JS(JavaScript)编程语言,主要实现与用户交互的页面,通讯方式为网络通讯
    • 后端: 使用C编程语言,主要实现web服务器和RFID读写功能
  • 系统从物理上分为软件和硬件。

    • 硬件: stm32 or ubuntu系统, RFID读写器(RC522), IC磁卡
    • 软件: 后端服务器和前端界面

简介

  • 五月二十七日考试

第一章计算机系统基础知识

1.1 嵌入式计算机系统概述

1.1.1 计算机硬件

  • 基本的计算机硬件系统由: 运算器,控制器,存储器,输入设备和输出设备
  • 运算器和控制器及其相关部件已被集成在一起,统称为中央处理单元(Central Processing Unit, CPU)
    • 运算器是对数据进行加工处理的部件,它主要完成算术和逻辑运算。
    • 控制器的主要功能是从主存中取出指令并进行分析,以控制计算机的各个部件有条不紊地完成指令的功能
  • 存储器是计算机系统中的记忆设备,分为内部存储器(Main Memory, MM, 简称内存,主存)和外部存储器(简称外存或辅存)
    • 相对而言,内存速度快,容量小,一般用来临时存储计算机运行时所需要的程序,数据及运算结果
    • 外村容量大,速度慢,可用于长期保存信息。
    • 寄存器是CPU中的存储器件,用来临时存放少量的数据,运算结果和正在执行的指令。

1.1.2 计算机软件

  • 计算机软件,是指为管理,运行,维护及应用计算机系统所开发的程序和相关文档的集合。

  • 如果计算机系统中仅有硬件系统,则只具备了计算的基础,并不能真正计算,只有将解决问题的步骤编制成机器可识别的程序并加载到计算机内存开始运行,才能完成计算

  • 软件,是计算机系统中的重要组成部分,通常可将软件分为系统软件,中间件和应用软件等类型

    • 系统软件的主要功能是管理系统的硬件和软件资源
    • 应用软件则用于解决应用领域的具体问题,
    • 中间件,是一类独立的系统软件或服务程序,常用来管理计算资源和网络通信,提供通信处理,数据获取,事务处理,Web服务,安全,跨平台等服务。

1.2 数据表示

  • 二进制,是计算机系统广泛采用的一种数制。在计算机内部,数值,文字,声音,图形图像等各种信息都必须经过数字化编码后才能被传送,存储和处理。

1.2.1 数值型数据的表示

  • 数据在计算机中表示的形式称为机器数,其特点是采用二进制计数制,数的符号使用0,1表示,小数点隐含表示而不占位置。

  • 机器数对应的实际数值称为数的真值。

  • 无符号数,是指全部二进制位均代表数值,没有符号位。

  • 对于有符号数,其机器数的最高位是表示正,负的符号位,其余位则表示数值。

    • 若约定小数点的位置在机器数的最低数值位之后,则是纯整数;
    • 若约定小数点的位置在机器数的最高数值位之前(符号位之后),则是纯小数。
  • 为了便于运算,带符号的机器数可采用原码,反码,补码和移码等不同的编码方法

1.2.2 定点数和浮点数

  • 所谓定点数,就是表示数据时小数点的位置固定不变。

  • 小数点的位置通常有两种约定方式:

    • 定点整数,纯整数,小数点在最低有效数值位之后,
    • 定点小数,纯小数,小数点在最高有效数值位之前。
  • 所谓浮点数,是指小数点位置不固定的数,浮点表示法能表示更大范围的数

1.2.3 其他数据的表示

  • 各类数据的表示都有相应的基本字符集,任何字符在计算机中都必须转换成二进制表示形式,称为字符编码。

1.2.4 校验码

  • 计算机系统运行时,各个部件之间要进行频繁的数据交换,为了确保数据在传送过程中准确无误,一是提高硬件电路的可靠性,二是提高代码的校验能力,以进行查错和纠错。

  • 通常使用校验码的方法来检测所存储和传送的数据是否出错,即对数据可能出席那的编码分为合法编码和错误编码两类。

    • 合法编码,用于存储和传送数据
    • 错误编码,是不允许在数据中出现的编码
  • 码距,是校验码中的一个重要概念。所谓码距,是指一个编码系统中任意两个合法编码之间至少有多少个二进制位不同。

  • 例如,4位8421码的码距为1,在传输过程中,该代码的一位或多位发生错误,都将变成另外一个合法编码,因此这种代码无差错检验能力

  • 常用的三种校验码:

    • 奇偶校验码(Parity Codes)
    • 海明码(Hamming Code)
    • 循环冗余校验码(Cyclic Redundancy Check, CRC)

1.3 算术运算和逻辑运算

  • 基本的算术运算有加法,减法,乘法和除法。
  • 逻辑数据的取值只有 真 和 假,通常以 1 表示为 真; 0 表示为 假。
  • 基本的逻辑运算有: 逻辑与, 逻辑或, 逻辑非

简介

  • 与AI算法团队紧密合作,负责AI算法在CPU,GPU等处理器上的模型,并进行压缩和优化
  • 提高模型性能,降低部署成本,封装成SDK供业务端使用
  • 帮助AI算法在项目中快速落地

任职资格

  • 精通C++,Python,具备良好的代码书写规范和文档编写能力
  • 熟悉tensorflow等深度学习框架,熟悉CNN,RNN,LSTM等常用神经网络模型代码实现,精通网络剪枝,量化等算法优化方法
  • 熟悉ARM,X86,GPU架构体系,熟悉并行计算软件开发,具有丰富的汇编,CUDA编程经验
  • 良好的英语阅读能力,良好团队合作精神

经验分享 1

1.1 简介

  • 想要真正的将训练好的模型部署到边缘计算设备上,并能够以可接受的速度和精度来运行需要掌握很多知识。技术栈可以粗分成两个部分,即软件栈和硬件栈
    • 软件栈主要针对算法,包括对深度学习模型的了解、对模型加速技术的了解;
    • 硬件栈需要了解自己选择的边缘计算设备的硬件架构,边缘计算设备的ISP、存储、算力等性能

1.2 软件栈

  • 我们需要掌握三部分:模型前处理、模型推理、后处理三部分内容。

  • 前处理

    • 了解图像从获取到输入到网络需要哪些基本的操作,常见的减均值,除标准差,通道变换,RGB变换,仿射变换,透视变换等,根据业务场景不同进行组合。
  • 模型推理

    • 了解网络结构模型的设计方法和各部分算子的具体意义。对于部署模型来讲,可能不需要对模型设计有创造性的能力,但需要掌握模型结构设计的基本知识,比如一个通用的目标检测模型包含骨干网络和检测头,针对不同的应用场景,需要我们灵活地调整骨干网络,搭起一个架子,是用VGG还是Resnet,用不用FPN或者Attention模块,有必要的要加进去,没必要的别瞎往里堆。实现一个高精度的深度学习模型网络结构。计算机视觉方向有很多优秀的开源工作,有监督网络里的目标检测、实例分割、关键点检测,无监督网络里的MOCO,github上有很多star作品,比自己设计要强,能白嫖谁还自己搭是吧?
  • 后处理

    • 明白一个模型推理结束之后,如何通过后处理得到自己想要的结果,分类加sigmoid,目标检测需要nms,关键点检测需要基于heatmap映射关键点。得到基本的信息之后再拿到自己的业务场景里去做内容

1.3 模型加速技术基础

  • 掌握了模型推理基础内容之后,开始模型加速技术相关工作,我们需要把一个在服务器上得到的大模型变成一个小模型,方便边缘计算设备去支持、去计算。很多人直接拿着模型就去进行加速,先剪枝、蒸馏、量化来一套再说,这样不能说错,但是真正想要兼顾速度和精度,还是要深入分析一个模型的特点,再去进行针对性的加速优化

  • 分析一个模型

    • 如何分析一个模型或者如何衡量一个模型的大小?模型的大小是否单单是由运算量体现的?好多人加速完模型已测试,卧槽咋变慢了?
      模型大小的衡量指标包括计算量、参数量、访存量、计算密度,前三个是绝对值,最后一个是相对值,衡量一个模型大小或者加速一个模型要从这四个方面去考量。因为内存墙的原因,访存比往往成为影响模型推理速度的一个重要因素
    • 我们不需要自己去计算这些指标,不同的平台或者后端都提供了这些指标的计算API,比如ONNX,Tensorrt,PPL,根据对应的API很快就能分析出一个模型在特定计算设备的指标情况。从模型推理角度出发,各种profiler能够更直观的看到整个模型推理过程中,流水线、计算时间等是怎么分布的。有了这些基本的认识之后,就可以针对性地进行模型加速了
  • 常用的加速技术

    • 加速技术很多,图优化技术,如结构重参数化技术;模型压缩技术如剪枝,蒸馏、量化;此外,不同的软件栈也针对性的做了很多其他方面的优化工作,kernel优化、动态内存,多线程优化技术等等,底层的技术都是类似的,只不过实现细节略有差异,性能也是千差万别。
  • 剪枝:

    • 剪去不需要的权重,相当于减少了模型的运算量,在模型的运算量是模型瓶颈的时候益处很大,各种剪枝方法也很多,设计损失函数的核心就是某个channel的权重重不重要,比如LI norm,L2 norm, Slim pruner, FPGM pruner,这些都是结构化剪枝方法,非结构化剪枝需要特定的ASIC,否则稀疏化和没做没啥区别。但当性能瓶颈不是计算量,而是访存时,剪枝技术的优点就不那么明显了。
  • 量化

    • 量化后放存量必然减少了,采用向量化的方法,计算设备单次发射的指令能够处理更多的数据,真香!
    • 主流的量化方法还是对称量化,饱不饱合的得看数据到底啥样。
  • 结构重参数化

    • 减少访存的利器,把网络结构里能合并的层合并在一起,实现访存优化,常见的就是CBR融合,RepVGG融合,关键看实操
  • 工具链

    • 大厂为我们提供了成熟的白嫖工具,自动完成所需要的优化工作:Tensorrt,NCNN轻松实现量化、结构重参,还附带其他内存优化、多线程工具,但如果你选择的边缘计算芯片不支持常用的工具链,优化工作就要自己做了,这才是真正检测功底的工作。

1.4 硬件栈

  • 通用计算芯片和专用计算芯片

    • 首先肯定得了解GPU,CPU,GPU代表英伟达,CPU代表intel,了解主流的GPU,CPU芯片一代代迭代,和计算相关的架构变化到底涉及了哪些内容
    • 以GPU为例,Nvidia的进化史大致是Kepler,Maxwell,Pascal,Volta,Turing, Ampere,每一代芯片都进行了那些更新,算力,显存怎么做的提升,都支持了那些操作等等
  • 专用芯片硬件架构

    • CPU、GPU架构主要在任务通用性上下了功夫,相较于专门针对计算机视觉的专用芯片性能很大差距。专用的ASIC种类很多了,架构各有特色,但都是为了一个目的:高性能+低功耗。以Google为代表的TPU问世后掀起了专用ASIC的研发热潮,这十年国产芯片也在疯狂输出,FPGA、KPU,NPU等各种PU层出不穷,性能鱼龙混杂,我们还是要擦亮眼睛去识别的
    • 涉及到模型部署还是要优选搭配软件栈的芯片,自己去实测芯片性能是最可靠的方法,别看彩页说的如何牛p,还得看模型、看实测!
      了解视觉信号从输入芯片到输出芯片全流程参与的硬件,这些硬件是怎么参与整个模型的前处理、推理和后处理的,比如昇腾的芯片采用专用硬件实现img2col,Nvidia采用软件实现img2col,各自的特点是怎么样的;再比如Nvidia专用的硬件解码,对于模型推理有怎样的增益等等

1.5 编程语言

  • Python是一门高级抽象语言,便利了深度学习模型搭建、训练,但用来部署无法和C++一较高下了,

  • 简单说说针对算法部署需要掌握的C++知识有哪些?

    • 面向对象编程的基础:类
    • 继承:构造函数、析构函数、指针、引用、重写,模板函数
    • STL:常用的序列容器及特性,共享内存
    • C++多线程:掌握 threading, mutex,condition_variable,future,RAII怎么用
    • C++动态内存管理:我也不会,google去吧
    • 编译基础,动静态库,makefile

经验分享 2

  • 一般部署的每一个硬件平台都有自己的推理框架,需要自己做的任务基本上是调用api来对一些模型进行落地,这些其实并不是很难
  • 如果想进阶,学习一些优化的知识,例如卷积优化算法,或者更深入的汇编优化等等,可以关注知乎移动端专栏或者GiantPandaCV公众号,都会带来一些比较良心的部署优化相关的文章

经验分享 3

  • 这个工作是开发,对算法的熟悉是为了帮助工程实现,对算法的要求和研究员的关键区别是不太需要算法上的创新

参考资料

简介

  • 对中年危机的提前应对之法

https://www.zhihu.com/pin/1392848366330556416

朋友们,写程序是一个目的性很强的事情,当你没有目标的时候,你最好不要开始动手写,因为那样是不可能做好事情的。人这一生时光匆匆,真的希望大家能够珍惜眼前的生活,不要浪费了。写程序也只是一种求得生存的方式,不是生活的全部,如果你不能想明白这个, 等你40岁,50岁的时候,你发现你以前其实什么都不是。。。

https://www.zhihu.com/question/437925439/answer/2914183102

技术专家和领域专家,程序员只会写代码,会几门编程语言没有实质上的竞争力。当你35岁时,有了十年左右的工作经验,是不是成为了某个领域中独当一面的专家?团队成员都信任你,你也求知上进,一直保持着技术学习的动力,有前瞻性。或者你已经是团队管理者,对某个领域有很好的战略策略思考,能带团队,能啃硬骨头。还有,你是否在过去十年中积累了业界口碑和人脉?当你需要工作时,你过去的工作履历,合作伙伴口碑,人脉积累才是你的贵人帮你35岁也不怕任何原因的失业,比如遭遇部门关门这样的黑天鹅。

https://www.zhihu.com/question/437925439/answer/1681476207

个人经验,不一定适合某个人。但有一些通用的规则,也许契合题主的“35岁仍然会被抢着要”的设想。

1.必须有能力做技术团队的管理。
这是你在多年工作中积累下来的技术能力、团队成员的协作经验,与各方stakeholder打交道的经验成就的,如果没有这一点,很难说到了一定年龄会有很大的竞争力。

2.必须有系统架构的能力。
你多年积累的项目/产品经验,与技术leader、架构师、DBA,产品经理、甚至是行业客户沟通打交道的经验的积累,只要你能持续总结和反思,都能帮你走到架构师这一阶段,有了这一技能加持,大概率还是有机会持续向上走的,而不大会被一刀切,即使被A公司优化了,别处应有机会。

3.最最最重要的一点,到了一定的年龄,你必须拥有你自己的资源、人脉的维护和积累,
在关键时刻,你有可供选择的余地,或者可能会被抢着要。职场上哪怕你只对技术感冒,其他不愿意去理会,你也要有意识的让你的领导和同事看到你是“靠谱”的,这都会为你日后的其他选择,积累无可替代的选择机会。如果有了第3点的优势,辅以第1、2点技能,程序员大概率会有一个靠谱的方式,帮我们避免所谓的“35岁危机”。

https://www.zhihu.com/question/437925439/answer/3104504655

当然是那种一直在一线撸代码,能力全面,经验丰富的老手了,这种一个顶10个。还有一种项目流程把控能力,成熟的程序员基本35岁以后才能积累足够的工具箱,有的时候一个人开发1个月的东西,换另外一组人可能要3-6个月,这些都是我的亲身经历,那么n人*n月,相当于成本高了几十倍。只有那种不求上进的,写ppt的很容易被淘汰替代。

https://www.zhihu.com/question/437925439/answer/1682432295

这么说吧,现实一点的目标,不是被公司抢着要,而是被用人部门的人抢着要。建议年轻人从一工作就立好自己的人设,比如说,不醉心于办公室政治但对周围有清晰的认知,对待技术认真、求真、不糊弄,对于业务能找到效果好、成本低的解决方案。这并不是说所有方面你都要做到100%的程度,真有这本事自然就是公司抢你了。这里说的是你要给周围同事建立这样的印象,以后他们在大公司里不管是招人还是内推,一想到你时脑海中浮现的就是这样的印象,他们觉得让你来做让人放心,这样你就能获得机会。当然,要有真材实料,不然人设就会坍塌。

https://www.zhihu.com/question/437925439/answer/1681494345

能解决问题的程序员。职位的本质,都是需要解决问题的,而很多问题在国内的技术层面上来说,是需要有特定的经验和技巧的人才能解决的,最明显的例子是驱动和算法,这些都是需要很多年经验积累的,这种要应届生过去毫无意义,这不是努不努力、加不加班、加不加人的问题。最明显的例子就是,现在主流的操作系统和行业软件,90%以上都不是国内的,甚至于国内的互联网公司都是做APP的,没一个能拿得出手的!其实从难易程度就可以看出来,技能能够长久有效的获取高薪,要么门槛很高,要么积累很重要,一些几个月学了java、Python之类就上手工作的人,几年后被更年轻和要价更低的人取代,不是很正常的事吗?你能几个月学会一门技术,别人也能,而且他们对薪资的要求比你低的多,如果你对于被替代还有不满,那你不是要公平,那是要抢劫…很多时候,好的C/C++程序员,对语言特性、算法和系统底层有深入的了解,那是需要持之以恒的努力和学习的,所以这种人越到后面越能够走得很高也很远,这个世界是平衡的。

https://www.zhihu.com/question/437925439/answer/1791644797

  • 其实无非有三类人,公司会抢着要:
    • 第一类,对某个行业有极深的了解,懂得把握行业趋势。
    • 第二类,在某个技术领域内有相对比较深的造诣,我们俗称的大拿。
    • 第三类,优秀的技术管理者,可能需要上面2个能力的合集,外加一定的管理沟通能力

下面展开来说。

  • 第一类,其实很多行业会有比较深的业务壁垒的,并不是随便招一个程序过来就可以干活的,比如银行系统领域,比如核心第三方支付系统。类似的还有财务、通讯、保险等,都需要在某个行业沉淀多年以后,才会对整个产品有一定深度的了解,这样编程起来才能真正的少走弯路,甚至指导年轻产品经理的工作。对某些行业来讲,很懂业务的程序员,亲睐有加。
  • 第二类,第二类就比较好说了,比如你是Mysql的顶级专家,或者JVM调优可以在国内挂的上号,不需要全才,只需要在某一个领域内有很深的研究。基本上就非常枪手了,特别是大型互联网公司,对这类人才的需求极度的渴望,工资可以给的非常高,而且能到这个级别的,大部分年纪也30+了。
  • 第三类,就是成熟的管理者了,对业务有一定的了解,技术不需要最顶尖,但对整个技术生态有一定的认识,同时沟通能力、协调能力也不错。很多互联网公司,会一直招聘中层的管理者,如果这方面能力不错,找工作也是不用愁的,基本上猎头都帮你搞定了

https://www.zhihu.com/question/437925439/answer/1730565869

  • 总结,35岁的年龄关卡确实实实在在的存在,但也同时存在着不卡年龄看重能力和企业。因为企业对不同岗位的求职者的能力要求是有很大差别的。

  • 在面试过程中通过跟面试官对话,确定其想要什么,保持对话水平跟面试官能同频,尽量把面试过程向你的优势经历上去引导。

  • 比如我的优势经历,就是在一个toC头部彩票电商企业呆了6年,负责核心交易部分,完整经历了0-10的过程,又出来跟着朋友创过2段业,带过团队,管过项目,兼职做过产品、顾问、营销。后又进入toB领域,在企业高速发展过程中,平衡产品、技术、人力的各种错配问题,保证你自己负责的那块业务按时保质的交付。

  • 所以,35之前,你要尽量保证自己技术那条腿给长粗了的同时,去想尽办法找机会,发展其他通用能力,比如沟通,组织协调,管理,表达能力等。

  • 当然啰,如果你就只想搞技术,往技术专家这条路上深耕,也要尽早给自己定一个技术方向,比如数据库,企业级开发,分布式计算、运维、大数据、人工智能、区块链,并在这个领域不断的深耕。而这个深耕也不是让你去追一堆的新技术,新框架,而就是能解决这个领域问题的核心原理,数据结构,算法,编程范型,设计模式,操作系统,网络基础这些基础中的基础

  • 可以看到,我现在的选择,基本都是熟人推荐过去的,有前同事,有现同事,甚至还有个从没打过照面过的同事介绍的。他们之所以为你提供机会,不仅仅只是因为有一层关系,而他们愿意因为这层关系,用他们的信任为你背书,这背后是基于对你的信任,而建立这个信任的过程,就是你能成事的事实。一个程序员能成事,技术永远是不可或缺的一环,但绝不唯一的一环。以下是我个人的一些总结思考,供你参考。

  • 关于技术:

    • 技术能力的提高是你自己的事,公司没有义务,你的导师也没有义务手把手教你成长。技术能力的锻炼是在做事中成长的,项目的天花板就是你技术上限的天花板,你要主动去参解决复杂的问题,复杂的项目,就算你当时没能力也要硬着头皮上。技术是服务于业务存在的,它只是手段而不是目的,最好最新的技术并不一定是最合适的技术,你要有意识的打造让自己顺手的武器库,切记不要贪多嚼不烂。技术是你吃饭的工具,但不要让它成为你唯一的工具,请想清楚技术对于自己到底意味着什么。
  • 关于关系:

    • 沟通能力是程序员职业生涯最重要的能力,没有之一,你如果不想成为一个只会编码的螺丝钉和编码机器,请主动拓展和锻炼这块的能力。请持续保持跟你的上下游(产品、测试、运维、甚至市场、销售),同级(同部门跨部门),高级(导师、直属领导)的同事有效沟通而不是发泄情绪,沟通的目的是达成共识,推进问题解决。你一定能找到为团队赋能的地方,请主动去承担更大的责任,并持续为此努力。学会站在领导的角度看问题,然后回到执行者的角度把活干好。想办法让自己成为一个团队的组织者、支持者、领导者而不仅仅只是一个发号命令的独裁者。
  • 关于做事:

    • 建立自己的工作原则,用原则驱动自己一天的工作。比如:让DRY成为你的核心准则之一:把困难的工作简单化,把简单的工作高效化,把重复的工作自动化。主动有意识的去做困难且有价值的事。合作而不是竞争,吃亏而不是占便宜。不要只埋头做事,还要找到展示自己价值的机会。更重要的事:身体健康是延长程序员职业生涯的必要条件。这个身体健康具体是指对抗随着你工作习惯逐步弱化的背部、腰部和臀部肌肉力量和最大摄氧量;尽早学会并养成健康的运动习惯,以保持身体高质量的精力水平。工作的熵(也就是负面情绪的能量),一定要自己在生活中找到合适的发泄口,不要让其积累。因为它会毁掉自己和自己的家庭。比起获得更高的薪水和职位,知道自己要什么是最最最重要的事。

https://www.zhihu.com/question/437831410/answer/1745528073

  • 如果你只考虑学历这一个因素,答案是会的。学历只能为你”有学习能力“这一个因素做背书。在其他条件相同的前提下,优先选择学历高的。那还有其他什么条件呢?

  • 之前偶遇一个高端猎头,给我的职业生涯做建议的时候,提到一个公司在看高级专业人才的时候,往往会考察以下三个点:

    • 你之前公司在行业的地位,以及你对此行业的熟悉程度(同行业跳)
    • 你有没有在知名公司专业序列技术经验或管理序列上的管理经验(跨行业跳)
    • 你的学历背景是不是知名高校(基础素质)
  • 我们常说的程序员”换行不换岗,换岗不换行“,其实就是在有效的积累1、2两点

  • 而面试是一个求职者和招聘者对齐信息的过程,而这个过程中,能给你简历里自夸”你有xxx能力“做”信用背书“只有三个东西,行业经验的积累(业务经验带给你的人脉和行业资源),一个就是你之前工作的平台(平台的职位给你的工作能力背书),一个就是你的学历(给你发证的学习给你的学习能力背书)。

  • 这几个点都指向一个基本事实:”你是资产而不是成本“,换句话说:”你能给公司创造价值,而且越快越好“。所以,学历只是在你还是应届毕业或者工作经验尚浅的时候比较有用。因为此时,招聘方其实没有其他考察的途径,你相当于是在用”未来成长的可能性“来换取当前这份工作的可能性,对公司来说,你就是一笔投资。你是拿这个预期在跟公司做价值交换。

  • 而你工作很多年了,还在拿学历说是,而不是上述1、2两点,这个时候,你的学历反而会成为一个质疑项目,学历越高这个质疑也会越大。所以就题主的问题,我个人建议,乘着年轻赶紧来北上深历练一下,可以选择一个朝阳行业(我自己的观察仅供参考:面向企业级的(toB),新能源,金融科技,云计算,智能制造,生物医疗,5G方向赛道的),从这个领域的小的初创公司切入进去。因为这些赛道在1-10的阶段(大概就是A-B轮),需要招大量的搬砖码农,还是可以获得不少面试机会的,然后就在公司内部随着公司成长,努力积累1、2两点相关的能力,再瞄准这个行业内,更大更强的公司。

  • 当然这一切,都需要你自身付出足够多的学习能力,吃别人更多的苦。因为程序员的核心能力就是”学习新事物的能力“,不断的精进这个能力,才是你在这个行业不被淘汰的核心。祝好运

https://www.zhihu.com/question/445718000/answer/1743512010

  • 我常常跟我的下属说:让你离职的唯一原因,就是你无法在这里获得成长。
  • 到底什么是成长?
  • 我个人的一个最基本的定义就是,当你手头的工作,都是不需要耗费很多脑力思考,就能很高效完成的事情,而此时你也无法通+ 过改变环境来改善这种处境的时候,才是你开始考虑换一份工作的时机。
  • 工作年限,永远不是一个程序员跳槽应该展示的资本,你从工作中获得成长的能力才是

附录

业务壁垒

行业的业务壁垒是指一组因素或条件,它们限制了新公司或竞争对手进入该行业并与现有公司竞争的能力。这些壁垒可以采取多种形式,通常取决于特定行业的性质。以下是一些常见的业务壁垒及其详细解释:

  1. 资本要求:

    • 行业需要大量资本来运营,例如制造业或航空业。新公司可能难以获得足够的资本来进入市场,并建立与现有公司竞争的规模和生产能力。
  2. 技术壁垒:

    • 行业内使用高度专业化或复杂的技术,这些技术需要时间和资源来掌握。新参与者可能需要投入大量资金和时间来开发或采用这些技术。
  3. 知识产权:

    • 存在专利、商标、版权或其他知识产权的行业可能难以进入,因为这些权利可以防止竞争对手复制或使用关键技术或品牌。
  4. 网络效应:

    • 在某些市场中,产品或服务的价值随着用户数量的增加而增加。已有的市场领导者通常拥有庞大的用户基础,新公司可能难以吸引足够的用户来建立竞争力。
  5. 渠道和分销:

    • 行业中的主要玩家可能已经建立了广泛的分销网络和渠道关系,使他们能够将产品或服务有效地推向市场。新公司可能需要时间和资源来建立类似的分销网络。
  6. 法规和许可:

    • 一些行业需要符合政府的法规和标准,或获得特定的许可证才能从事业务。这些法规和许可证可能对新公司构成障碍,因为它们需要时间和资源来满足。
  7. 品牌认知度:

    • 在市场上已有的品牌通常享有高度的认知度和信任度。建立和推广一个新品牌需要大量的市场营销和广告投入,以吸引客户并与竞争对手竞争。
  8. 垄断地位:

    • 如果某个公司已经垄断了市场,其他竞争对手可能很难进入并获得足够的市场份额。这种情况可能需要政府的干预来维护竞争。
  9. 切入成本:

    • 进入某些行业可能需要巨大的启动成本,例如购买设备、建立工厂或购买土地。这些成本可能会限制新公司的进入。
  10. 经济规模:

    • 具有较大规模的公司通常可以生产更多,从而降低单位成本。这使它们能够以更低的价格提供产品或服务,从而对小型竞争对手构成压力。

业务壁垒的类型和程度因行业而异,有些行业可能具有多种壁垒,而其他行业可能只有少数几个。成功的公司通常能够克服这些壁垒,但它们需要仔细的计划、战略和资源来应对挑战。同时,政府法规和市场变化也可能会改变业务壁垒的性质和程度。

简介

  • 代码评审

什么是 Code Review

  • Code Review 翻译成中文是代码评审,具体的定义可以看 wiki。这篇 wiki 介绍说 Code Review 在帮助团队找到代码缺陷这件事上作用巨大:“代码审查一般可以找到及移除约65%的错误,最高可以到85%”。实际上, Code Review 的好处远不止这一条,它至少能在以下三个方面帮到我们:
    • 传播知识。相信很多人第一次提交 Code Review 都有类似的经历:短短几百行代码,却被提了密密麻麻几十条 comments,更新了十多次代码,才最终被 accept 。其实当代码被 accept,提交代码的工程师通过这次 review 就学习到了代码规范和很多好的实践。同时,通过 review 更资深工程师的代码,年轻的工程师也更直观地学习架构和编码;另外,工程师之间也可以通过 review 代码来共享项目知识,看代码实现在绝大多数时候是了解项目的最好方式。
    • 增进代码质量。这点也很容易理解,有经验的工程师可以在架构设计、代码细节等各个方面帮助到初学者。不同工程师也会有知识盲点,互相 review 进步也很快。另外,被 review 的代码质量更高还有一个很多人注意不到的心理因素:在状态不佳的时候,工程师难免会匆忙写些“潦草”的代码,但是当你知道自己的代码会被review 的工程师提交 comment 打回来,自然会更仔细些 :
    • 找出潜在的 bug。这是大部分团队进行 Code Review 的目的。就像上面提到的,Code Review 在这方面效果不错。其实我认为大部分代码 bug 应该由单元测试,功能测试,性能测试和回归测试来保障。不过由于静态分析不理解业务,另外有些 bug 在测试中并不容易复现,这两种情况下,经验丰富的工程师来 review 代码就尤其重要了。

Code Review 不应该做

  • Code Review 应该讨论的是功能实现,架构设计,代码质量,不应该做以下两件事情
    • 检查代码风格和编程规范。除了新人,其他工程师提交的代码不应该通过 review 来确保代码风格。这里所说的代码风格包括但不限于:命名规范、代码缩进、注释和文档等等。你可以利用 IDE 或者其他工具来保证编程规范和代码风格的统一。如果你在制定团队的代码规范,可以 follow Google Java Style 或者 Facebook Coding Standards 。在这里我推荐好好看看 Facebook 的规范,因为 Google 的代码规范告诉你应该怎么做,而 Facebook 的规范解释了为什么要这样做,以及在什么情况下需要权衡。
    • 检查常规的 bad smell 和代码 bug 。《重构》 和 《Clean Code》 对代码 bad smell 都有非常详细的描述。团队的工程师应该熟读这两本书,避免这些 bad smell,比如:重复代码、过长函数、过大类、过于亲密的两个 classes 等,你可以利用 IDE 和静态代码检查工具 checkstyle、 findbugs 和 pmd 来帮你检查出这些问题。同样,代码中的大多数 bug 也不应该在 Code Review 阶段来发现,你应该通过静态工具、单元测试、集成测试和性能测试来发现它们

如何提高 Code Review 的效率

  • 选用合适的工具。

    • 我用过 Phabricator、Gerrit、Gitlab 来 review 代码。这里推荐使用 Phabricator ,就不过多介绍了,可以看 这里 的讨论。
  • 每次只 Review 少量代码。

    • 新人经常犯的一个错误,花了两周甚至更多的时间写代码,然后又花了一些时间做测试,等他们自己觉得“大功告成”才敢自信地提交 review,殊不知,这个时候提交的 review 几乎没有什么意义。一方面,对于提交 review 的工程师来说,辛辛苦苦开发测试了两三周,就等 review 完成后 release 了,这时候如果收到各种需要修改代码的意见,心里难免会有抵触情绪,尤其是 review 的结果是架构需要改动,代码需要大面积重写,内心一定是崩溃的。另一方面,代码审查者如果面对数千甚至上万行代码,需要理清项目架构都需要花费大量时间,强行 review 这种代码,争论、修改、测试代码,很可能 一周甚至更长时间都完成不了 review,结果就是双方都痛苦不堪。在实践过程中,我们认为,频繁 review 代码并且每次只 review 少量代码非常重要,我自己认为 reivew 不超过 500 行代码比较好。
  • 明确职责。

    • Review 过程中经常遇到的一个问题是 review 响应不及时。比如 assgin 给了工程师,工程师没有及时 Review,或者提交 review 的工程师没有及时响应修改意见。造成这种现象的原因大致有这么几种:工程师没有及时处理 review 的习惯;review 工程师需要项目的领域知识等。解决方法也很简单,Review 是项目开发的一部分,进度由开发工程师来负责,这样,Code Review 如果不顺利,应该由提交代码的工程师负责推动,如果需要讲解代码,提交代码的工程师应该主动走到 reviewer 工位上,说说背景知识和代码逻辑。也就是说,如果沟通受阻,工程师应该更积极的面对 reviewer ,毕竟大家是在花自己的时间来帮助他。
  • 整理 checklist。

    • 如果你回顾犯过的编程错误就会发现,在某个阶段自己容易犯类似的错误。其实上,团队里的工程师也有这种情况。刚入门的工程师会出现 API 误用;刚加入团队的工程师对编码规范需要一段时间来适应;有些工程师在代码命名上总会犯同样的错误;也有一些工程师搞不清楚并发编程;还有工程师甚至常常写面条式的代码而不自知。如果每位工程师有自己的 checklist 来记录这些问题,定期回顾自己是不是还在犯类似的错误,他们的水平就会很快提高,至少不容易重复已经犯过的错误。同样,团队也需要积累 Code Review 的 checklist,刚开始,这个 list 可能非常初级,会有一些常见的 bad small,甚至代码规范的内容。不过没关系,相信随着团队成员能力的提升,这个 list 慢慢会集中在设计方面,比如编写代码的工程师有没有考虑到代码可维护性、扩展性和性能等等。
  • 完善CI/CD设施。

    • 很多团队不愿意做 Code Review,其实和不愿意做单元测试、集成测试原因一样,这些团队的CI/CD 工具不成熟,每增加一个不直接产出“功能代码”的步骤就会增加工作负担。其实根本原因是工程效率工具的缺失。
  • 培养工程师的能力。

    • 还有一个比较常见问题是,有些新人面对被 review 代码往往提不出问题。这个时候就需要工程师提升自己的能力。如果平时有积累,面对等待 review 的代码,即使不能面面俱到,也能提供不少有价值的意见,比如整理学习 Restful API 知识,在评审 Http 接口代码时就会是专家;掌握了 Spring 框架,Guava 等工具类,也能在很多时候提出很好的建议。慢慢地积累更多经验后,这些工程师就能提出更多业务、设计方面的意见

注: CI/CD设施

“CI/CD” 是持续集成(Continuous Integration)和持续交付(Continuous Delivery)的缩写,是软件开发中的一种流程和方法论。它旨在自动化和简化软件开发、测试、部署和交付的过程,从而提高软件交付的速度和质量。

持续集成(Continuous Integration,CI)
持续集成是指开发团队将他们的代码频繁地集成到共享的版本控制库中,每次集成都会触发自动化的构建、测试和代码质量检查。这可以帮助团队尽早地发现和解决代码集成导致的问题,确保代码在整体上保持稳定和可工作的状态。CI 可以减少代码集成时的冲突,并鼓励更频繁地提交代码,以便更快地发现和修复问题。

持续交付(Continuous Delivery,CD)
持续交付是在持续集成的基础上,自动化地将可工作的、经过测试的代码交付到一个类似于生产环境的环境中。这种做法可以确保在每个阶段的开发过程中都存在可部署的代码,从而使团队随时都能够将新功能、改进或修复部署到生产环境中,而不需要复杂的手动步骤。

持续部署(Continuous Deployment,CD)
持续部署是持续交付的一种更进一步的扩展,它是指将经过测试的代码自动发布到生产环境中,以实现实时或几乎实时的部署更新。这需要高度的自动化和测试覆盖率,以确保新的代码变化不会破坏现有的生产环境。

综上所述,CI/CD 是一种在软件开发过程中通过自动化和持续的方式来集成、测试、交付和部署代码的方法,旨在提高软件质量、降低风险,同时加速软件交付的速度。这种方法对于现代软件开发中的敏捷和迭代式开发非常重要,它可以帮助团队更快地交付新功能、修复错误并响应市场需求。

注: checkstyle

Checkstyle 是一个用于静态代码分析的工具,用于帮助开发团队在代码编写过程中遵循统一的代码风格和最佳实践。它可以在代码编写的早期阶段发现潜在的代码质量问题,从而提高代码的可读性、可维护性和稳定性。以下是关于 Checkstyle 的详细解释:

功能和特点

  • 代码风格检查Checkstyle 可以根据预定义的代码风格规则,检查代码是否符合规范,例如缩进、命名约定、括号使用等。
  • 代码质量检查:它可以检查代码中的各种问题,如未使用的变量、未使用的导入、冗长的方法等。
  • 配置灵活:你可以根据团队的需求和偏好,自定义和配置各种规则和检查项。
  • 支持多种编程语言:虽然最初是为 Java 设计的,但 Checkstyle 也可以用于其他编程语言,如 C、C++、C#、XML 等。
  • 命令行和集成Checkstyle 提供命令行工具,也可以与常见的集成开发环境(IDE)和持续集成工具(如 Jenkins)集成。
  • 可扩展性:你可以编写自定义的 Checkstyle 规则和检查器,以满足特定需求。

使用示例
以下是一个简单的使用 Checkstyle 的示例。假设你有一个 Java 项目,你可以按照以下步骤进行静态代码分析:

  1. 安装 Checkstyle:首先,你需要下载并安装 Checkstyle。你可以从 Checkstyle 的官方网站或仓库获取最新的版本。

  2. 配置文件:创建一个 Checkstyle 配置文件,其中包含你想要的代码规范和检查项。配置文件可以是 XML 格式。

  3. 运行 Checkstyle:使用命令行工具,运行 Checkstyle 并指定要分析的源代码文件或目录以及配置文件。例如:

    1
    checkstyle -c my_checkstyle_config.xml src/

    这将对指定的源代码进行静态分析,并根据配置文件中的规则和检查项报告问题。

  4. 查看报告Checkstyle 将生成一个报告,显示代码中的问题、违反的规则以及建议的修复措施。

  5. 集成到持续集成流程:你可以将 Checkstyle 集成到你的持续集成流程中,以便在每次代码提交或构建时自动运行代码分析,并生成相应的报告。

需要注意的是,Checkstyle 只是众多静态代码分析工具之一。在使用它之前,你需要了解团队的编码规范,配置适当的规则,并根据报告进行代码修复。同时,还可以考虑与其他代码质量工具、代码审查流程等结合使用,以提高代码质量和开发效率。

静态代码检查工具 findbugs 详解

FindBugs 是一个用于静态代码分析的工具,用于发现 Java 代码中潜在的 bug、错误和不良实践。它能够帮助开发人员在代码编写的早期发现潜在的问题,从而提高代码的质量和可靠性。以下是关于 FindBugs 的详细解释:

功能和特点

  • 静态分析FindBugs 在不执行代码的情况下,对源代码进行分析,以查找潜在的问题和错误。
  • 多种检查:它可以检查诸如空指针引用、资源未关闭、不良的异常处理、未使用的变量等多种问题。
  • 定制规则FindBugs 允许你配置和定制不同的规则,以适应你的项目需求和编码标准。
  • 可视化报告:分析结果会生成一个可视化的报告,展示了发现的问题、问题的严重程度和建议的修复措施。
  • 持续集成集成:它可以与常见的持续集成工具(如 Jenkins)集成,使代码分析自动化并集成到开发流程中。

使用示例
以下是一个简单的使用 FindBugs 的示例。假设你有一个 Java 项目,你可以按照以下步骤进行静态代码分析:

  1. 安装 FindBugs:首先,你需要下载并安装 FindBugs。你可以从 FindBugs 的官方网站或仓库获取最新版本。

  2. 运行 FindBugs:使用命令行工具,运行 FindBugs 并指定要分析的编译后的类文件或 jar 文件。例如:

    1
    findbugs -textui my_project.jar

    这将对指定的 jar 文件进行静态分析,并生成文本报告。

  3. 查看报告FindBugs 将生成一个报告,显示代码中的问题、问题的严重程度以及建议的修复措施。

  4. 集成到持续集成流程:你可以将 FindBugs 集成到你的持续集成流程中,以便在每次代码提交或构建时自动运行代码分析,并生成相应的报告。

需要注意的是,FindBugs 是一个非常有用的工具,可以帮助你在开发过程中及早发现潜在的问题。然而,它并不是万能的,它只能发现静态代码中的问题,有些问题可能需要更深入的分析和测试来发现。在使用 FindBugs 之前,你需要了解规则和报告,以便理解其结果并决定如何处理问题。

静态代码检查工具 pmd 详解

PMD 是一个用于静态代码分析的开源工具,用于检测代码中的潜在问题、错误、不良实践和性能优化机会。它可以帮助开发人员在代码编写的早期阶段发现并解决潜在的问题,从而提高代码的质量和可维护性。以下是关于 PMD 的详细解释:

功能和特点

  • 多语言支持:除了 Java,PMD 还支持其他语言,如 JavaScript、Apex、PLSQL 等。
  • 多种检查规则:它提供了多种内置的检查规则,用于检查代码中的不良实践、错误、性能问题等。
  • 自定义规则:你可以创建自定义规则,以适应项目的需求和编码标准。
  • 报告生成PMD 生成可视化的报告,展示了发现的问题、问题的严重程度和建议的修复措施。
  • 集成到开发环境PMD 可以与常见的集成开发环境(IDE)集成,如 Eclipse、IntelliJ IDEA 等。
  • 命令行支持:它也可以通过命令行工具在构建过程中运行,并将结果导出为文本、HTML 或 XML 格式的报告。

使用示例
以下是一个简单的使用 PMD 的示例。假设你有一个 Java 项目,你可以按照以下步骤进行静态代码分析:

  1. 安装 PMD:首先,你需要下载并安装 PMD。你可以从 PMD 的官方网站或仓库获取最新版本。

  2. 运行 PMD:使用命令行工具,运行 PMD 并指定要分析的源代码文件或目录。例如:

    1
    pmd -d src/ -R ruleset.xml

    这将对指定的源代码进行静态分析,并使用指定的规则集(ruleset.xml)进行检查。

  3. 查看报告PMD 将生成一个报告,显示代码中的问题、问题的严重程度以及建议的修复措施。

  4. 集成到持续集成流程:你可以将 PMD 集成到你的持续集成流程中,以便在每次代码提交或构建时自动运行代码分析,并生成相应的报告。

需要注意的是,PMD 是一个有助于代码质量和可维护性的工具,但并不是完美的。它可以帮助你发现静态代码中的问题,但不能解决所有问题。在使用 PMD 之前,你需要了解规则和报告,以便理解其结果并决定如何处理问题。结合其他代码质量工具、代码审查流程和测试策略,可以更好地提高代码质量。

注: Phabricator 工具 详解

Phabricator 是一个由 Facebook 开发的开源软件开发协作平台,旨在帮助团队更高效地进行软件开发、代码审查、协作和项目管理。它整合了多个工具和功能,以提供一个综合的开发环境。以下是关于 Phabricator 的详细解释:

功能和特点

  1. 代码托管和版本控制:Phabricator 提供了代码托管功能,支持 Git、Mercurial 和 Subversion。团队可以在平台上进行代码提交、分支管理、代码合并等操作。

  2. 代码审查:Phabricator 提供强大的代码审查功能,允许团队成员在提交代码之前进行审查和讨论。审查者可以提供反馈、评论和建议修改。

  3. 任务和项目管理:团队可以在 Phabricator 中创建任务、追踪工作进度、分配任务给成员,并将任务组织成项目来管理整体项目流程。

  4. 代码浏览:Phabricator 提供功能强大的代码浏览工具,允许用户查看代码提交的差异、历史记录、注释等。

  5. 文档和维基:平台上的 Phriction 组件允许团队创建和维护文档、维基页面,以方便知识共享和团队协作。

  6. 构建和部署集成:Phabricator 可以与持续集成和部署工具集成,支持自动化构建、测试和部署。

  7. API 和扩展性:Phabricator 提供了强大的 API,使开发者可以自定义和扩展平台的功能。

  8. 轻量级和高度可配置:尽管具备丰富的功能,Phabricator 仍然保持了一定的轻量级特性,并提供了丰富的配置选项。

  9. 开源和社区支持:作为开源项目,Phabricator 拥有活跃的社区,用户可以获取开发文档、论坛支持等。

使用场景

  • 软件开发:Phabricator 提供了从代码编写、审查、测试到部署的一体化开发环境,适用于团队协作开发。

  • 代码审查:Phabricator 的代码审查工具有助于提高代码质量,促进团队合作,减少代码缺陷。

  • 项目管理:通过任务和项目管理功能,团队可以更好地组织和跟踪项目进度。

  • 知识管理:文档和维基功能使团队可以共享知识、最佳实践和资源。

  • 持续集成和部署:Phabricator 可以与构建和部署工具集成,支持自动化的持续集成和部署流程。

需要注意的是,尽管 Phabricator 提供了丰富的功能,但在实际使用中,根据团队需求可能需要一些学习和配置。如果你打算使用 Phabricator,建议查阅其官方文档以获得更详细的使用指南和配置信息。

注: Gerrit 工具 详解

Gerrit 是一个基于 Git 的开源代码审查工具,专门用于团队协作进行代码审查和管理。它提供了一个集中式的方式来处理代码审查流程,帮助团队更有效地合并和审查代码变更。以下是关于 Gerrit 的详细解释:

功能和特点

  1. 代码审查:Gerrit 的核心功能是代码审查,它允许开发人员将代码变更(提交)提交到 Gerrit 中,然后其他开发人员对这些变更进行审查和讨论。

  2. 权限控制:Gerrit 具有灵活的权限控制机制,可以细粒度地控制哪些用户有权进行审查、合并或提交代码。

  3. 集成 Git:Gerrit 是基于 Git 的,因此它与 Git 版本控制系统紧密集成,可以直接与 Git 仓库交互。

  4. 线上评论:审查者可以在代码行级别提供评论和反馈,以便进行详细的技术讨论和修正。

  5. 自动构建和测试集成:Gerrit 可以与持续集成工具集成,以自动构建和测试提交的代码,确保质量。

  6. 审查工作流:Gerrit 支持多种审查工作流,如拉取请求(Pull Request)式和代码共享式。它使团队可以根据需求选择适合的工作流。

  7. 可定制性:Gerrit 可以根据团队的需求进行定制,包括主题、插件、报告等。

  8. 报告和统计:Gerrit 提供了审查的报告和统计信息,帮助团队了解审查的状态和趋势。

使用场景

  • 代码审查:Gerrit 最主要的使用场景是代码审查。团队可以使用 Gerrit 进行严格的代码审查流程,确保代码质量。

  • 团队协作:Gerrit 促进了团队内部的协作,通过审查、评论和讨论,开发人员可以共同改进代码。

  • 质量控制:通过自动构建和测试集成,Gerrit 帮助团队确保代码变更不会破坏现有的代码质量。

  • 版本控制管理:Gerrit 作为一个版本控制系统,可以帮助团队集中管理代码库,确保代码的安全性和一致性。

需要注意的是,Gerrit 需要一些学习和配置,特别是对于团队来说,要设置好合适的权限和工作流程。如果你打算使用 Gerrit,建议查阅其官方文档以获得更详细的使用指南和配置信息。

注: gitlab 工具 详解

GitLab 是一个基于 Git 的开源代码托管和协作平台,提供了版本控制、持续集成、代码审查、项目管理和多个其他开发工具。它可以帮助开发团队更高效地进行软件开发、协作和交付。以下是关于 GitLab 的详细解释:

功能和特点

  1. 代码托管:GitLab 提供了强大的代码托管功能,支持 Git 版本控制系统。团队可以在平台上创建代码仓库、分支、标签等。

  2. 持续集成(CI):GitLab 内置了持续集成功能,允许团队将代码自动构建、测试和部署。它集成了运行测试、生成报告等功能,有助于确保代码的质量。

  3. 代码审查:GitLab 提供了内置的代码审查工具,可以帮助团队进行代码审查、评论和讨论。审查者可以提供反馈,改进代码质量。

  4. 项目管理:GitLab 具备任务追踪、问题管理、里程碑、项目看板等功能,支持团队管理项目和跟踪进度。

  5. 持续交付(CD):除了持续集成,GitLab 也提供持续交付功能,可以自动将代码部署到生产环境中。

  6. 容器注册表:GitLab 集成了容器注册表,支持存储和管理 Docker 镜像,方便构建和部署容器化应用。

  7. 集成第三方工具:GitLab 可以与其他开发工具(如 JIRA、Slack)进行集成,实现更好的协作和通信。

  8. 自动化流程:GitLab 的 CI/CD 支持自动化流程,从代码提交到部署的整个流程都可以自动执行。

  9. 自定义配置:GitLab 提供丰富的配置选项,允许团队根据需要定制开发流程。

使用场景

  • 版本控制:GitLab 提供了稳定和强大的代码托管功能,适用于任何需要版本控制和代码管理的团队。

  • 持续集成和持续交付:通过 GitLab 的 CI/CD 功能,团队可以自动构建、测试和部署代码,提高交付效率。

  • 代码审查:内置的代码审查工具有助于提高代码质量和团队协作。

  • 项目管理:任务追踪、问题管理等功能帮助团队更好地组织和跟踪项目进度。

  • 容器化应用开发:容器注册表和集成的容器构建功能使 GitLab 适用于容器化应用的开发和部署。

  • 跨团队协作:通过集成第三方工具,团队可以更好地进行协作和通信。

需要注意的是,GitLab 提供了广泛的功能,可能需要一些学习和配置,特别是对于团队来说。如果你打算使用 GitLab,建议查阅其官方文档以获得更详细的使用指南和配置信息。

简介

  • 存储一些个人的,可以公开的信息
  • 梳理所学的知识,寻找要学习的知识

项目介绍

  • 项目介绍,按照下面四个步骤进行,保证无遗漏,而且能出亮点

    • 简短的项目背景
    • 自己完成的任务
    • 为了完成任务,自己做了那些工作,是怎么做的
    • 自己的贡献
  • 第一步,项目背景不用过多介绍,几句话即可。如果这个项目是一个大流量,大用户,负责度高的项目,一定要描述出来,这是亮点。

  • 第二步,自己完成的任务,一定要写明 参与 还是 负责,用词很重要。当然,如果你对项目的一个模块很熟悉,也可以写负责XXX模块。只要你在面试时能够回答的上来即可,完全看你个人对项目的熟悉程度。注意,对一个项目的熟悉不仅仅是技术,还有项目管理,项目流程方面的。

  • 第三步,这一步其实是一个简单的证明,证明你有能力做上述的任务。你可以写出一些技术名词,例如用了哪个平台,用了哪些技术,什么测试工具。但是别过于冗长,简洁明了即可。简历不是论文,只要能够吸引人即可,详细的后面还有面试。

  • 第四步,自己的贡献,一定要写的具体一些,最好都要量化,例如性能提高了百分之多少,一共修改了多少个bug等等,这就跟你在公司晋升述职汇报一个道理

简历优化技巧

  • 程序员在找工作时,一开始有三件事情会对能否获得面试机会至关重要:
    • 知识,技能,经历梳理
    • 确立求职目标
    • 简历优化

知识,技能,经历梳理

  • 知识,技能,经历,这都是一个人能体现出来的商业价值。

  • 一家企业招募某个人,一定是因为这个人可以帮助企业在某方面实现价值。而且,正常情况下,个人的贡献一定要大于企业为这个人负担的各种成本。

  • 所以,作为程序员,我们一定要清楚自己的价值在哪里。个人的商业价值,可以通过下面的五大要素分析出来:

    • 知识,技能,经历,天赋,人脉
  • 在最开始的时候,不建议直接到招聘简历上填写简历。强烈建议先用Word或者Markdown来整理记录你认为你具备的所有有价值的知识,技能,经历,不论大小,统统记录下来。这是后续优化简历的基础,也是确立求职目标的基础。

知识和技能

  • 知识可以通过语言文字,语音,视频进行传授,比如像C++,Java,数学,物理,Qt,Android,设计模式,网络协议等都是知识。

  • 技能,是指按照某种规则应用知识和经验完成某种任务的能力。比如使用Qt开发桌面客户端就是一种技能,使用Java和Android界面类库开发APP也是一种技能。

  • 我所具备的知识大概有:

    • C,C++,Python,Qt,MySQL,Json,FFmpeg,HTTP,socket,WebSocket,前处理,推理,后处理,Fasis第三方库,图像编解码,mongoose第三方库, 共享内存,图漾SDK适配,modbus
  • 我最熟悉的三种知识:

    • C,C++,Json
  • 技能就是对知识的运用,所以一般来讲你有什么知识,就能找到一组对应的技能。

  • 例如

    • 使用Qt开发客户端软件
    • 使用Qt开发服务器软件
    • 使用Java开发Android App
    • 管理项目,制定项目计划,跟踪计划,控制项目进度
  • 需要特别注意的是,每个人都有很多知识和技能,一定要找出你擅长的2-3种知识,2-3种技能,这将是你求职时的重要参考。人只有使用最擅长的技能去做事情,才能达到最好的效果。

经历

  • 知识和技能可以帮助我们创造商业价值,而知识和技能的积累过程本身也是有价值的。积累知识和技能的过程,就是经历。

  • 在回顾项目经历时,关于你自己的那部分,一定要想明白并记录下来,从下面三点来挖掘你的亮点:

    • 你负责的工作内容
    • 用到的知识,技能
    • 你对整个项目的贡献(最好可以量化)
  • 协作机器人底层控制服务开发

    • 项目描述:研发协作机器人,需要一个服务器,提供对硬件设备进行控制,例如机械臂的控制,相机的控制,末端工具的控制等等。为后端业务开发提供功能基础
    • 用到的知识,技能:
      • C++,modbus,OpenCV,Json,
      • 异步服务器,可同时接收多个请求,每个请求启动一个线程,处理
      • 多态,不同的设备,抽象出统一的控制接口
      • 请求,使用httplib第三方库,Json使用nlohmann/json第三方库
    • 我对整个项目的贡献:
      • 实现对物理设备的控制,对上一层提供统一的控制接口,是上层业务开发的基础,是整个项目运行的基础
  • 边缘计算产品开发

    • 项目描述:人工智能行业,边缘计算产品,实现从共享内存获取图片,到推理,检测业务,Web后端,用C++实现,实现低成本方案的边缘计算产品
    • 用到的知识,技能:
      • C++11, mongoose, sqlite3,Json
      • Web后端开发
      • 图片服务器开发
    • 我对整个项目的贡献:
      • 从图片服务器到Web后端服务器开发,都是我完成的,实现了低成本方案的边缘计算产品
  • 机械臂主控系统研发

    • 项目描述:机械臂主控系统研发,结合机械臂控制算法,编写一个服务器,对外提供机械臂控制的接口
    • 用到的知识,技能:
      • C++,mongoose,libjsoncpp第三方库,WebSocket
      • 服务器开发
    • 我对整个项目的贡献:
      • 熟悉机器人学相关理论知识,实现对机械臂控制算法的抽象,为前端提供接口,实现机器人的控制
  • 动态人脸识别项目开发

    • 项目描述:对图片进行人脸识别,并进行人脸矫正的底层服务器开发
    • 用到的知识,技能:
      • C++,libjsoncpp
      • 人脸库的管理,
    • 我对整个项目的贡献
      • 实现人脸服务,输入一张base64编码的图片,输出这张图片中人脸的检测框信息,输入一张人脸图片,输出识别结果
  • 实现服务自启动

    • 项目描述:VideoProcess产品是由前端JS,后端Python,服务vca组成的,客户需要在无网络,无人值守的环境下实现断电自启动
    • 用到的知识,技能:
      • docker,bash shell
      • docker镜像制作
      • 自启动脚本编写
    • 我对整个项目的贡献
      • 掌握基础的docker知识,将原本的产品服务都迁移至docker内部,制作docker镜像,并编写产品初始化脚本,实现无网络,无人值守环境下服务自启动
  • 晶视1838硬件产品下图像编码功能适配

    • 项目描述:对晶视1838智能盒子进行硬件适配,包括视频编解码,推理加速
    • 用到的知识,技能:
      • C++
      • 图像编解码
    • 我对整个项目的贡献:
      • 熟悉视频流编解码理论知识,实现图片编码功能的适配,
  • A311D硬件产品下推理功能适配

    • 项目描述:对A311D智能盒子进行硬件适配,硬件推理加速
    • 用到的知识,技能:
      • C++
      • 前处理,推理,后处理
    • 我对整个项目的贡献:
      • 熟悉模型工程化的理论知识,实现基于yolov3的目标检测
  • 遗留物检测

    • 项目描述:需要对静止物理进行检测
    • 用到的知识,技能:
      • C++,OpenCV
    • 我对整个项目的贡献:
      • 熟悉传统目标检测流程,实现帧差法遗留物检测

确立求职目标

  • 不管是从大学走向社会的初次求职,还是在职场上摸爬滚打了N年,找工作时都要忌讳的一点:茫无目的,漫天撒网

  • 求职时,明确目标行业,企业,职位,有针对性的做准备,事半功倍

  • 职业连续性

    • 跳一次槽换一个行业,跳一次槽换一条技术栈,这样极其不利于程序员的商业价值积累(知识,技能,业务)。假如你不是第一次求职,就有必要考虑职业延续性。
  • 成就事件,挖掘职业兴趣

    • 在我们总结整理自己的工作,项目经历时,要特别留意那些让你特别有成就感的事件,其中隐藏你的职业兴趣,可以挖掘出你今后乐意从事的职业方向。
  • 聚焦行业,企业,职业

    • 聚焦的目的是缩小目标范围,节省时间和精力,深入研究分析,有针对性的对自己的商业价值进行优化组合,提高简历的吸引力,最后提升获取面试机会的概率
  • 程序员运用编程语言,技术框架,设计模式,算法等开发针对某个领域问题的软件,软件必然和目标需求和业务密不可分,所以,程序员左手技术,右手业务,假如你对业务内容完全不感兴趣,很难想象你可以把软件做好。

  • 因此,当你有了目标产业及目标公司后,还要去了解这家公司做什么产品,是产品导向,项目导向,还是外包为主,选择那家你对他的业务范围感兴趣的公司,不感兴趣的果断筛掉

  • 基于延续性的考量,以往工作过的行业领域都需要认真对待,但不一定非要继续在之前的方向上做,换一换也可以。但有一个基本的原则:离夕阳产业和走下坡路的企业远点

简介

  • 绩效考核相关笔记

自我评价 模板

  • rk平台项目 : mnc

    • 代码量 一万七千多行
  • vcr平台项目 : vcr

    • 代码量 一万两千多行

给你一个横版。

  • 所做事项:

    • 已完成****,
    • 未完成****,
    • 未完成原因****,
    • 计划何时完成*****
  • 取得成绩:*****

    • (尽量数据化,比如完成项,件,占比**%)
  • 自我提升:*****

    • (学到什么?长进了什么?为更好地产生绩效服务)
  • 不足之处:*****

    • (哪些不足需要改进?怎么改进?)

紧扣工作内容,力求做到不突兀、不生硬,不长篇大论,切不可肆意抒情。

2023年自我评价

我所做的主要工作有机械臂主控系统开发,rockchip平台的边缘计算产品开发,协作机器人的视觉控制系统底层服务器开发。所有项目代码约三万行,按时完成领导分配的开发任务。
在个人能力上,通过完成一个个开发任务,分析问题,解决问题的能力得到了很大的提升,能够独立处理问题和新的项目需求。在技术上,使用C++编程语言进行工程开发的能力得到了极大提升,同时熟悉了python编程语言,能够编写python测试程序,提高了程序测试的效率。在团队合作上,在机械臂主控系统开发阶段和前端的对接,在协作机器人的视觉控制系统开发阶段对接后端和算法等,这些经历都对我的团队合作能力和沟通交流能力有极大的提升,现在能够高效率的提出需求或者找到需求并解决。
我的不足之处有不够高效的代码和项目框架设计能力欠缺。针对不够高效的代码的改进方法,我将阅读和学习优秀的开源项目代码,重新翻阅自己的代码以进行优化;针对项目框架设计能力欠缺的改进方法,我将阅读相关书籍,例如设计模式等,学习相关理论知识,针对新项目多思考和实践来增强项目框架的设计能力。

简介

  • 资金记录
  • 短期目标,2023年存款3万
  • 中期目标,2025年存款30万

2023.10.10

  • 招商银行:8090.85

  • 微信: 1090.07

  • 农业银行:2672.23

  • 信用卡:-113.30

  • 总计:

    • 11853.15 - 113.30 = 11739.85
  • 节前计划:

    • 预计工资+当前资金:7343.25 * 3 + 11739.85 = 33769.6
    • 租房补贴:3 * 833.33 = 2499.99
    • 房租预计: 3 * 600 = 1800
    • 春节存款:三万元,表示 第一份工作,时间:一年半,存款:三万

2023.11.10

  • 工资: 7343.25

  • 10月01日 - 10月31日

    • 餐饮 575.55
    • 房租 555
    • 购物 431.30
    • 其他 368.6
      • 和购物相同
    • 服务 124
    • 服饰 99
    • 运动 47
    • 交通 15
    • 旅行 12
  • 10月总计:2227.45

  • 11月01日-11月10日

    • 餐饮 214.11
    • 购物 169.50
      • 闲趣坊
      • 超市
    • 娱乐 60
      • 大润发 游戏厅
    • 其他 37.10
  • 十一月十天总计:495.71

  • 支付宝:864.34 + 2000 = 2864.34

  • 招商银行:11041.13

  • 农业银行:2672.23

  • 招商信用卡:-458.70

  • 总计

    • 13254.66
  • 2023.11.24 统计

    • 农业银行 5171.21
      • 租房补贴进账 2499
    • 支付宝
      • 转账 3000
    • 招商银行: 2556.04
    • 总计:
      • 5171.21 + 2556.04 + 3000 = 10727.25
  • 计划

    • 工资 7343.25 - 预计花销 2230 = 存款 5113.25 + 现有存款 13254.66 = 总计 18367.91

2023.12.10

  • 工资: 7343.25

  • 2023.12.23 统计

    • 农业银行 5171.21
    • 招商银行 5874.36
    • 总计:
      • 5171.21 + 5874.36 = 11045.57
    • 大额消费:
      • 房租: 600
      • 九价最后一针: 1418
  • 上次计划

    • 2023.11.24实际资金: 5171.21 + 2556.04 = 7727.25
    • 2023.12.24实际资金: 5171.21 + 5874.36 = 11045.57
    • 存款为: 11045.57 - 7727.25 = 3318.32
  • 本次计划

    • 工资7343.25 - 预计花销 2000 = 存款 5113.25 + 现有存款 11045.57 = 总计 16158.83

2024.1.10

  • 工资: 7343.25

2024.2.10 - 2024.1.10

  • 工资预计收入: 22029.75

2024.03.08

  • 总存款: 3w

  • 当前余额:

    • 招商: 8452.97
    • 农业: 318.42
    • 信用卡: -92.95
  • 截至下一次收入之前的规划

    • 存钱: 6000
    • 房租: 700
    • 剩余: 1752.97 + 318 - 92.96 = 1978.01

2024.03.18

  • 总存款: 3.6w
  • 当前余额
    • 招商: 1660.9
    • 农业: 298.42
    • 信用卡: -92.95

2024.04.12

  • 总存款: 3.6w + 5k + 2k = 4.3w

  • 当前余额

    • 招商: 1886.88
    • 农业: 42.93
    • 信用卡: -334.58
    • 微信: 800.07
    • 总计: 2395.3
  • 上一次统计到目前为止,大额输出是: 苏州游玩 1000+ 和 三个月的房租 1506

  • 截至下一次收入之前的规划

    • 存钱: 8000
    • 日常开销: 1000+
    • 剩余: 2395.3 - 1000 + 400 = 1800

2024.05.10

  • 2023年存款 3w
  • 2024年存款 6k + 5k + 8k = 1.9w

2024.06.08

  • 2023年存款 3w
  • 2024年存款 1.9w + 0.6w = 2.5w

2024.07.31

  • 2023年存款 3w

  • 2024年存款 2.5w + 1.65w = 4.15w

  • 当前余额

    • 微信: 441.31
    • 招商: 4527.03
    • 农业: 1.15
    • 中国: 22.2
    • 总计: 4991.69
  • 大额消费

    • 魔方公寓房租: 1250
    • 大食堂会员: 200
    • 乐游暑期观光卡: 398
    • 水蜜桃: 130 + 150 + 100 = 380
    • 总计: 2228
  • 未来规划

    • 存钱: 5000 + 2400 + 1500 = 8900
    • 日常开销: 1250 + 1500 = 2750+
    • 剩余: 4991.69 - 2750 = 2241.69

2024.08.23

  • 当前余额

    • 微信: 1609.41
    • 招商: 298.29
    • 农业: 499.99
    • 中国: 1024.6
    • 总计: 3432.29
  • 未来规划

    • 存钱: 无
    • 日常开销: 1250 + 2000+ = 3250+
    • 剩余: 3432.29 - 3250 = 182.29
    • 九月份工资预计: 10140

2024.09.25

  • 当前余额

    • 微信: 264.95
    • 招商: 252.46
    • 中国: 8652.03
    • 总计: 9196.44
  • 未来规划

    • 现在的钱用过西藏旅行
    • 下个月再存钱

2024.10.15

  • 当前余额

    • 微信:7.16
    • 招商:205.56
    • 中国:1247.4
    • 信用:-251.71
    • 总计:1208.41
  • 未来规划

    • 工资预计:15000 * 0.845 = 12675
    • 购买手机:8000
    • 房租:1250
    • 存款:2000
    • 生活费:1425

2024.10.28

  • 工资:11547.38 + 350 = 11897.38

  • 生日:1w(iphone15 promax)

  • 当前余额

    • 微信:1.23
    • 招商:147.4
    • 中国:1853.61
    • 信用:-251.71
    • 总计:1750.53
  • 未来规划

    • 房租:欠租
    • 生活费:1750.53

2024.12.11

  • 工资: 12889.8 + 200 = 13089.8

  • 存款: 4.15w + 1w = 5.15w

  • 房租: 1k

  • 当前余额

    • 中国: 907.52
    • 招商: 3.46
    • 信用: -143.13
    • 总计: 767.85