update
This commit is contained in:
0
.gitignore
vendored
Normal file → Executable file
0
.gitignore
vendored
Normal file → Executable file
0
image.png
Normal file → Executable file
0
image.png
Normal file → Executable file
|
Before Width: | Height: | Size: 3.5 MiB After Width: | Height: | Size: 3.5 MiB |
0
image2.png
Normal file → Executable file
0
image2.png
Normal file → Executable file
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
145
main.tex
Normal file → Executable file
145
main.tex
Normal file → Executable file
@@ -1,33 +1,30 @@
|
|||||||
% !TeX TS-program = xelatex
|
% !TeX TS-program = xelatex
|
||||||
|
|
||||||
\documentclass{resume}
|
\documentclass{resume}
|
||||||
\ResumeName{连奕恒}
|
\ResumeName{个人简历}
|
||||||
|
|
||||||
% 如果想插入照片,请使用以下两个库。
|
|
||||||
\usepackage{graphicx}
|
\usepackage{graphicx}
|
||||||
\usepackage{tikz}
|
\usepackage{tikz}
|
||||||
|
|
||||||
|
\setmainfont{Latin Modern Roman}
|
||||||
|
|
||||||
\begin{document}
|
\begin{document}
|
||||||
|
|
||||||
\ResumeContacts{
|
\ResumeContacts{
|
||||||
|
姓名:连奕恒,%
|
||||||
|
学历:硕士,%
|
||||||
|
专业:软件工程,%
|
||||||
(+86)178-8812-0369,%
|
(+86)178-8812-0369,%
|
||||||
\ResumeUrl{mailto:lianyh0266@outlook.com}{lianyh0266@outlook.com},%
|
\ResumeUrl{mailto:lianyh0266@outlook.com}{lianyh0266@outlook.com},%
|
||||||
% \ResumeUrl{https://blog.fkynjyq.com}{blog.fkynjyq.com} \footnote{下划线内容包含超链接。},%
|
|
||||||
% \ResumeUrl{https://github.com/fky2015}{github.com/fky2015}%
|
|
||||||
}
|
}
|
||||||
|
|
||||||
% 如果想插入照片,请取消此代码的注释。
|
|
||||||
% 但是默认不推荐插入照片,因为这不是简历的重点。
|
|
||||||
% 如果默认的照片插入格式不能满足你的需求,你可以尝试调整照片的大小,或者使用其他的插入照片的方法。
|
|
||||||
% 不然,也可以先渲染 PDF 简历,然后用其他工具在 PDF 上叠加照片。
|
|
||||||
\begin{tikzpicture}[remember picture, overlay]
|
\begin{tikzpicture}[remember picture, overlay]
|
||||||
\node [anchor=north east, inner sep=1cm] at (current page.north east)
|
\node [anchor=north east, inner sep=1cm] at (current page.north east)
|
||||||
{\includegraphics[width=2cm]{image.png}};
|
{\includegraphics[width=2cm]{image2.png}};
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
|
|
||||||
\ResumeTitle
|
\ResumeTitle
|
||||||
|
|
||||||
|
|
||||||
\section{教育经历}
|
\section{教育经历}
|
||||||
\ResumeItem
|
\ResumeItem
|
||||||
[西安电子科技大学|硕士研究生]
|
[西安电子科技大学|硕士研究生]
|
||||||
@@ -35,8 +32,8 @@
|
|||||||
[\textnormal{软件工程,计算机科学与技术学院|} 专业学位研究生]
|
[\textnormal{软件工程,计算机科学与技术学院|} 专业学位研究生]
|
||||||
[2024.09—2027.06(预计)]
|
[2024.09—2027.06(预计)]
|
||||||
|
|
||||||
% \textbf{GPA: 3.62/4.0},主要研究方向为\textbf{拜占庭共识算法},在分布式系统领域方面有一定的研究和工程经验。\textbf{2024年应届生}。
|
主要研究方向为密态数据库、加密数据查询与索引结构。2027 年应届生。
|
||||||
主要研究方向为\textbf{密态数据库和数据索引}。\textbf{2024年应届生}。
|
|
||||||
|
|
||||||
\ResumeItem
|
\ResumeItem
|
||||||
[兰州理工大学|本科生]
|
[兰州理工大学|本科生]
|
||||||
@@ -48,84 +45,84 @@
|
|||||||
|
|
||||||
\section[技术能力]
|
\section[技术能力]
|
||||||
{技术能力}
|
{技术能力}
|
||||||
% \protect\footnote{与求职岗位无关的技能省略或用灰色表示。}
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item \textbf{语言}: 熟练使用 C/C++,熟悉面向对象特性、内存模型与多文件工程组织; 了解 C++11 常用特性(智能指针、Lambda 表达式等); 了解协程的实现原理; 具备 Java、Go、Python 使用经验,能够快速上手新语言。
|
\item 熟悉 C/C++ 开发,熟悉面向对象的编程思想,熟悉常用设计模式和STL;
|
||||||
\item \textbf{系统与并发}: 熟悉 Linux 环境开发,理解进程/线程管理、内存管理机制; 熟悉协程原理、多路复用模型(select / poll / epoll),了解 Reactor / Proactor 架构。
|
熟悉智能指针、Lambda 表达式、协程原理;
|
||||||
\item \textbf{组件}: 熟悉线程池连接池; 无锁队列; 网络缓冲区; 定时器; 死锁检测; 分布式锁; 异步日志方案spdlog; 应用层协议设计ProtoBuf。
|
对原子变量、内存序与无锁数据结构设计有一定了解。
|
||||||
\item \textbf{网络}: 熟悉 TCP/IP 五层模型,掌握 TCP/UDP、HTTP 等常见协议;能够基于 Socket 进行 Linux 网络编程,理解高并发服务器基本设计思路。
|
\item 熟悉 Linux 操作系统,对进程/线程模型、常用IPC以及内存管理有一定了解。
|
||||||
\item \textbf{数据结构与库}: 熟悉 STL 常用容器(vector、map 等)及其底层实现原理。
|
\item 掌握 Socket 网络编程,熟悉 TCP/IP 协议栈;熟悉 epoll/select 等 I/O 多路复用模型与异步 I/O 框架 io\_uring ;熟悉 Reactor / Proactor 架构。
|
||||||
\item \textbf{数据库}: 熟悉 MySQL ,了解索引、事务、锁机制、MVCC,具备一定 SQL 调优能力; 熟练掌握 Redis 常用数据结构及应用场景,了解持久化、淘汰策略与集群原理。
|
\item 了解 SPDK 用户态存储框架,有 Blobstore 实际开发经验;了解 Linux VFS 层次结构与 POSIX 文件系统调用语义;具备 LD\_PRELOAD 拦截用户态 I/O 的经验;对应NVMe协议有一定了解。
|
||||||
\item \textbf{工程与工具}: 熟悉 Linux 常用命令; Git 协作流程; GDB; 熟悉 Docker 容器技术。
|
\item 具备 eBPF 程序开发经验,使用过 uprobe/kprobe/tracepoint 等探测点;探索过 eBPF 内核态网络转发方案。
|
||||||
\item \textbf{后端开发}: 了解项目开发流程与前后端交互方式,能够基于 RESTful API 规范进行后端接口设计。
|
\item 了解 Redis 基本原理;熟悉 MySQL,了解索引、事务、锁机制、MVCC;完成 15445 BusTub 数据库项目。
|
||||||
|
\item 熟悉 Linux 常用命令;了解 Makefile、Cmake;熟悉 Git、GDB;使用过 gprof、strace。
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
% \section{工作经历}
|
|
||||||
|
|
||||||
% \ResumeItem{北京 ABCD 有限公司}
|
|
||||||
% [后端开发实习生/XXXX]
|
|
||||||
% [2020.10—2021.03]
|
|
||||||
|
|
||||||
% \begin{itemize}
|
|
||||||
% \item \textbf{独立负责XXX业务后端的设计、开发、测试和部署。}通过 FaaS、Kafka 等平台实现站内信模板渲染服务。向上游提供 SDK 代码,增加或升级了多种离线和在线逻辑。完成了业务对站内信的多样需求。
|
|
||||||
% \item \textbf{参与 XXX 的需求分析,系统技术方案设计;完成需求开发、灰度测试、上线和监控。}
|
|
||||||
% \end{itemize}
|
|
||||||
|
|
||||||
\section{项目经历}
|
\section{项目经历}
|
||||||
|
|
||||||
\ResumeItem{\textbf{BusTub} 基于 C++ 的简易单机数据库}
|
\ResumeItem{ZVFS | 基于 SPDK 的透明 POSIX 文件系统 }
|
||||||
[ \textnormal{CMU 15-445} 课程]
|
[独立开发 | \ResumeUrl{https://git.1ian.cn/lian/zvfs}{gitea}]
|
||||||
[2024.11 - 2025.04]
|
[2025.11 --- 2026.03]
|
||||||
|
|
||||||
|
\vspace{0.5em}
|
||||||
|
|
||||||
|
\noindent 透明用户态文件系统原型,面向 AI 检索场景(pgvector)对存储 I/O 的高吞吐需求,通过 LD\_PRELOAD 无侵入劫持 POSIX I/O,将文件数据路径路由至 SPDK Blobstore,在零业务代码改动下绕过内核 I/O 栈。透明接管 PostgreSQL及 pgvector 已完成功能验证。
|
||||||
|
\par
|
||||||
|
|
||||||
|
% \ResumeDesc{技术栈}{SPDK / NVMe / Blobstore / LD\_PRELOAD / xattr / Unix Domain Socket。}
|
||||||
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item 实现了基于可扩展哈希表和LRU-K的内存池管理。实现了可并发的B+树,支持乐观加锁的读写操作。
|
\item 需要非侵入的绕过内核 I/O 栈以降低存储延迟:以 LD\_PRELOAD 劫持 POSIX I/O 接口,通过 Unix Domain Socket 将 LD\_PRELOAD 层拦截的 POSIX I/O 请求路由至 Daemon 进程,由 Daemon 统一接管 SPDK Blobstore 数据路径,完成数据库场景零侵入接入。
|
||||||
\item 采用火山模型实现了查询、修改、连接、聚合等查询执行器,对部分查询进行了改写与下推。
|
|
||||||
\item 采用 2PL 进行并发控制,支持死锁处理、多种隔离级别、表锁和行锁。
|
\item 从零实现目录树工程复杂度极高:控制面全部复用 Linux VFS 管理目录、权限、inode 生命周期,仅以 xattr将文件绑定至对应 SPDK Blob;无需实现元数据存储/载机制,显著降低实现复杂度。
|
||||||
\item 对数据库系统有了基本的认识和实践。
|
|
||||||
|
\item SPDK 的 Ownership 机制要求固定线程操作元数据:设计 Daemon 进程为「单 IPC I/O 线程 + 单 SPDK 元数据线程 + 多 SPDK I/O 线程」架构,在满足 SPDK 单线程约束的同时支持并行数据 I/O。
|
||||||
|
|
||||||
|
\item 多进程下需要正确模拟 fork/dup 等语义:在 Daemon 进程中模拟 Linux Open File Description 与 FdTable 模型,并通过 IPC 同步引用计数与偏移语义,保证多 fd / 多进程共享句柄时行为一致。
|
||||||
|
|
||||||
|
\item 每次 I/O 重新申请 DMA 内存导致延迟抖动:实现 DMA IO Pool 复用 DMA 内存区域,消除重复申请开销。
|
||||||
|
|
||||||
|
\item FIO 中 WRITE 延迟明显高于预期:对端到端路径加轻量打点,将总延迟分解至各层;定位到无条件 RMW、poller 调度抖动、线程未绑核等多个叠加问题,逐项修复后 spdk服务端延迟 从毫秒级降至约 350 µs。
|
||||||
|
|
||||||
|
\item 性能测试:在 VMware + 模拟 NVMe 环境下,FIO 16K Psyn 随机写达到 kernel 路径约 73\% IOPS(1353 vs 1855),平均时延为 692 µs;顺序对齐写场景下吞吐达spdk\_nvme\_perf 基准 90\%(4K: 94/100 MiB/s;128K: 1662/1843 MiB/s)。单客户端场景 TPS 为 38.2,对比 kernel 39.1,端到端性能基本持平(约 4\% 差距)。
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
% \ResumeItem{\textbf{KVDB} 分布式 \textbf{KV} 存储系统}
|
\vspace{1em}
|
||||||
% [ \textnormal{MIT 6.824} 课程]
|
|
||||||
% \begin{itemize}
|
|
||||||
% \item 实现了 Raft 协议的选举、日志复制、持久化、日志压缩等基本功能。
|
|
||||||
% \item 基于 Raft 协议实现了满足线性一致性的 KV 数据库。
|
|
||||||
% \item 采用 Multi-Raft 架构,支持数据分片,分片迁移,分片垃圾回收和分片迁移时读写优化。
|
|
||||||
% \item 对分布式系统的设计考量有了更多的认识。
|
|
||||||
% \end{itemize}
|
|
||||||
|
|
||||||
\ResumeItem{\textbf{L-RPC} 基于Reactor的RPC项目}
|
|
||||||
[C++ 协程实现N:M调度模型]
|
\ResumeItem{LDB | 高性能 KV 存储系统 \& 本地语义问答引擎}
|
||||||
[2025.11—2022.12]
|
[独立开发 | \ResumeUrl{https://git.1ian.cn/lian/ldb}{gitea}]
|
||||||
|
[2025.02 --- 2025.07]
|
||||||
|
|
||||||
|
\vspace{0.5em}
|
||||||
|
|
||||||
|
\noindent 自研 KV 存储引擎,兼容 RESP 协议,支持 pipeline;采用 Reactor/epoll + io\_uring 架构实现高性能网络与持久化路径。在此基础上构建本地语义问答系统,通过向量检索与三层路由降低 LLM 调用成本。
|
||||||
|
\par
|
||||||
|
|
||||||
|
% \ResumeDesc{技术栈}{Linux、Reactor、epoll、io\_uring、RESP2、eBPF、共享内存 IPC、gprof、ChainBuffer、SPSC。}
|
||||||
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item 基于 \textbf{C++11} 实现的多线程 RPC 框架,采用 \textbf{主从 Reactor 架构},底层基于 \textbf{epoll} 实现 I/O 多路复用,支持高并发网络通信。
|
\item 频繁小对象分配导致内存碎片严重:自实现内存池统一管理分配,小对象场景吞吐较 glibc malloc 提升 7\%。
|
||||||
\item 应用层基于 \textbf{Protocol Buffers} 设计并实现自定义 RPC 协议,完成服务注册、请求编解码与调用分发流程。
|
\item AI问答的长回复在固定缓冲区下存在内存浪费:以 ChainBuffer + ET 边缘触发 + readv 直读重构收发路径,支持大命令缓冲,实现跨分段大Key解析。
|
||||||
\item 采用 \textbf{多线程 + 协程的 N:M 并发模型}:由 N 个 I/O EventLoop 线程负责事件监听与分发,M 个工作线程中以协程方式调度业务逻辑,减少线程阻塞与上下文切换开销。
|
\item 同步持久化阻塞主线程,高并发下落盘成为瓶颈:以 io\_uring + n×spsc 落盘线程组实现异步持久化,配合 in-flight 背压防止 CQ overflow,负载均衡分摊写压力;无fsync 时 set QPS 损失仅 5.6\%,每秒fsync一次 QPS损失 11.3\%,读路径接近零影响。相较同步持久化方案,整体性能提升 2x。对比Redis AOF 模型持久化开销降低50\%。
|
||||||
\item 自主实现 \textbf{异步日志系统},通过独立日志线程与缓冲队列解耦业务逻辑与 I/O 操作,降低日志对主流程性能影响。
|
\item 运行时内存泄漏难以追踪:通过 eBPF 实现热插拔泄漏探测组件,对比 valgrind 性能开销更小且无需重启即可介入。
|
||||||
\item 在本地压测环境下,框架在简单 Echo/RPC 场景中可稳定支撑 \textbf{10W QPS} 级别请求。
|
\item 为实现读写分离架构,降低主进程压力:实现基于独立进程的主从同步,通过共享内存向独立同步进程转发写命令,QPS损失15\%。设计基于内核态函数探测的eBPF转发方案,探测开销低于3\%。
|
||||||
|
% \item 增量持久化路径存在性能瓶颈:gprof 定位后发现提交落盘任务频繁申请内存,引入组提交机制与可复用组提交缓冲池,合并多次写入批量落盘;持久化路径开销降低 23\%。
|
||||||
|
\item 针对重复问题频繁触发 LLM 调用导致的高延迟与高成本问题:设计“精确匹配 → 向量检索 → LLM 兜底”的三层路由,显著减少模型调用次数与 tokens 消耗。
|
||||||
|
\item 性能测试:压测场景(RBTree,256B value,pipeline=128)下 set/get 吞吐达同环境 Redis 的 72\% / 75\%。
|
||||||
|
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
\ResumeItem[EncryptSql 基于 PostgreSQL 的透明加密查询与运算框架]
|
|
||||||
{\textbf{EncryptSQL} 基于 PostgreSQL 的透明加密查询与运算框架}
|
|
||||||
[学校横向|部分代码开发]
|
\section{个人总结}
|
||||||
% {\ResumeUrl{https://github.com/BITNP/BIThesis}
|
|
||||||
% }
|
|
||||||
[2024.09 — 2025.09]
|
|
||||||
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item 在客户端侧对 \textbf{libpq} 进行改造,实现 \textbf{SQL 解析后重写}:将原生表达式/运算符节点替换为密态版本的函数/算子调用,使业务侧尽量无需改动即可使用加密能力。
|
\item 对基础组件开发具有浓厚兴趣,喜欢与系统底层机制打交道,关注系统性能优化与高并发处理能力。
|
||||||
\item 基于 \textbf{PostgreSQL 扩展机制}(如自定义函数/算子等)接入密态运算:支持常见算术运算(加/减/乘/除)与部分聚合能力,运算由自定义实现承载并与查询执行流程集成。
|
\item 对关系型数据库原理较为熟悉,对常见非关系型数据库有一定了解。
|
||||||
\item 设计并实现基于工厂模式的 \textbf{KMS 调用接口框架},在\texttt{encryptsql} 组件中通过统一接口完成密钥获取/管理;实现 \textbf{LocalKMS}与\textbf{HuaweiKMS API的接口适配}用于本地开发,并支持替换为任意实现该接口的外部 KMS 系统。
|
\item 了解线程池、连接池、无锁队列、网络缓冲区、定时器等基础组件的设计。
|
||||||
\item 针对耗时较长/安全要求更高的计算场景,引入 \textbf{可信执行环境(TEE)} 执行部分运算流程。
|
\item 阅读过 DPDK 中 MPMC 无锁队列的实现源码,对高性能并发数据结构有一定理解。
|
||||||
|
\item 具备使用 Codex / AI 编程工具辅助开发的经验。
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
% \section{个人总结}
|
|
||||||
|
|
||||||
% \begin{itemize}
|
|
||||||
% \item 本人乐观开朗、在校成绩优异、自驱能力强,具有良好的沟通能力和团队合作精神。
|
|
||||||
% \item 可以使用英语进行工作交流(六级成绩 XXX),平时有阅读英文书籍和口语练习的习惯。
|
|
||||||
% \item 有六年 Linux 使用经验,较为丰富的软件开发经验、开源项目贡献和维护经验。善于技术写作,持续关注互联网技术发展。
|
|
||||||
% \end{itemize}
|
|
||||||
|
|
||||||
|
|
||||||
\end{document}
|
\end{document}
|
||||||
41
resume.cls
Normal file → Executable file
41
resume.cls
Normal file → Executable file
@@ -1,12 +1,11 @@
|
|||||||
\RequirePackage{expl3,l3keys2e}
|
\RequirePackage{expl3,l3keys2e}
|
||||||
\ProvidesExplClass{resume}
|
\ProvidesExplClass{resume}
|
||||||
{2022-12-26}{0.1.0}{Another Resume Class by Feng Kaiyu}
|
{2022-12-26}{0.1.0}{Another Resume Class by Feng Kaiyu}
|
||||||
|
|
||||||
% Keep Quiet
|
% Keep Quiet
|
||||||
\PassOptionsToPackage{quiet}{xeCJK}
|
\PassOptionsToPackage{quiet}{xeCJK}
|
||||||
\ProcessOptions\relax
|
\ProcessOptions\relax
|
||||||
\LoadClass[zihao=5,autoindent=0.5em]{ctexart}
|
% \LoadClass[zihao=5,autoindent=0.5em]{ctexart}
|
||||||
|
\LoadClass[zihao=-4,autoindent=0.5em]{ctexart}
|
||||||
% Define paper size.
|
% Define paper size.
|
||||||
\RequirePackage{geometry}
|
\RequirePackage{geometry}
|
||||||
% Remove the default header and footer.
|
% Remove the default header and footer.
|
||||||
@@ -20,25 +19,18 @@
|
|||||||
\RequirePackage{xeCJKfntef}
|
\RequirePackage{xeCJKfntef}
|
||||||
% Provide colors.
|
% Provide colors.
|
||||||
\RequirePackage{xcolor}
|
\RequirePackage{xcolor}
|
||||||
|
|
||||||
% Clean pagestyle.
|
% Clean pagestyle.
|
||||||
\pagestyle{empty}
|
\pagestyle{empty}
|
||||||
|
|
||||||
% Adopt A4 style but with smaller margins.
|
% Adopt A4 style but with smaller margins.
|
||||||
\geometry{a4paper,margin=1cm, bottom=0.5cm}
|
\geometry{a4paper,margin=1cm, bottom=0.5cm}
|
||||||
|
|
||||||
%%% Global Variables %%%
|
%%% Global Variables %%%
|
||||||
|
|
||||||
% Store all contacts info.
|
% Store all contacts info.
|
||||||
\seq_new:N \g__resume_contacts_seq
|
\seq_new:N \g__resume_contacts_seq
|
||||||
% Store title name.
|
% Store title name.
|
||||||
\tl_new:N \g__resume_title_name_tl
|
\tl_new:N \g__resume_title_name_tl
|
||||||
|
|
||||||
%%% Global Settings %%%
|
%%% Global Settings %%%
|
||||||
|
|
||||||
% No page number.
|
% No page number.
|
||||||
\pagenumbering{gobble}
|
\pagenumbering{gobble}
|
||||||
|
|
||||||
% Set the style of section title.
|
% Set the style of section title.
|
||||||
\ctexset{
|
\ctexset{
|
||||||
section = {
|
section = {
|
||||||
@@ -46,46 +38,37 @@
|
|||||||
number = {},
|
number = {},
|
||||||
format = \noindent \zihao{4} \heiti \__resume_section_title_format:n,
|
format = \noindent \zihao{4} \heiti \__resume_section_title_format:n,
|
||||||
indent = -1em,
|
indent = -1em,
|
||||||
afterskip = 0.5em,
|
afterskip = 0.7em, % 原 0.5em
|
||||||
beforeskip = 0.2em,
|
beforeskip = 0.4em, % 原 0.2em
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
% Set the style of list.
|
% Set the style of list.
|
||||||
\setlist{
|
\setlist{
|
||||||
labelsep=2pt,
|
labelsep=2pt,
|
||||||
labelwidth=5pt,
|
labelwidth=5pt,
|
||||||
leftmargin=1.3em,
|
leftmargin=1.3em,
|
||||||
itemsep=0em,
|
itemsep=0.30em, % 原 0em
|
||||||
parsep=0.20em,
|
parsep=0.20em, % 原 0.20em
|
||||||
topsep=0em,
|
topsep=0em,
|
||||||
}
|
}
|
||||||
|
|
||||||
% Set the line spacing.
|
% Set the line spacing.
|
||||||
\linespread{1.15}
|
\linespread{1.15} % 原 1.15
|
||||||
|
|
||||||
% New counter for bookmarks.
|
% New counter for bookmarks.
|
||||||
\newcounter{resumebookmark}
|
\newcounter{resumebookmark}
|
||||||
|
|
||||||
%%% User Commands %%%
|
%%% User Commands %%%
|
||||||
|
|
||||||
% Predefined commands.
|
% Predefined commands.
|
||||||
\cs_new:Npn \__resume_append_concat:n #1
|
\cs_new:Npn \__resume_append_concat:n #1
|
||||||
{
|
{
|
||||||
\seq_put_right:Nn \g__resume_contacts_seq {#1}
|
\seq_put_right:Nn \g__resume_contacts_seq {#1}
|
||||||
}
|
}
|
||||||
|
|
||||||
% Predefined commands.
|
% Predefined commands.
|
||||||
\cs_new:Npn \__resume_section_title_format:n #1
|
\cs_new:Npn \__resume_section_title_format:n #1
|
||||||
{#1 \vspace{3pt} \hrule}
|
{#1 \vspace{3pt} \hrule}
|
||||||
|
|
||||||
|
|
||||||
% Add a contant info.
|
% Add a contant info.
|
||||||
\NewDocumentCommand{\ResumeContact}{m}
|
\NewDocumentCommand{\ResumeContact}{m}
|
||||||
{
|
{
|
||||||
\__resume_append_concat:n {#1}
|
\__resume_append_concat:n {#1}
|
||||||
}
|
}
|
||||||
|
|
||||||
% Add multiple contant info.
|
% Add multiple contant info.
|
||||||
% ```
|
% ```
|
||||||
% \ResumeContacts{ itemA, itemB, itemC }
|
% \ResumeContacts{ itemA, itemB, itemC }
|
||||||
@@ -98,13 +81,11 @@
|
|||||||
\__resume_append_concat:n {##1}
|
\__resume_append_concat:n {##1}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
% Add your resume title, which generally is your name.
|
% Add your resume title, which generally is your name.
|
||||||
\NewDocumentCommand{\ResumeName}{m}
|
\NewDocumentCommand{\ResumeName}{m}
|
||||||
{
|
{
|
||||||
\tl_set:Nn \g__resume_title_name_tl {#1}
|
\tl_set:Nn \g__resume_title_name_tl {#1}
|
||||||
}
|
}
|
||||||
|
|
||||||
% Render the title.
|
% Render the title.
|
||||||
\NewDocumentCommand{\ResumeTitle}{}
|
\NewDocumentCommand{\ResumeTitle}{}
|
||||||
{
|
{
|
||||||
@@ -114,10 +95,9 @@
|
|||||||
% Reduce the space.
|
% Reduce the space.
|
||||||
\vspace{-1.4em}
|
\vspace{-1.4em}
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\seq_use:Nnnn \g__resume_contacts_seq {~|~} {~|~} {~|~}
|
{\zihao{5} \seq_use:Nnnn \g__resume_contacts_seq {~|~} {~|~} {~|~}}
|
||||||
\end{center}
|
\end{center}
|
||||||
}
|
}
|
||||||
|
|
||||||
% Render the section title.
|
% Render the section title.
|
||||||
% #1(optional): This content will be used as the bookmark in PDF.
|
% #1(optional): This content will be used as the bookmark in PDF.
|
||||||
% #2: The title of the section.
|
% #2: The title of the section.
|
||||||
@@ -145,11 +125,9 @@
|
|||||||
\IfValueT{#3}{
|
\IfValueT{#3}{
|
||||||
\tl_if_empty:nF {#3} {
|
\tl_if_empty:nF {#3} {
|
||||||
\ |
|
\ |
|
||||||
\textit{
|
|
||||||
#3
|
#3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
\hfill
|
\hfill
|
||||||
\IfValueT{#4}{
|
\IfValueT{#4}{
|
||||||
#4
|
#4
|
||||||
@@ -157,17 +135,14 @@
|
|||||||
\par
|
\par
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
% Gray out the content.
|
% Gray out the content.
|
||||||
\NewDocumentCommand{\GrayText}{m}
|
\NewDocumentCommand{\GrayText}{m}
|
||||||
{
|
{
|
||||||
\textcolor{gray}{#1}
|
\textcolor{gray}{#1}
|
||||||
}
|
}
|
||||||
|
|
||||||
% Render content with a hyperlink, marked with underline.
|
% Render content with a hyperlink, marked with underline.
|
||||||
\NewDocumentCommand{\ResumeUrl}{mm}
|
\NewDocumentCommand{\ResumeUrl}{mm}
|
||||||
{
|
{
|
||||||
\href{#1}{\CJKunderline{#2}}
|
\href{#1}{\CJKunderline{#2}}
|
||||||
}
|
}
|
||||||
|
|
||||||
\endinput
|
\endinput
|
||||||
Reference in New Issue
Block a user