Jiahong 的个人博客

凡事预则立,不预则废


  • Home

  • Tags

  • Archives

  • Navigation

  • Search

Linux——代理使用教程


整体说明

  • 本文以 CentOS 的终端中配置代理为例
  • 通过设置环境变量来实现
  • 某些工具的代理比较特殊,可能需要单独配置,本文不考虑这种情况

临时生效(当前终端会话)

  • 在终端中直接执行以下命令(根据你的代理类型和地址修改):
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # HTTP 代理
    export http_proxy="http://代理服务器IP:端口"
    export https_proxy="http://代理服务器IP:端口"

    # 如果代理需要认证
    export http_proxy="http://用户名:密码@代理服务器IP:端口"
    export https_proxy="http://用户名:密码@代理服务器IP:端口"

    # SOCKS5 代理
    export all_proxy="socks5://代理服务器IP:端口"

    # SOCKS5 代理(需认证)
    export all_proxy="socks5://用户名:密码@代理服务器IP:端口"

永久生效(对当前用户,常用)

  • 编辑用户目录下的 .bashrc 文件,在文件末尾添加上述代理设置命令:

    1
    vi ~/.bashrc
  • 使配置生效:

    1
    source ~/.bashrc

永久生效(对所有用户)

  • 如果需要让所有用户都使用代理,可以修改 /etc/profile 文件:

    1
    sudo vi /etc/profile
  • 添加代理设置后执行:

    1
    source /etc/profile

验证代理是否生效

  • 可以使用 curl 命令测试:

    1
    curl -I http://www.google.com
  • 如果返回 HTTP 状态码(如 200、301 等),说明代理配置成功


取消代理

  • 如果需要临时取消代理,可以执行:
    1
    2
    3
    unset http_proxy
    unset https_proxy
    unset all_proxy

Linux——进程相关操作


批量杀死进程

  • 杀死某个用户的所有进程
    1
    pkill -u jiahong

top查看进程信息

  • M: 根据驻留内存大小进行排序
  • P: 根据CPU使用百分比大小进行排序
  • f: 每列的参数说明

查看进程的堆栈

  • pstack
  • gstack

杀死特定进程

已知进程pid

  • 杀死进程

    1
    kill [pid]
  • 强制杀死进程

    1
    kill -9 [pid]

未知进程pid

  • 如果不知道进程pid可以在top命令里面找COMMAND列中相关的进程

  • 有时候通过top的信息不方便找到(比如想通过启动命令查找,比如想进程太多,找不过来)

    • 此时通过下面的命令查找

      1
      ps -aux | grep "command"
    • 更多ps -aux的解析可以参考博客https://www.cnblogs.com/dion-90/articles/9048627.html


htop查看进程

1
2
apt intall htop
htop
  • 比top更优秀的进程查看工具

Python——ArgumentParser类的使用


整体说明

  • 在 Python 里,argparse.ArgumentParser() 是标准库 argparse 模块的核心部分,其主要功能是解析命令行参数
  • 大部分优秀的开源函数都会使用这个功能

代码示例

  • ArgumentParser类使用示例
    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    import argparse

    def main():
    # 创建 ArgumentParser 对象
    parser = argparse.ArgumentParser(
    description='这是一个命令行工具演示程序',
    epilog='示例: python demo.py -n Alice -a 35 --verbose'
    )

    # 添加参数
    # 位置参数 (未添加-为前缀的是位置参数,位置参数是必须给出的)
    parser.add_argument('input_file', help='输入文件路径')

    # 可选参数(添加-或--的是可选参数),同一行可以同时注册-或--,都可以作为输入参数
    # # 但代码内部名字命名规则是--优先-,没有--时,代码内部-才会生效(比如下面的定义下,parser.output 和 parser.x 生效,但是 parser.o 会报错)
    parser.add_argument('-o', '--output', default='output/result.txt', help='输出文件路径') # 调用时使用args.output调用参数
    parser.add_argument('-x', help='x') # 调用时使用args.x调用参数
    parser.add_argument('-n', '--name', default='Guest', help='用户名称') # 调用时使用args.x调用参数
    parser.add_argument('--age', type=int, choices=range(30, 40), help='用户年龄(30-39)')
    # action='store_true'表示这是布尔变量,若传入命令行存在该参数,则该 Python 参数值为 true,否则为 false;'store_false' 则功能相反
    parser.add_argument('--verbose', action='store_true', help='显示详细输出')
    parser.add_argument('--color', choices=['red', 'green', 'blue'], default='blue', help='颜色选择')
    parser.add_argument('--scale', type=float, default=*0, help='缩放比例')

    # 互斥参数组,同时指定会出错
    group = parser.add_mutually_exclusive_group()
    group.add_argument('--fast', action='store_true', help='快速模式')
    group.add_argument('--slow', action='store_true', help='慢速模式')

    # * 解析参数
    args = parser.parse_args()

    print("args对象完整属性:", args.__dict__)
    print("--end--\n")
    # * 使用参数
    print(f"输入文件: {args.input_file}")
    if args.output:
    print(f"输出文件: {args.output}")
    print(f"用户名: {args.name}")
    if args.age:
    print(f"年龄: {args.age}")
    print(f"详细模式: {'是' if args.verbose else '否'}")
    print(f"颜色: {args.color}")
    print(f"缩放比例: {args.scale}")
    if args.fast:
    print("模式: 快速")
    elif args.slow:
    print("模式: 慢速")
    else:
    print("模式: 默认")


    if __name__ == '__main__':
    main()

    # args对象完整属性: {'input_file': 'text.txt', 'output': 'output/result.txt', 'x': None, 'name': 'Guest', 'age': 33, 'verbose': False, 'color': 'blue', 'scale': *0, 'fast': False, 'slow': False}
    # --end--
    #
    # 输入文件: text.txt
    # 输出文件: output/result.txt
    # 用户名: Guest
    # 年龄: 33
    # 详细模式: 否
    # 颜色: blue
    # 缩放比例: *0
    # 模式: 默认

Python 内部变量参数命名规则

  • - 和 -- 同时存在时,优先 -- 定义的变量
    • 注:传入时都可以使用,且没有优先级,只会用后面的覆盖前面的
  • --output-path 等会自动被转换成 parser.output_path 变量访问
    • 注:传入时还是必须跟参数定义方式对齐 --output-path
    • 当然:--output_path 也是相同的参数名 parser.output_path ,若同时定义了 --output_path 和 --output-path,则两者实际上是同一个参数,且互相之间可以被覆盖

ArgumentParser 类其他使用注意事项

  • 参数类型 :
    • 默认情况下参数是字符串类型,可以使用 type 指定其他类型
    • 常用类型:int, float, str (默认)
  • 参数种类 :
    • 位置参数:没有前缀,必须提供
    • 可选参数:以 - 或 -- 开头,可选提供
    • 注:位置参数是必须的,可选参数可通过增加 required=True 来设定为必须参数
  • 常用参数选项 :
    • help:参数的帮助信息
    • default:参数的默认值
    • choices:限制参数的取值范围
    • action:参数的动作,常见值:
      • store:存储参数值(默认)
      • store_true/store_false:存储布尔值
      • append:允许多次使用参数并存储为列表
  • 互斥参数 :
    • 使用 add_mutually_exclusive_group() 创建互斥组
    • 组内的参数不能同时使用
  • 帮助信息 :
    • description:程序的简要描述
    • epilog:帮助信息末尾的文本
    • 自动生成的帮助信息可以通过 -h 或 --help 查看
  • 错误处理 :
    • 当用户输入无效参数时,argparse 会自动生成错误信息并退出,会抛出 ArgumentError 或 SystemExit 异常
  • 子命令 :
    • 对于复杂的命令行工具,可以使用 add_subparsers() 实现子命令功能
    • 类似 git 的 commit, push 等子命令
  • 参数前缀 :
    • 通常单字母参数用 - 前缀,完整单词用 -- 前缀
    • 但这不是强制要求,只是约定俗成

Python——signal.signal函数处理OS信号


整体说明

  • signal.signal() 是 Python 中用于设置信号处理方式的核心函数
  • signal.signal()主要用于捕获和处理操作系统发送的各种信号(如中断信号、子进程状态变化信号等)

signal.signal 函数说明

  • 基本语法如下:

    1
    2
    3
    import signal

    signal.signal(signalnum, handler)
  • 参数说明:

    • signalnum:需要处理的信号类型(如 signal.SIGINT 表示键盘中断,signal.SIGCHLD 表示子进程状态变化等)
    • handler:信号处理函数(或特殊常量),用于定义收到信号后的行为

信号类型(signalnum)

  • 常见的信号常量包括:
    • signal.SIGINT:程序终止(Interrupt)信号,通常由 Ctrl+C 触发
    • signal.SIGTERM:终止请求,默认可以被捕获和处理
    • signal.SIGCHLD:子进程状态改变(终止、暂停等)时触发
    • signal.SIGKILL:强制终止信号(无法被捕获或忽略)
    • signal.SIGSTOP:暂停信号(无法被捕获或忽略)
  • 完整信号列表可通过 signal.__dict__ 查看
    • 也可以参考 Python 官方文档: signal — Set handlers for asynchronous events

处理函数(handler)

  • handler 可以是以下三种类型之一:

  • 自定义函数类型:

    • 函数需接收两个参数:signum(信号编号)和 frame(当前栈帧对象,可选)
    • 使用示例:
      1
      2
      3
      4
      5
      6
      def handle_sigint(signum, frame):
      print(f"\n收到信号 {signum},程序即将退出")
      exit(0)

      # 注册 SIGINT 信号的处理函数
      signal.signal(signal.SIGINT, handle_sigint)
  • 使用默认处理方式 ,即取值 signal.SIG_DFL

    • 此时表示使用默认处理方式(系统预设行为,如 SIGINT 默认终止程序)
    • 使用示例:
      1
      2
      # 恢复 SIGINT 的默认处理(取消自定义函数)
      signal.signal(signal.SIGINT, signal.SIG_DFL)
  • 使用忽略该信号处理方式 ,即取值 signal.SIG_IGN

    • 表示忽略该信号(不做任何处理)
    • 使用示例:
      1
      2
      # 忽略 SIGINT 信号(Ctrl+C 无效)
      signal.signal(signal.SIGINT, signal.SIG_IGN)

使用注意事项

  • 信号处理函数应尽量简单,避免包含复杂逻辑(如 I/O 操作、长时间阻塞等),否则可能导致程序不稳定
  • 部分信号(如 SIGKILL、SIGSTOP)无法被捕获或忽略,用于强制终止/暂停程序
  • 信号处理函数通常在主线程中执行,多线程程序中需谨慎处理信号,避免线程安全问题
  • 部分信号(如 SIGCHLD)在 Windows 系统中可能不支持,使用时需注意平台兼容性

Pyhton——有限迭代器转无限迭代器


整体说明

  • 本文记录一个非常有用的特别函数,可用于将有限的迭代器包装变成无限的迭代器(不停重复)

Python 生成器回顾

  • 斐波那契数列生成器定义和使用示例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # 以后调用这个函数不能再简单的理解为函数调用,要理解为创建生成器
    def fibonacci_generator(n):
    a, b = 0, 1
    count = 0
    while count < n:
    yield a # 返回当前值,并暂停函数执行
    a, b = b, a + b
    count += 1

    # 使用生成器
    fib_gen = fibonacci_generator(10) # 创建生成器对象
    for num in fib_gen: # for 循环访问 fib_gen即可,不需要再访问原始函数,原始函数调用一次足以
    print(num, end=" ")
    print("\n")

    # 0 1 1 2 3 5 8 13 21 34

代码外简单解释

  • 下面的程序定义了一个函数 infinite_iterator,可以对任意有限迭代器(如列表)无限次循环遍历
  • 每遍历一轮,先输出 “this”,再依次输出迭代器的所有元素
  • 整个过程是无限循环,除非手动终止
  • 代码示例:
    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
    from itertools import repeat

    def infinite_iterator(finite_iterator):
    """
    实现对有限迭代器的无限循环遍历
    每次循环开始时,先打印 "this",然后依次输出迭代器的所有元素

    参数:
    finite_iterator: 任意可迭代对象(如列表、元组等)

    实现原理:
    1. 使用 itertools.repeat(finite_iterator) 实现对同一个迭代器对象的无限重复
    2. 外层 for 循环每次进入时,先打印 "this"
    3. 使用 yield from finite_iterator,将 finite_iterator 的所有元素依次生成,finite_iterator 被访问完以后,才会进入下一个 yield(即下个 for 迭代)
    4. 这样,每次完整遍历 finite_iterator 后,又会重新开始新一轮遍历,整个过程无限循环
    注意:
    如果 finite_iterator 是可迭代但不可重复遍历的(如生成器),第二轮开始时将不再有元素
    """
    for _ in repeat(finite_iterator): # 无限循环
    print("this") # 每轮遍历前打印
    yield from finite_iterator # 依次输出所有元素

    # 创建生成器,循环遍历 [1, 2, 4]
    iter_x = infinite_iterator([1, 2, 4])

    # 无限输出 "this, 1, 2, 4, this, 1, 2, 4, this, ...",直到手动终止
    for i in iter_x:
    print(i)

预估——CTR预估中的样本采样

  • 参考链接:
    • 参考文献:ctr 校准的方式
    • 论文:《Practical Lessons from Predicting Clicks on Ads at Facebook》

CTR 预估的样本采样

  • CTR 预估任务中,正负样本可能偏差很多,此时需要做样本采样,以提升训练速度和效果
    • “负采样可以提升训练速度和模型效果”来自论文《Practical Lessons from Predicting Clicks on Ads at Facebook》

CTR 预估样本采样后的校准

  • 方法一
    • 参见ctr 校准的方式中的推导
  • 方法二【常用方式】
    • 假设负采样比例为 \(w\),原始预估值为 \(p\),则校准后的预估值 \(q\) 为:
      $$
      \begin{align}
      q = \frac{p}{p+(1-p)/w}
      \end{align}
      $$
    • 具体实现如下:
      1
      2
      3
      logits = ctr_mlp_layer(input)
      pctr = tf.nn.sigmoid(logits)
      final_pctr = pctr / (pctr + (1 - pctr) / negative_downsampling_rate)

Linux——在root用户下也无法删除文件

本文介绍Linux中即使是root用户,某些特殊文件也无法删除的问题

  • 相关指令:
    • chattr
    • lsattr

问题来源

  • chattr命令给予用户权限去修改文件属性已提高系统的安全性
    • 注意chattr命令不能保护/, /dev, tmp, var目录(本身)
  • 其中一个属性i可以使得文件无法被删除,重命名,设置链接,同时不能修改内容等
    • 添加i属性指令: chattr +i [filename]
    • 移除i属性指令: chattr -i [filename]
  • 问题特征表现为,在root用户权限下,某些文件无法删除,报错为:

    rm: cannot remove ‘[filename]’: Operation not permitted


解决方案

  • 查看文件属性

    1
    lsattr [filename]
    • 此时文件属性中会多一个i属性
  • 删除文件i属性

    1
    chattr -i [filename]
    • 文件i属性删除后可以正常修改或者删除文件了

相关说明

  • 参考博客链接为: http://www.ha97.com/5172.html

    + :在原有参数设定基础上,追加参数
    - :在原有参数设定基础上,移除参数
    = :更新为指定参数设定
    A:文件或目录的 atime (access time)不可被修改(modified), 可以有效预防例如手提电脑磁盘I/O错误的发生
    S:硬盘I/O同步选项,功能类似sync
    a:即append,设定该参数后,只能向文件中添加数据,而不能删除,多用于服务器日志文件安全,只有root才能设定这个属性
    c:即compresse,设定文件是否经压缩后再存储。读取时需要经过自动解压操作
    d:即no dump,设定文件不能成为dump程序的备份目标
    i:设定文件不能被删除、改名、设定链接关系,同时不能写入或新增内容。i参数对于文件 系统的安全设置有很大帮助
    j:即journal,设定此参数使得当通过mount参数:data=ordered 或者 data=writeback 挂 载的文件系统,文件在写入时会先被记录(在journal中)。如果filesystem被设定参数为 data=journal,则该参数自动失效
    s:保密性地删除文件或目录,即硬盘空间被全部收回
    u:与s相反,当设定为u时,数据内容其实还存在磁盘中,可以用于undeletion
    各参数选项中常用到的是a和i。a选项强制只可添加不可删除,多用于日志系统的安全设定。而i是更为严格的安全设定,只有superuser (root) 或具有CAP_LINUX_IMMUTABLE处理能力(标识)的进程能够施加该选项


评论补充说明

  • 参考地址: http://www.ha97.com/5172.html 的评论部分

    i: 将无法对文件进行修改,若对目录设置后则仅能修改子文件而不能新建或删除
    a: 仅允许补充(追加)内容.无法覆盖/删除(Append Only)
    S: 文件内容变更后立即同步到硬盘(sync)
    s: 彻底从硬盘中删除,不可恢复(用0填充原文件所在硬盘区域)
    A: 不再修改这个文件的最后访问时间(atime)
    b: 不再修改文件或目录的存取时间
    D: 检查压缩文件中的错误
    d: 当使用dump命令备份时忽略文件/目录
    c: 默认将文件或目录进行压缩
    u: 当删除此文件后依然保留其在硬盘中的数据,方便日后恢复
    t: 让文件系统支持尾部合并(tail-merging)
    X: 可以直接访问压缩文件的内容。

ML——各种数据分析图介绍.md

[日常编辑]
Python数据分析时可能用到各种各样的图,本文将简单介绍数据分析中常用的几种基本图


直方图(Hist-plot)


柱形图(Dist-plot)

seaborn.distplot

  • 集合了matplotlib的hist()与核函数估计kdeplot的功能

核密度估计图(KDE-plot)

seaborn.kdeplot


箱式图(Box-plot)

  • 箱式图,是指—种描述数据分布的统计图
  • 是表述最小值、第一四分位数、中位数、第三四分位数与最大值的一种图形方法
  • 可以粗略地看出数据是否具有对称性,分布的分散程度等信息

异常值

又称离群值(Outlier), 指不在区间[Q1-1.5IQR, Q3+1.5IQR]中的值

  • Q1为25%中位数,也称为下四分位数
  • Q3为75%中位数,也称为上四分位数
  • IQR为Q3-Q1,四分数间距

绘图方法

去除离群值之后的部分计入图中,分别标记五个特征值

  • 特征值 最小值,Q1,中位数,Q3,最大值
  • 将五个数值描绘在一个图上,五个特征值在一个直线上
  • 最小值和Q1连接起来,Q1、中位数、Q3分别作平行等长线段
  • 连接两个四分位数构成箱子
  • 连接两个极值点与箱子,形成箱式图
  • 最后点上离群值

实例

  • 箱式图示例:

小提琴图(Violin-plot)

  • 用于显示数据分布及其概率密度
  • 竖向显示类似于箱式图,横向表征密度分布,越宽的地方密度分布越高

ML——课程学习


整体说明

  • 在机器学习领域,课程学习(Curriculum Learning,CL) 训练策略,适用场景广泛,包括监督学习,强化学习等场景
  • 课程学习的核心思想是让模型从简单任务逐步过渡到复杂任务,如同人类在学习新知识时先掌握基础概念,再逐渐挑战更难的内容
  • 思路 :人类学习遵循“从易到难”的顺序,课程学习希望通过模拟这一过程,提升机器学习模型的学习效率和泛化能力
  • 定义 :通过设计一个“课程”,即按照任务难度排序的训练数据序列,让模型先在简单任务上学习,再逐步增加任务复杂度,最终掌握目标任务
  • 优点:
    • 从简单任务入手可帮助模型更快收敛,减少训练时间(如CV中先学识别简单物体边缘,再学完整物体)
    • 逐步积累的知识体系让模型更适应复杂场景,减少过拟合(如语音识别中先学干净语音,再学带噪声语音)
    • 复杂任务直接训练可能陷入局部最优,课程学习通过分阶段优化降低难度(如神经网络训练中的逐层预训练)
  • 它不仅适用于传统监督学习,还在强化学习、多任务学习等领域展现出潜力。随着算法对“任务难度”理解的深化,未来课程学习可能成为解决复杂AI任务的关键策略之一

课程学习中的核心概念

  • 任务难度定义 :衡量任务的“难易程度”,常通过数据的特征复杂度、样本数量和模型在任务上的预测准确率等来评估任务难度
  • 课程设计策略 :人工划分或自动划分
    • NLP 中先学短文本分类,再学长文本(人工划分)
    • 基于数据相似度聚类,先训练简单簇,再逐步引入复杂簇(自动划分)
    • 根据模型当前表现,动态选择下一个合适的任务(自动划分)
  • 训练过程 :模型在每阶段完成后,保留已学知识,并将新知识与旧知识结合,避免“灾难性遗忘”

典型示例

  • CV-图像分类:先学识别猫狗等简单动物,再学区分稀有物种
  • CV-目标检测:先学大尺寸物体检测,再学小尺寸物体检测
  • NLP-机器翻译:先学短句翻译,再学复杂长句翻译
  • NLP-问答系统:先回答事实性问题,再处理推理类问题
  • RL-游戏AI:如 AlphaGo 先学基础落子规则,再学复杂策略
  • RL-机器人控制:先学基础动作(如行走),再学复杂任务(如避障)
  • 推荐系统:先学基础用户偏好,再学个性化长尾推荐

一些相关名词辨析

  • 课程学习
    • 主动按难度排序任务,强调“从易到难”的顺序性,适用于复杂任务分步训练
  • 迁移学习
    • 从源任务迁移知识到目标任务,重点在知识迁移而非任务排序,主要强调跨领域知识复用
  • 元学习
    • 强调学习“如何学习”,关注快速适应新任务的能力,着重在少样本学习场景中使用
  • 增量学习
    • 逐步添加新数据,防止遗忘旧知识,重点在记忆保留,主要在动态数据场景

Python——如何优雅的导入自定义的Python包


对于IDEA的管理

  • 在IDEA中运行文件时,当前项目根目录会默认被添加为Python的搜索路径
  • 根目录下的文件可以直接被访问
  • 根目录的子目录需要每一层都添加__init__.py文件,将其编译为包

IDEA项目用命令行运行

  • 在运行的第一个文件中添加IDEA项目的根目录作为搜索路径

    • 这里的根目录最好是绝对路径
      1
      2
      import sys
      sys.path.append("/home/xxx/xxx/xxx")
  • 如果是想使用相对路径,从而方便移植也行,但需要获取当前文件的文件路径,然后从当前文件与根目录的关系解析出根目录

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import os
    thisFileDir = os.path.split(os.path.realpath(__file__))[0]
    # we have to modify the tail if we change the path of this python file
    tail = 6
    rootPath = thisFileDir[0:-tail]
    if rootPath[-1] != "/" and rootPath[-1] != "\\":
    message = "Error root path [%s]\n\tPlease check whether you changed the path of current file" % rootPath
    raise Exception(message)
    print "Current root path: %s" % rootPath

    import sys
    sys.path.append(rootPath)
  • 其他的和在IDEA中运行一样,需要添加的库加上__init__.py即可

1…262728…63
Joe Zhou

Joe Zhou

Stay Hungry. Stay Foolish.

630 posts
53 tags
GitHub E-Mail
© 2026 Joe Zhou
Powered by Hexo
|
Theme — NexT.Gemini v5.1.4