惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AI
AI
博客园 - 叶小钗
Blog — PlanetScale
Blog — PlanetScale
Microsoft Azure Blog
Microsoft Azure Blog
Vercel News
Vercel News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
MyScale Blog
MyScale Blog
大猫的无限游戏
大猫的无限游戏
A
About on SuperTechFans
量子位
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 【当耐特】
Martin Fowler
Martin Fowler
阮一峰的网络日志
阮一峰的网络日志
D
Docker
Jina AI
Jina AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
The Register - Security
The Register - Security
J
Java Code Geeks
S
SegmentFault 最新的问题
月光博客
月光博客
G
Google Developers Blog
美团技术团队
Last Week in AI
Last Week in AI
L
LangChain Blog
Apple Machine Learning Research
Apple Machine Learning Research
T
The Blog of Author Tim Ferriss
腾讯CDC
Recent Announcements
Recent Announcements
Recorded Future
Recorded Future
The Cloudflare Blog
有赞技术团队
有赞技术团队
博客园_首页
博客园 - 聂微东
人人都是产品经理
人人都是产品经理
B
Blog
I
InfoQ
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
F
Fortinet All Blogs
B
Blog RSS Feed
Engineering at Meta
Engineering at Meta
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Microsoft Security Blog
Microsoft Security Blog
MongoDB | Blog
MongoDB | Blog
爱范儿
爱范儿
D
DataBreaches.Net
F
Full Disclosure
M
MIT News - Artificial intelligence
博客园 - 司徒正美
H
Help Net Security

纸鹿摸鱼处

北京实习300天 | 纸鹿摸鱼处 实习后买了一堆东西 | 纸鹿摸鱼处 谈谈不受欢迎的博客技术特征 | 纸鹿摸鱼处 我们的设备被拿来做了什么:软件的背景行为 | 纸鹿摸鱼处 生成式AI正在生成 | 纸鹿摸鱼处 前端字体二三事 | 纸鹿摸鱼处 深色模式开发的最佳实践 | 纸鹿摸鱼处 寻不回手工油糕 | 纸鹿摸鱼处 一些数码外设的评价和“捡垃圾”心得 | 纸鹿摸鱼处 朋友的 Vivado 和 Modelsim 装上了吗 | 纸鹿摸鱼处 迟到三月的年末博客杂谈:动力、文章和内容 | 纸鹿摸鱼处 VitePress 不完全优化指南 | 纸鹿摸鱼处 给电脑新手的笔记本开荒指南导读 | 纸鹿摸鱼处 再谈考试时钟:技术之外的思考 | 纸鹿摸鱼处 今日校园见闻:我已经出离高兴了 | 纸鹿摸鱼处 配置并差点运行不了 Java Applet | 纸鹿摸鱼处 Windows 上的开源软件入门 | 纸鹿摸鱼处 博客进化:从 Hexo 到 Nuxt Content | 纸鹿摸鱼处 祖母的90年代南昌差旅之险 | 纸鹿摸鱼处 Linux 下通过 Samba 共享文件夹 | 纸鹿摸鱼处 从“端口无法访问”到本地环境问题——朋友的博客踩坑记录 | 纸鹿摸鱼处 Windows 空间管理/清理指南 | 纸鹿摸鱼处 遭遇APP乱象:老人的「钱袋子」开线了 | 纸鹿摸鱼处 封面被 Linux QQ 官方用了,但是有一些小缺陷 | 纸鹿摸鱼处 Windows 终端体验优化指南 | 纸鹿摸鱼处 有问题,就要讲出来。 | 纸鹿摸鱼处 从 CSS 排序折腾到 Stylelint 和 pnpm | 纸鹿摸鱼处 使用 DOSBox 的多种方式 | 纸鹿摸鱼处 今日有「假」 | 纸鹿摸鱼处 把博客文章按年份放在子文件夹中了 | 纸鹿摸鱼处 Arch Linux 启动引导修复 | 纸鹿摸鱼处 在延长今天和期待明天之间 | 纸鹿摸鱼处 今日无事,除了一些技术咨询 | 纸鹿摸鱼处 系统引导配置分享 | 纸鹿摸鱼处 病毒高占用CPU,三天杀俩 | 纸鹿摸鱼处 运营商又想多收话费了 | 纸鹿摸鱼处 电脑连接手机,手机给电脑传文件…… | 纸鹿摸鱼处 Moonlight 串流指南 | 纸鹿摸鱼处 SSH 免密登录 | 纸鹿摸鱼处 Termux 简单指南 | 纸鹿摸鱼处 Tailscale 不完全使用指南 | 纸鹿摸鱼处 Windows 安装指南 | 纸鹿摸鱼处 Arch Linux 易用性及美化 | 纸鹿摸鱼处 Arch Linux 初步配置 | 纸鹿摸鱼处 使用 ArchInstall 安装 Arch Linux | 纸鹿摸鱼处 VS Code 简单配置项 | 纸鹿摸鱼处 他修电脑又遇到了我 | 纸鹿摸鱼处 修监控 (授权转载) | 纸鹿摸鱼处 被大块落冰砸中的话—— | 纸鹿摸鱼处
写过的奇妙代码。 | 纸鹿摸鱼处
纸鹿本鹿, hi@zhilu.cyou · 2024-04-07 · via 纸鹿摸鱼处

C 语言排序:根据条件选择排序依据

这是一个简单的 ls 实现,于2023年3月4日学习 C 语言时编写。82 行处使用了选择排序,但是排序条件会根据参数的设置(-t -r)来选择排序的依据:

  • !!(param & P_r):检查参数 param 是否设置了标志位 P_r-r 是逆序参数)。双感叹号 !! 用于将布尔值转换为 0 或 1。
  • 逻辑异或运算 ^:根据 P_r 设置情况,决定后续的排序判断结果是否需要翻转。
  • (param & P_t):检查参数 param 是否设置了标志位 P_t。如果设置了,则表示需要根据文件的修改时间进行排序,否则根据文件名进行排序。
c
// 排序文件列表
for (int i = 1, j, temp; i < entc; i++) {
    temp = enti[i];
    for (j = i;
         // 排序的 condition 很长
         j > 0 && !!(param & P_r) ^ (param & P_t
             ? entv[enti[j - 1]].mtime > entv[temp].mtime
             : strcmp(entv[enti[j - 1]].name, entv[temp].name) > 0);
        j--)
        enti[j] = enti[j - 1];
    enti[j] = temp;
}

这里的排序的条件比较复杂,但是有效简化了排序的逻辑,不需要再写很多 if 语句来判断排序条件。

Linux 下简单 ls 命令的实现

/2023/zls

程序中关于参数解析的内容也比较有意思,使用了宏函数来解析参数,同时二进制标志位来存储参数。

HTML 模板生成器

2023年2月7日,我建立了一个简单的网址导航页面。4 天后,我和半岛的孤城聊了聊,他觉得用 HTML 手搓导航项不够优雅,于是推荐我用类似 JSON 的结构来维护导航项。

他推荐我用 JS 的模板字符串来生成导航,但是遇到了一些问题,最后发现是生成的 HTML 标签没有正确闭合,导致浏览器报错。同时,由于我的导航项比较复杂,所以写出的模板生成器代码也很抽象。

js
const nav = {
    name: 'CO导航',
    description: '',
    list: [],
    ele: document.getElementsByClassName('navlist'),
}

nav.list[0] = [{
    name: '线上课时',
    icon: 'fa-solid fa-chalkboard-user',
    item: [
        { text: '学习通', icon: 'iconfont icon-chaoxing', link: 'http://i.chaoxing.com/' },
    ]
}, {
    name: '西邮生活',
    icon: 'fa-solid fa-school',
    item: [
        { text: '我在校园', desc: '网页版登录', icon: 'fa-solid fa-location-dot', js: 'dialog.showMsg(this.textContent)' },
    ]
},]

nav.list.forEach((list, i) => {
    nav.ele[i].innerHTML = list.map(group => `
    <div class="card">
    <div class="between">
    <h4><i class="${group.icon} fa-space"></i>${group.name}</h4>
    ${group.desc ? `<p class="dim">${group.desc}</p>` : ``}
    </div>
    <div class="list">
    ${group.item.map(item => `
      <a data-sub="${item.desc || ''}"
      ${item.js ? `onclick="${item.js}"` : `href="${item.link}"`}
    >${item.icon ? `<i class="${item.icon} fa-space"></i>` : ``}${item.text}</a>
    `).join(`\n`)}
    </div>
    </div>`).join(`\n`)
})

模板生成器的嵌套结构比较复杂:

  • 使用 nav.list.forEach() 遍历名为 nav.list 里的每一个导航块。
  • 在每个导航块中,使用 map() 方法创建新的字符串数组,使用 join() 方法将数组里的导航组拼接为字符串。
  • 在每个导航组中,使用 map() 方法创建新的字符串数组,使用 join() 方法将数组里的导航项拼接为字符串。
    • 导航项可能会有图标、小字描述。
    • 有的导航项不是链接,而是 JS 脚本。

其实也可以用 createElement()appendChild() 来生成 HTML,或者 Vue 的组件也很方便。不过,用原生 JavaScript 写出来了这些,感觉还是挺奇妙的。

面向函数而不是面向过程

2024年4月6日,我在维护一个网页工具的背景列表。由于这个项目已经运营了三年,背景列表已经有了四百多张图片,并且还携带了一些描述信息。为了让代码看起来短一些,我先使用比较抽象的数据结构来存储,在使用时再生成更友好的数据结构。

js
const gallery = {
    End22: [['呱唧', '山望', '2/12/16/HBqoL'], ['呱唧', '瞰林', '2/12/16/HBBGX'],],
    Jan23: [['酸子', '云中印象', '3/01/03/E8Lwa'], ['酸子', '镜中暮', '3/01/03/E8HSK'],],
}

经过某个处理函数后,它应当变成这种结构:

js
const galleryFlated = [
    { vol: 'End22', author: '呱唧', name: '山望', url: 'https://ooo.0x0.ooo/2022/12/16/HBqoL.jpg' },
    { vol: 'End22', author: '呱唧', name: '瞰林', url: 'https://ooo.0x0.ooo/2022/12/16/HBBGX.jpg' },
    { vol: 'Jan23', author: '酸子', name: '云中印象', url: 'https://ooo.0x0.ooo/2023/01/03/E8Lwa.jpg' },
    { vol: 'Jan23', author: '酸子', name: '镜中暮', url: 'https://ooo.0x0.ooo/2023/01/03/E8HSK.jpg' }
]

刚开始使用面向过程的方式来处理,后来发现,使用面向函数的方式更简短清晰。

js
const galleryFlated = Object.entries(gallery).flatMap(([vol, picInfos]) =>
    picInfos.map(([author, name, shortURL]) => ({
        vol,
        author,
        name,
        url: `https://ooo.0x0.ooo/202${shortURL}.jpg`,
    }))
)

总结

这些代码不算是 Best Practice,甚至有些抽象,不过挺有意思的。