LaTeX Tikz 绘图积累
Tikz 绘图的内容非常复杂,目前没有精力去仔细学习,只是简单记录一些可能用到的例子。 Tikz 相关教程例如:TikZBolg。 有一些在线绘图工具可以可视化绘制简单图形,并导出 Tikz 代码,例如:Mathcha。 对于更复杂的需求,可以使用专业的矢量图绘制软件(例如 Inkscape) 绘制并导出 Tikz 代码。 函数图像 1234567891011121314151617181920\documentclass[border=2mm]{standalone}\usepackage{amsmath,amssymb,amsfonts,amsthm}\usepackage[dvipsnames]{xcolor}\usepackage{tikz}\begin{document}\begin{tikzpicture} \draw[->] (-0.5, 0) -- (6, 0) node[above] {$x$}; \dr...
基于 SVD 实现图片压缩
图像本质上就是一个或多个矩阵,并且通常具有低秩结构,可以利用SVD分解舍弃低奇异值的部分来实现图片的压缩存储。 简单的 Python 示例实现如下 1234567891011121314151617181920212223242526import numpy as npimport matplotlib.pyplot as pltfrom PIL import Imagedef compress_img_first_k(img_array, k): if img_array.ndim == 2: img_array = img_array[:, :, np.newaxis] m, n, c = img_array.shape compressed_channels = [] for i in range(c): channel = img_array[:, :, i] U, S, VT = np.linalg.svd(channel, full_matrices=False) channel_k =...
Python 单元测试 unittest / pytest
整理一下 Python 单元测试的内容,包括: 内置的单元测试模块 unittest 第三方测试工具 pytest 除此之外,其实还有直接解析源码注释,获取测试用例的内置模块 doctest。 准备 为了便于描述,下面准备两个函数和一个类作为测试目标,构成 my_module.py my_module.py1234567891011121314151617181920def my_add(a, b): return a + bdef my_divide(a, b): return a / bclass MyDict(dict): def __init__(self, **kw): super().__init__(**kw) def __getattr__(self, key): try: return self[key] except KeyError: raise AttributeError(r"'MyDict' object ha...
DLL 注入攻击
概念介绍 DLL 注入攻击(DLL Injection)是一种将动态链接库(DLL)强制加载到目标进程中的技术,使得攻击者编写的代码能在目标进程的地址空间中运行。 在 Windows 中,DLL 注入是系统提供的合法功能,主要用于调试器和辅助工具,但也可以被用于攻击,不过这种攻击手段是非常明显且初等的,一般的防护软件都会阻止这种行为。 简易实现 可以使用最经典的 CreateRemoteThread + LoadLibraryA 方法实现 DLL 注入攻击,下面是主要的代码思路。 代码参考:idea4good/AbuCoding Loader 目标是让目标进程(这里以记事本Notepad.exe为例)加载提供的 DLL,实现步骤: 查找并获取目标进程句柄:使用 CreateToolhelp32Snapshot 遍历系统进程列表;调用 OpenProcess(PROCESS_ALL_ACCESS, ...) 在目标进程分配内存并写入 DLL 路径:VirtualAllocEx 为 DLL 路径字符串留空间;WriteProcessMemory 将 DLL 路径写到目标进程 获取 ...
Python 日志库 logging
Python 标准库中的 logging 模块提供了功能完备、可高度自定义的日志记录方案,适用于从简单脚本到复杂应用程序的各种场景。 许多 C/C++ 项目都依赖自行实现的简单日志库或成熟的第三方日志库(如 spdlog、log4cpp 等),与之不同的是,Python 内置的 logging 模块已经可以满足绝大多数开发需求,各种语言的日志库使用逻辑具有很多共性。 基本使用 先讨论在简单脚本文件中的日志使用,不涉及 logger 以及复杂的日志配置逻辑。 极简示例 导入日志库之后,无需任何配置就可以直接使用 1234567import logginglogging.debug("This is a debug message.")logging.info("This is an info message.")logging.warning("This is a warning message.")logging.error("This is an error message.")logging....
Vim 学习笔记
vim 被称为编辑器之神,学习难度很大,但是熟练掌握后可以更高效地敲代码,因此有必要学一下,但是没必要鼓捣各种插件。 主要参考:【Vim】可能是B站最系统的Vim教程 vim 介绍与版本 vim 是古董编辑器 vi 的升级版,在现代的 Linux 发行版中通常自带 vim,无需手动安装,虽然版本通常不是最新的,但是也足够使用。在很多发行版中都将 vi 命令链接到 vim 命令,因此 vi 命令和 vim 命令通常是等价的,都是在调用 vim 编辑器。 在 vim 中输入 :version 可以查看版本信息,例如 123VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Nov 22 2021 19:31:05)Included patches: 1-3582Compiled by <https://www.msys2.org/> vim 的各种功能模块化,在编译安装时可以选择精简其中一部分功能,至少有几种安装模式:tiny, small, normal, big, huge,显然 huge 版本的功能最完整。 在 :version...
K-means 算法
K-means 算法是一种经典的无监督学习算法,用于将数据自动分为 \(k\) 个簇,这里的 \(k\) 需要提前给定。 K-means 算法假设簇是凸的、大小相近,此时处理效果最好,但是并不能处理复杂形状的簇(如半月形),对维度高的稀疏数据(如文本)不太适用。 算法步骤 设数据集为 \(X = \{x_1, x_2, \dots, x_n\}\),\(x_i \in \mathbb{R}^d\),希望聚为 \(k\) 类,算法流程如下: 初始化:随机选择 \(k\) 个数据点作为初始的簇中心。 分配:将每个数据点分配到最近的簇中心,以形成 \(k\) 个簇。设当前中心为 \(\mu_1, \dots, \mu_k\),对于样本 \(x_i\),所属的簇为 \[ x_i \in C_s \,\, \text{where} \,\, s = \arg\min_{j=1,\dots,k} \| x_i - \mu_j \|^2 \] 更新:重新计算每个簇的中心,记 \(C_s\) 是第 \(s\) 个簇内的数据点集合,那么中心 \(\mu_s\) 为 \[ \mu_s = \fra...
Julia 学习笔记——8. 模块与包
TODO 项目管理 Julia 的项目下面有两个文件 Project.toml 项目配置文件 Manifest.toml 项目依赖包列表 作用大致相当于 package.json 和 package-lock.json,通常不需要手动修改。 Julia 调用 Python 在 Julia 的实际使用中,如何调用其它语言尤其是 Python 是一个重要的需求,目前有两种做法: PyCall.jl,搭配 Conda.jl 使用 PythonCall.jl,搭配 CondaPkg.jl 使用 前者是早期或者说是主流的做法,后者则是一种新方案。
Julia 学习笔记——7. 多维数组
概述 TODO 创建数组 数组字面量 特殊数组 向量化函数的点语法 TODO
Julia 学习笔记——6. 函数进阶
函数的参数类型 Julia 允许给函数的(一部分或全部)参数加上类型约束,例如 123function add2(x::Int64, y::Int64) return x + yend 正常使用例如 12add2(1, 3) # 4add2(Int64(1), Int64(10)) # 11 注意 Julia 不会对参数进行自动的类型转换,即使转换是安全无损的,例如 1add2(Int32(1), Int32(2)) # error 使用过于具体的参数类型约束通常不是合适的选择,可以使用更抽象的类型约束,例如使用一般的整数类型 123function add3(x::Integer, y::Integer) return x + yend 此时可以支持更多种类的参数进行调用,例如 12add3(Int32(1), Int32(10)) # 11add3(Int32(1), 10) # 11 注意到这里允许两个参数是不同的整数类型,Julia 提供了 where 关键字为泛型编程增加额外约束(类似 C++ 的 concepts 和 requires),例如要求两个参数的...
