Jiahong 的个人博客

凡事预则立,不预则废


  • Home

  • Tags

  • Archives

  • Navigation

  • Search

Linux——Ubuntu和Centos服务器管理


Centos

配置静态IP

  • 查看网卡名称

    1
    ifconfig
    • 查看网卡信息,每行的第一项为网卡名称
    • 一般服务器可能有多个网卡,按照需求选择一个即可
    • 网卡信息包含当前网卡的ipv4和ipv6地址,MAC地址等信息
  • 根据网卡名字打开相应网卡的配置文件

    1
    2
    # 假设网卡名称为eth0
    vi /etc/sysconfig/network-scripts/ifcfg-eth0
  • 修改相关配置内容

    1
    2
    3
    4
    5
    6
    7
    IPADDR=12.12.12.12
    NETMASK=255.255.255.0
    GATEWAY=12.12.12.1
    ONBOOT=yes
    BOOTPROTO=static
    DNS1=114.114.114.114
    DNS2=8.8.8.8
    • 等号后面是具体的ip地址名称
    • DNS可以有多个,用数字标识即可
  • 重新启动网络服务

    1
    service network restart

管理用户

修改root密码

默认可远程登录root用户,只需知道密码即可(SSH默认已经安装)

  • 修改root密码

    1
    passwd
  • 若需要找回root密码,参考博客 https://blog.csdn.net/shanvlang/article/details/80385913

添加用户

假设添加用户名为test的用户

  • 添加新用户

    1
    useradd test
    • centos中,以上命令将自动为test用户分配一个属于test用户的/home/test文件夹
  • 为新用户修改密码

    1
    passwd test
  • 添加用户权限

    • 打开配置文件

    • 如果root用户没有该文件的写权限的话需要用chmod u+w /etc/sudoers, 修改完成再改回到chmod u-w /etc/sudoers

      1
      vi /etc/sudoers
    • 编辑以下内容,注意空格类型,最好复制一行修改

      1
      2
      3
      ## Allow root to run any commands anywhere
      root ALL=(ALL) ALL
      test ALL=(ALL) ALL
  • 删除用户

    1
    userdel test

Ubuntu

配置静态IP

  • 查看网卡名称

    1
    ifconfig
    • 查看网卡信息,每行的第一项为网卡名称
    • 一般服务器可能有多个网卡,按照需求选择一个即可
    • 网卡信息包含当前网卡的ipv4和ipv6地址,MAC地址等信息
  • 修改配置文件

    1
    vi /etc/network/interfaces
  • 修改相关配置内容

    1
    2
    3
    4
    5
    6
    7
    8
    # 假设网卡名称为eth0

    auto eth0
    iface eth0 inet static
    address 12.12.12.12
    netmask 255.255.255.0
    gateway 12.12.12.1
    dns-nameserver 114.114.114.114 8.8.8.8
    • dns可以有多个,以空格间隔开
  • 重新启动网络服务

    1
    sudo /etc/init.d/networking restart

管理用户

修改root密码

Ubuntu默认禁用root用户登录,需要配置root账户才能以root身份登录(SSH默认已经安装)

  • 修改root密码

    1
    passwd
  • 若需要找回root密码,参考博客 https://blog.csdn.net/shanvlang/article/details/80385913

添加用户

假设添加用户名为test的用户

  • 添加新用户

    1
    useradd test
    • Ubuntu中以上命令并不会直接为当前用户分配自己的文件夹,所以需要我们为其手动添加一个并使用chown test /home/test命令将文件家分配给test用户,这样使用test用户登录时将会自动转到/home/test文件夹下面工作
  • 为新用户修改密码

    1
    passwd test
  • 添加用户权限

    • 打开配置文件

    • 如果root用户没有该文件的写权限的话需要用chmod u+w /etc/sudoers, 修改完成再改回到chmod u-w /etc/sudoers

      1
      vi /etc/sudoers
    • 编辑以下内容,注意空格类型,最好复制一行修改

      1
      2
      3
      # User privilege specification
      root ALL=(ALL:ALL) ALL
      test ALL=(ALL:ALL) ALL
  • 删除用户

    1
    userdel test

Linux——Ubuntu和Centos服务器管理


Terminal无法访问外网

  • 问题现象 : 当在Linux上安装Clash后,浏览器可以访问而终端(Terminal)不行

  • 问题原因 :Clash设置的代理环境变量未正确配置到终端中,导致终端无法使用代理

  • 解决方法 :手动配置终端的代理环境变量。假设Clash监听的端口是7890,可以在终端中输入以下命令设置HTTP和HTTPS代理:

    1
    2
    export http_proxy=http://127.0.0.1:7890
    export https_proxy=http://127.0.0.1:7890
    • 如果使用的是Zsh shell,需要将上述命令添加到~/.zshrc文件中;
    • 如果是Bash shell,则添加到~/.bashrc文件中,然后执行source ~/.zshrc或source ~/.bashrc使配置生效

Git——GitHub开源协议


整体说明

  • GitHub上有许多开源协议,本文总结常见的开源协议及其含义

MIT License

  • 极宽松,允许自由使用、修改和分发,只需保留版权声明。无担保,作者不承担责任
  • 适用场景:适合个人项目或希望代码广泛传播的场景
  • 个人开发者常使用的协议

Apache License 2.0

  • 允许商业使用、修改和分发,需保留版权和许可证
  • 特殊条款 :专利授权,明示禁止商标使用
  • 适用场景:企业项目,需明确专利授权
  • 目前的大模型大多使用的这个协议

GNU GPL v3

  • 强Copyleft,修改和分发需开源且保持相同许可证。衍生作品必须开源,商业分发需提供源代码
  • 适用场景:确保代码及其衍生版本永远开源

GNU LGPL v3

  • 弱Copyleft,允许闭源软件通过库引用方式使用。修改LGPL库本身需开源
  • 适用场景:开发开源库,允许闭源应用调用

BSD 2-Clause “Simplified” License

  • 允许自由使用和修改,禁止用作者名义推广。需保留版权声明
  • 适用场景:类似MIT,但限制稍多

BSD 3-Clause “New” License

  • 在2-Clause基础上增加禁止使用作者商标的条款
  • 适用场景:需明确商标保护的项目

Mozilla Public License 2.0 (MPL 2.0)

  • 部分Copyleft,修改文件需开源,未修改部分可闭源
  • 适用场景:适合混合开源/闭源的组件化项目

Creative Commons Licenses

  • CC0 :放弃版权,进入公有领域
  • BY :允许商用,但需署名
  • NC :禁止商业使用
  • 适用场景:非软件类作品(如文档、设计)

Unlicense

  • 放弃所有版权,代码进入公有领域
  • 适用场景:完全开放的公共项目

选择建议

  • 希望代码广泛传播: MIT/Apache
  • 确保衍生作品开源: GPL
  • 开发开源库: LGPL
  • 非软件作品: CC系列

Git——Git环境配置


安装 Git

  • 可以命令行安装,也可以从 Git 的官方网站(https://git-scm.com/downloads)下载安装程序,然后按照安装向导的提示完成安装
    1
    git --version

配置用户名和邮箱

  • Git 在提交代码时会使用这些信息来标识提交者

  • 执行以下命令来设置用户名和邮箱:

    1
    2
    git config --global user.name "你的用户名"
    git config --global user.email "你的邮箱地址"
  • 这里使用的--global参数表示这是全局配置,在这台计算机上进行的所有Git操作都会使用这些信息

  • 如果你想为某个特定的项目设置不同的用户名和邮箱,可以在该项目的根目录下执行相同的命令 ,但不使用--global参数


查看配置信息

  • 可以通过以下命令来查看当前的 Git 配置信息:

    1
    git config --list
  • 执行该命令后,终端会列出所有的Git配置项,你可以从中找到user.name和user.email,确认它们是否是你刚刚设置的内容


SSH 配置

  • 查看 SSH 秘钥

    1
    ls -al ~/.ssh
    • 若存在,会看到类似 id_rsa.pub 或 id_ed25519.pub 的文件(.pub 为公钥,无后缀为私钥)
  • 若无秘钥,需先生成秘钥

    1
    ssh-keygen -t ed25519 -C "your_email@example.com"
    • -t ed25519:使用更安全的 Ed25519 算法(推荐使用)

附录:配置文件位置

  • Git 的配置信息存储在不同的文件中,具体取决于配置的范围:
    • 全局配置 :存储在用户主目录下的.gitconfig文件中
    • 项目配置 :存储在项目根目录下的.git/config文件中

Git——问题记录


Ubuntu 中文乱码问题

  • 解决方案
    1
    git config --global core.quotepath false

Windows 拉取项目后无法 checkout

  • 表现:拉取远程分支后无法进行 checkout 操作,具体错误表现为

    1
    fatal:unable to checkout working tree
  • 原因:一般是因为文件名命名包含非法字符导致,比如亲测文件名包含 | 就会出错(通常是有些不适用 Windows 且命名不规范的作者容易出现该错误)

  • 解决方案:修改文件名称,将非法字符去掉


文件权限导致记录更改

  • 现象:文件权限修改(如执行权限改为无执行权限)也会导致文件被默认为修改,此时文件内容没有任何修改
  • 具体细节:在使用 git diff 时看到的 old mode 100755 和 new mode 100644,核心是 Git 检测到文件的执行权限发生了变化,而非文件内容的修改
    • 755:代表文件拥有执行权限(所有者可读可写可执行,组和其他用户可读可执行),常见于脚本、可执行程序
    • 644:代表文件无执行权限(所有者可读可写,组和其他用户仅可读),是普通文论文件的默认权限
    • 注:权限位规则:755(可执行)= rwxr-xr-x,644(不可执行)= rw-r–r–
  • TLDR:有意修改则直接提交,误改可恢复权限,跨系统开发建议关闭 core.filemode 忽略权限检测

补充问题:为什么会出现这个差异?

  • 常见原因有 2 种:
    • 1)手动修改了权限:可能通过 chmod 命令(如 chmod 644 文件名)修改了文件权限
    • 2)系统/工具自动调整:不同操作系统(如 Windows 和 Linux)、Git 配置或编辑器可能自动调整权限

解法1:接受权限变更并提交(如果是有意修改)

  • 如果这个权限修改是刻意想要的,直接正常提交即可:
    1
    2
    3
    4
    5
    # 添加权限变更的文件到暂存区
    git add 你的文件名

    # 提交变更(备注说明权限修改)
    git commit -m "调整xxx文件权限:从100755改为100644,移除执行权限"

忽略权限变更(避免 Git 追踪权限)

  • 如果只是误操作,或不想让 Git 检测权限变化(比如跨系统开发时),可以配置 Git 忽略文件权限:

    1
    2
    3
    4
    5
    6
    7
    8
    # 临时忽略(仅当前仓库生效,关闭终端/切换仓库失效)
    git config core.filemode false

    # 永久忽略(当前仓库全局生效)
    git config --local core.filemode false

    # 全局忽略(所有Git仓库生效)
    git config --global core.filemode false
    • 配置后,Git 就不会再检测文件权限的变化,git diff 也不会再显示这类差异

恢复原有权限(撤销误改的权限)

  • 如果想把文件权限改回原来的(如 100755),执行:
    1
    2
    3
    4
    5
    # 恢复为可执行权限(755)
    chmod 755 你的文件名

    # 验证权限是否恢复
    ls -l 你的文件名 # 输出中权限列会显示 -rwxr-xr-x

Python——PyCharm使用笔记


PyCharm使用技巧记录

  • PyCharm IDE 卡顿,可考虑 Help->VM Options 增加虚拟机内存
  • PyCharm IDE 显示连字形式,<= 仅显示一个 \(\le\),修改 File-> Settings -> Editor -> General -> Font 可以切换回来,亲测 Monaco 可以
  • PyCharm IDE 显示当前代码所在路径:View -> Appearance -> Navigation Bar
  • PyCharm IDE 显示当前文件结构:View -> Tool Windows -> Structure
  • PyCharm IDE 显示当前行所属类和函数: 在 Settings 全局搜索 Breadcrumbs 并打开
  • PyCharm IDE 识别指定子目录下的项目,比如第三方项目(./sub_module/my_project/)等,直接将该项目的文件夹设置为 Root Source

Python——Pylint库简单学习


Pylint 整体说明

  • Pylint 是面向 Python 的静态代码分析工具(linter),在不运行代码的前提下检查错误、执行编码规范、识别代码异味,并给出重构建议;
  • Pylint 可与 flake8(轻量快检)、mypy/pyright/pyre(类型检查)、bandit(安全检查)、black/isort(格式化)、autoflake/pyupgrade(清理/升级)等配合使用
  • 大部分 IDE 会自动集成该功能
  • Pylint 高度可配置,支持编写自定义插件,适配内部库或框架(如 pylint-django)

Pylint 能做什么

  • 语法/语义错误与未使用变量/导入
  • 命名、缩进、行长度等风格与 PEP 8 一致性
  • 复杂度与设计问题(长函数、深嵌套等)
  • 未显式类型时的节点值推断(基于 astroid),能识别别名导入带来的误用风险
  • 提供代码质量评分与报告,并支持生成包/类图(pyreverse)、查找重复代码(symilar)

Pylint 安装与使用

  • 安装:pip install pylint
  • 命令行:pylint your_module.py 或 pylint your_package/
  • 可集成到 VS Code、PyCharm、Emacs 等编辑器/IDE
  • 首次使用:先开 --errors-only,再按需启用样式/重构提示,逐步收紧规则

Python——Python3新特性f-string

Formatted string literals


f-string

说明

  • 格式化的字符串文字以“f”为前缀
  • 类似于str.format()接受的格式字符串
  • 它们包含由花括号包围的替换字段
  • 替换字段是表达式,在运行时进行评估,然后使用format()协议进行格式化

工作原理

  • 从字符串中提取的表达式在f字符串出现的上下文中计算
  • 这意味着表达式可以完全访问本地和全局变量
  • 可以使用任何有效的Python表达式,包括函数和方法调用

与之前的表达式对比

  • 之前

    1
    print("%s%s%s" % (a, b, c+d))
  • f-string

    1
    print(f'{a}{b}{c+d}')

Python——Pydantic库简单学习


整体说明

  • Pydantic 库可利用 Python 类型提示对数据进行验证、解析、转换以及管理,确保数据的完整性、规范性和一致性
  • Pydantic 库还方便数据在不同格式间的序列化与反序列化

安装

  • 使用以下命令安装 Pydantic:
    1
    pip install pydantic

基本使用

定义数据模型

  • 通过继承BaseModel来定义数据模型类,类中的字段使用类型注解来指定数据类型
    1
    2
    3
    4
    5
    6
    7
    from pydantic import BaseModel

    class User(BaseModel):
    id: int
    name: str
    age: int
    is_active: bool = True

数据验证和解析

  • 创建数据模型的实例时,Pydantic 会自动进行数据验证和解析
    • 如果数据符合模型定义,就可以正常创建实例;
    • 如果数据无效,会抛出ValidationError异常
  • 示例如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    data = {
    "id": 1,
    "name": "Alice",
    "age": 30
    }
    user = User(**data)
    print(user)

    invalid_data = {
    "id": "invalid", # id应该是int类型
    "age": "thirty" # age应该是int类型
    }
    try:
    user = User(**invalid_data)
    except ValidationError as e:
    print(e)

高级特性

  • 可选字段 :使用Optional类型来定义可选字段。例如:

    1
    2
    3
    4
    5
    6
    7
    from typing import Optional
    from pydantic import BaseModel

    class User(BaseModel):
    id: int
    name: str
    age: Optional[int]
  • 默认值 :可以在定义字段时直接设置默认值。例如:

    1
    2
    3
    4
    5
    6
    from pydantic import BaseModel

    class User(BaseModel):
    id: int
    name: str = "Jane Doe"
    age: int = 18
  • 允许多种数据类型 :通过类型提示允许字段接受多种数据类型。例如:

    1
    2
    3
    4
    5
    6
    from typing import Union
    from pydantic import BaseModel

    class User(BaseModel):
    id: Union[int, str]
    name: str
  • 枚举类型 :Pydantic支持枚举类型,用于限制字段的值只能是预定义的一组值之一。例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from enum import Enum
    from pydantic import BaseModel

    class Gender(str, Enum):
    MALE = "male"
    FEMALE = "female"

    class User(BaseModel):
    id: int
    name: str
    gender: Gender
  • 嵌套模型 :可以定义嵌套的模型来表示复杂的数据结构。例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from pydantic import BaseModel

    class Address(BaseModel):
    street: str
    city: str
    zip_code: str

    class User(BaseModel):
    id: int
    name: str
    address: Address
  • 自定义验证器 :使用validator装饰器可以在数据被解析后进行额外的验证。例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from pydantic import BaseModel, validator

    class User(BaseModel):
    age: int

    @validator('age')
    def check_age(cls, value):
    if value < 0:
    raise ValueError('Age must be a non - negative integer')
    return value

其他功能

  • 数据模型实例具有一些属性和方法,如dict()返回模型字段和值的字典,json()返回JSON字符串表示,copy()创建模型的副本等
  • 使用create_model方法可以动态创建模型(不常用):
    1
    2
    3
    from pydantic import create_model

    DynamicModel = create_model('DynamicModel', foo=(str, ...), bar=123)

Python——Python3相对Python2的异同点总结

Python 3 和 Python 2 存在许多显著差异,下面为你详细介绍主要的不同之处:


语法层面

  • 打印函数 :
    • Python 2 里,print 属于语句,使用时无需括号。例如:print "Hello, World!"
    • Python 3 中,print 变为函数,必须使用括号。例如:print("Hello, World!")
  • 除法运算 :
    • Python 2 中,整数相除结果为整数,小数部分会被截断。例如:3 / 2 结果是 1
    • Python 3 里,整数相除结果为浮点数。例如:3 / 2 结果是 1.5。若想得到整数结果,需使用 // 运算符,如 3 // 2 结果是 1
  • Unicode 编码 :
    • Python 2 对 Unicode 支持欠佳,字符串默认是 ASCII 编码,若要使用 Unicode 字符串,需在字符串前加 u,如 u"你好"
    • Python 3 中,字符串默认是 Unicode 编码,可直接处理多种语言文字,无需额外指定

异常处理

  • 异常捕获语法 :
    • Python 2 可使用 except Exception, e 来捕获异常
    • Python 3 要求使用 except Exception as e 这种语法

迭代器与生成器

  • range 函数 :
    • Python 2 有 range 和 xrange 两个函数。range 返回列表,xrange 返回迭代器对象
    • Python 3 里,range 函数等同于 Python 2 的 xrange,返回迭代器对象,节省内存
  • 字典方法 :
    • Python 2 中,dict.keys()、dict.values() 和 dict.items() 返回列表
    • Python 3 里,这些方法返回视图对象,是迭代器,并非列表

模块和库

  • 标准库变动 :
    • Python 3 中部分模块的名称和位置有所改变。例如,urllib 模块被拆分成多个子模块,像 urllib.request、urllib.parse 等
    • 一些 Python 2 的库在 Python 3 中需要重新安装或更新以确保兼容

其他Python3特性

  • Python3还提供了比如 f-string 等新特性(允许使用print(f'{a}{b}{c+d}')这种代码来组织字符串)

示例代码对比

  • Python 2 代码示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # 打印语句
    print "Hello, Python 2!"

    # 除法运算
    result = 3 / 2
    print result

    # 异常处理
    try:
    num = 1 / 0
    except ZeroDivisionError, e:
    print "Error:", e

    # range 函数
    for i in range(5):
    print i

    # 字典方法
    my_dict = {'a': 1, 'b': 2}
    print my_dict.keys()
  • Python 3 代码示例 :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # 打印函数
    print("Hello, Python 3!")

    # 除法运算
    result = 3 / 2
    print(result)

    # 异常处理
    try:
    num = 1 / 0
    except ZeroDivisionError as e:
    print("Error:", e)

    # range 函数
    for i in range(5):
    print(i)

    # 字典方法
    my_dict = {'a': 1, 'b': 2}
    print(my_dict.keys())
    • 在捕捉多个异常时可以使用
      1
      except (ZeroDivisionError, ABCError) as e:

附录:Python 3 可以指定参数类型

  • Python 3 可以指定参数类型(Python2不可以),不过这属于类型提示(Type Hints),它只是一种提示,并不会在运行时强制检查参数类型
  • 虽然类型提示不会在运行时进行强制检查,但它能提升代码的可读性和可维护性,同时还能让 IDE 提供更精准的代码提示和错误检查。若要在运行时进行类型检查,可以使用第三方库,例如 pydantic
  • 下面从不同方面介绍 Python 3 中指定参数类型的方式

函数参数类型提示

  • 在定义函数时,可以为参数和返回值指定类型,示例如下:

    1
    2
    def add_numbers(a: int, b: int) -> int:
    return a + b
    • 在上述代码里,a: int 和 b: int 表明 a 和 b 应当是整数类型,-> int 表示该函数返回值为整数类型

类属性类型提示

  • 在类中,也能够为属性指定类型,示例如下:

    1
    2
    3
    4
    5
    6
    7
    class Person:
    name: str
    age: int

    def __init__(self, name: str, age: int):
    self.name = name
    self.age = age
    • 在这个示例中,name: str 和 age: int 分别指定了 Person 类的 name 和 age 属性的类型

复杂类型提示

  • Python 还提供了 typing 模块,借助该模块可以进行更复杂的类型提示,例如列表、字典等。示例如下:

    1
    2
    3
    4
    5
    6
    7
    from typing import List, Dict

    def process_list(numbers: List[int]) -> int:
    return sum(numbers)

    def process_dict(data: Dict[str, int]) -> int:
    return sum(data.values())
    • 在上述代码中,List[int] 表示列表中的元素应当是整数类型,Dict[str, int] 表示字典的键为字符串类型,值为整数类型

可选类型和联合类型

  • 使用 typing 模块的 Optional 和 Union 可以表示可选类型和联合类型。示例如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    from typing import Optional, Union

    def get_length(s: Optional[str]) -> int:
    if s is None:
    return 0
    return len(s)
    print(get_length("Alice")) # OK
    print(get_length(None)) # OK
    print(get_length([1,2,3])) # 运行正常,但编译器会有提示

    def convert_to_number(value: Union[int, str]) -> int:
    if isinstance(value, str):
    return int(value)
    return value
    print(convert_to_number("112")) # OK
    print(convert_to_number(112)) # OK
    print(convert_to_number(112.0)) # 运行正常,但编译器会有提示

    # 5
    # 0
    # 3
    # 112
    # 112
    # 112.0
    • 在 get_length 函数里,Optional[str] 意味着参数 s 可以是字符串类型,也可以是 None
    • 在 convert_to_number 函数中,Union[int, str] 表示参数 value 可以是整数类型或者字符串类型
1…464748…66
Joe Zhou

Joe Zhou

Stay Hungry. Stay Foolish.

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