程序员学哪一门语言更不容易失业
今天,大学室友微信群在聊一个很经典的话题,程序员学哪一门语言更不容易失业?
有人认为PHP已经到了黄昏,有人认为Go语言可以和Java掰一下手腕,有人认为没有什么是一行sql解决不了的,有人认为 Python和Java永远是主流,能干到头秃… (有研究表明,程序员与秃头并没有太大的相关性,研究并不一定准)
我的观点是,javascript和 Node.js配合,更不容易失业,JS这门语言应用极为广泛,几乎什么都能做,Web小程序(React),App开发(React Native),桌面应用(Electron)都可以用js写,是万金油一般的存在。
JS这门语言易上手,上限很高,从业者众多,依赖包生态也极为丰富,神库众多,即使你的水平一般,也能借助各种神库,写出健康的代码,保持健康的发量。
JS深度绑定Web生态,JS是Web生态的基石,Web是互联网的基石,互联网技术越发展,JS的内容层次就越丰富,同时也意味着,JS程序员要不断学习,才不会被后浪拍在沙滩上,说穿了,想要不失业,就要不断学习。
JS是最接近前端的语言,前端是最接近用户的,如果想要证明自己的编程实力,可以自己搞开源项目,而JS很适合搞开源项目,一个周末写个油猴子增强插件不是梦~
在2023年,很多人在喊前端已死,我认为初级水平的前端可以被机器取代,但JS程序的基数极为庞大,如果拥有对JS程序调优的能力,那就不容易失业,如果能用ChatGPT这类工具提升开发效率,那反而会让我们的工作更轻松。
本文永久更新地址:
https://fangyuanxiaozhan.com/p/2023-03-16-16-24-25-js/
摄影天然适合程序员
程序员的脑力劳动远大于体力劳动,写个人博客是很好的爱好,但脑力不足的时候,摄影是程序员天然的生活调味剂。
-
摄影增加运动量,提升程序员的体力,多走多拍才有好照片,摄影给久坐的程序员一个锻炼的机会,努力锻炼,保持健康,活得久比什么都重要。
-
摄影教会程序员做减法,提升程序员审美,微软的程序大多功能丰富,毫无设计感,而好的摄影作品讲求明确主体,突出主题,简化画面,懂得做减法的程序员能前往更高的境界。
-
摄影扩大程序员折腾的范围,找到更多可玩的领域,Adobe全家桶,相机raw解码软硬件,照片原片的存储备份,不同焦段原副厂镜头的选购,走山访海旅行计划的制定,游戏摄影配套插件工具的优化,都能扩大程序员的折腾范围,这些恰好都和程序相关。
-
摄影是一门下限很低,上限极高的学科,如果一门知识的上限很低,便不可持续,而摄影的上限很高,即使到了70岁,我们只要出门打开取景器,就可能拍出比以往作品都更好的照片,持续向上发展的兴趣,能给程序员更好的人生体验。
-
摄影容易交到朋友,扩大程序员的社交范围,程序员大量的时间都被工作占据,交朋友的时间很少,而摄影这项爱好,能让我们通过同城摄影群,交到各行各业的朋友。
本文永久更新地址:
https://fangyuanxiaozhan.com/p/2023-03-16-16-11-43-programmer-photography/
我为什么喜欢用锤子便签
锤子便签配色舒服,适合阅读,锤子便签用户界面一直是暖色,背景与文字的配色都很舒服,无论是创作者还是阅读者,都有很好的观感。
锤子便签免费且没有广告,锤子便签没有搞订阅制,也没有广告,属于真正小而美的软件。
锤子便签有Web版!我认为一个工具良不良心,支持web是很重要的指标,支持web就意味着可以在任何可以安装浏览器的设备使用,即使你是Linux用户。
锤子便签支持多端同步,无论是安卓,iOS,还是PC web版都能顺利同步进度,对于拥有碎片化时间的人,我们可以在床上用iPhone或安卓手机写,起床后可以用PC或Mac接着写。
锤子便签生成的图片分辨率很不错,锤子便签生成的图片适合发布在各种社交媒体,文字不失真,排版工整细致,图片适合阅读,也方便下载存档。
锤子便签默认字体很周正,适合发正式的通知,非衬线字体适合发通知,锤子便签字体很适合发布通知内容。
本文永久更新地址:
https://fangyuanxiaozhan.com/p/2023-03-16-16-04-56-smartisan-notes/
建议Apple推出新表带:你大爷永远是你大爷!公园唱歌老大爷才是Apple Watch的核心用户
在深圳莲花山公园闲逛,遇到一位老大爷唱歌,周围很多阿姨围观,仔细观察,发现老大爷的手表是Apple Watch!


老大爷或许才是Apple Watch的核心用户,关注自身健康,喜欢手表,退休金充裕,配合iPad 可以组个K歌全家桶,而且Apple Watch 还支持电子木鱼App,没事可以敲两下,功德加一
建议库克出个老大爷专属表带,表带名为:「你大爷永远是你大爷」(手动狗头)
本文永久更新地址:
https://fangyuanxiaozhan.com/p/2023-02-23-12-51-18-apple-watch/
ChatGPT是一个理解自然语言的工具箱
ChatGPT的话题在2023年2月格外火热,以聊天对话的形式,为人类提供大量的专业知识。

ChatGPT 擅长产出符合逻辑的答案,人类的逻辑能力其实并不好。作为一个开发工程师,我发现代码80%的BUG,都是程序逻辑有问题,即使是常年写码的工程师,也会写出逻辑有问题的程序,ChatGPT非常适合排查代码片段,辅助工程师写出逻辑正确的代码,在这方面, ChatGPT最大的竞品是Github Copilot

ChatGPT拟人化的问答模式,非常适合当老师。学会一门知识,本身是枯燥的,如果把知识转换为ChatGPT问答的形式,将会极大提升课堂的趣味性,玩过RPG游戏的人,要进行大量的问答,这些问答往往是几个固定的问题,再给几个固定的选项,如果将知识转换为RPG游戏的形式,并给予极大的问答自由度,学生就变成了玩家。
ChatGPT适合仿制3A游戏,3A游戏需要大量的人力,海量的资金投入,巨长的开发周期;引入ChatGPT,游戏开发者只需定义玩法,ChatGPT就可以生成中规中矩的罐头游戏,罐头游戏并非贬义词,市面上绝大多数游戏都是没什么特色的罐头游戏,ChatGPT能生成罐头游戏,反而让开发者们,更有时间去研究特色玩法。
ChatGPT适合生成产品发布会,因为发布会的套路都是固定的;ChantGPT也适合做直播,因为直播的套路也是固定的;ChatGPT最适合做的是公务员,我们一直谈法制,但不好搞,ChatGPT代替法官来判案,代替律师来辩护,会让罪与罚更容易一一对应。
ChatGPT 会员终于开放了,支持万事达,Visa,每月20美元,开通后有两个模型可选,开通会员后,会默认使用提升回答速度的版本,当然也可以选择普通速度的Legacy版本。

买ChatGPT PLUS会员并不容易,需要用海外信用卡支付,我办了Depay的海外万事达卡,特色是支持USDT充值,如果50美元开卡,可以免月租;如果需要海外信用卡,可以通过我的邀请链接开卡 https://depay.depay.one/web-app/register-h5?invitCode=620375&lang=zh-cn
ChatGPT非常适合写脚本,但小概率会出现类型错误,变量名的语义和实际进行的操作产生了误差(命名不规范坑人也坑ChatGPT)

ChatGPT可以帮忙写很多前端样式,对汉语描述的理解非常到位,我们还可以不断追加要求,要求ChatGPT对代码进行改写,真的是理想的乙方


让ChatGPT用Node.js写一个同步脚本
写一个基于rsync命令同步服务器目录(比如 /opt)到本地目录(比如 ~/cloud-backup/ )的Node.js每日定时备份脚本;
支持配置登陆用户, 和登录服务器信息, 服务器IP, 登录端口, 登录用户, 无需配置密码, 默认使用ssh key登录;
每天的备份目录用YYYY-MM-DD日期格式命名,如果从服务器同步的文件夹为 `/opt/` , 则在本地的存放位置为 `${用户目录}/cloud-backup/YYYY-MM-DD/opt/` ,传输速度限制为每秒100KB,如果同步失败, 则1分钟后自动重试, 只保留最近14天的备份, 过期的备份自动删除;
如果本地文件夹不存在,则自动创建;
同步过程中, 打印同步文件进度的log; log同步输出到脚本同级目录下的log.txt文件, log.txt只保存最近14天的log, 过期的log自动删除;
将功能点细分为函数, 便于后续扩展;
列出以上脚本依赖包相关的 package.json
我需要使用pm2守护运行这个脚本,请给出pm2凌晨2点25分运行脚本的方法
ChatGPT输出代码
const { exec } = require("child_process");
const { format } = require("date-fns");
const fs = require("fs");
const path = require("path");
const { promisify } = require("util");
const execAsync = promisify(exec);
const SSH_KEY_PATH = process.env.SSH_KEY_PATH || "~/.ssh/id_rsa";
const SYNC_FOLDER = "/opt";
const BACKUP_FOLDER = `${process.env.HOME}/cloud-backup`;
const SSH_CONFIG = {
host: "example.com",
port: 22,
username: "example",
};
const MAX_SPEED = 100; // KB/s
const RETRY_INTERVAL = 60 * 1000; // 1 minute
const MAX_BACKUPS = 14;
const now = new Date();
const backupFolderName = format(now, "yyyy-MM-dd");
const backupFolderPath = path.join(BACKUP_FOLDER, backupFolderName);
const logFilePath = path.join(__dirname, "log.txt");
async function syncWithRetry() {
let success = false;
while (!success) {
try {
await sync();
success = true;
} catch (err) {
console.error(err);
console.log(`Sync failed, retrying in ${RETRY_INTERVAL / 1000} seconds...`);
await new Promise((resolve) => setTimeout(resolve, RETRY_INTERVAL));
}
}
}
async function sync() {
const command = `rsync -a --progress --max-size=${MAX_SPEED}K --delete -e "ssh -i ${SSH_KEY_PATH}" ${SSH_CONFIG.username}@${SSH_CONFIG.host}:${SYNC_FOLDER} ${backupFolderPath}`;
console.log(`Syncing ${SSH_CONFIG.username}@${SSH_CONFIG.host}:${SYNC_FOLDER} to ${backupFolderPath}...`);
await execAsync(command);
console.log("Sync finished.");
}
async function removeExpiredBackups() {
const backupFolders = await fs.promises.readdir(BACKUP_FOLDER);
const expiredBackups = backupFolders
.filter((folder) => folder !== backupFolderName)
.sort()
.slice(0, -MAX_BACKUPS);
await Promise.all(
expiredBackups.map((folder) =>
fs.promises.rm(path.join(BACKUP_FOLDER, folder), { recursive: true, force: true })
)
);
}
async function removeExpiredLogs() {
const logs = await fs.promises.readdir(__dirname);
const expiredLogs = logs
.filter((log) => log.endsWith(".log") && log !== `${backupFolderName}.log`)
.sort()
.slice(0, -MAX_BACKUPS);
await Promise.all(expiredLogs.map((log) => fs.promises.rm(path.join(__dirname, log))));
}
async function createBackupFolder() {
try {
await fs.promises.mkdir(backupFolderPath, { recursive: true });
console.log(`Created backup folder: ${backupFolderPath}`);
} catch (err) {
if (err.code !== "EEXIST") {
throw err;
}
}
}
async function main() {
await createBackupFolder();
await syncWithRetry();
await removeExpiredBackups();
await removeExpiredLogs();
const logText = `Synced ${SSH_CONFIG.username}@${SSH_CONFIG.host}:${SYNC_FOLDER} to ${backupFolderPath} at ${new Date().toISOString()}\n`;
await fs.promises.appendFile(logFilePath, logText);
}
main().catch((err) => console.error(err));
如果输出中断,我们可以要求ChatGPT继续上次的输出,而不用重新生成


然而,ChatGPT 还是漏了package.json的输出,我们可以要求ChatGPT对package.json内容重新输出

前面我们明确要求了ChatGPT进行函数式编程,如果我们需要优化某个函数的输出,可以直接让ChatGPT继续修改

运行ChatGPT修改后的脚本

修改后的脚本可以顺利完成同步任务,由于rsync可以自动跳过已同步的文件,当天,多次运行同步脚本,也可以快速进行增量同步。
让ChatGPT推荐一些WordPress主题

如果我们有自己的WordPress网站,个人服务器带宽有限,首屏打开速度不理想,也可以让ChatGPT给出一些轻量化主题推荐
小结
2023年,用中文在搜索引擎(Google, Bing, baidu)查点儿东西(凯恩斯陷阱),大概率都会指向知乎,但知乎产品又做的非常粪坑,强迫用户装App, App各种无厘头的弹窗广告,搞的推荐和热榜话题简直是兢兢业业的给用户喂shi

ChatGPT确实可以当搜索引擎来用,用中文问内容,几乎是有问必答,而且干净无废话,不懂还可以追问,一言以蔽之,搜索引擎本身也不生产内容,和ChatGPT一样,都是内容的搬运工,但ChatGPT和搜索引擎的用户体验简直是天壤之别,而且ChatGPT还可以通过加入新数据,不断成长,搜索引擎确实应该努努力了,一个无法持续优化的搜索引擎,是无法和ChatGPT竞争的。
本文永久更新地址:
https://fangyuanxiaozhan.com/p/2023-02-12-11-51-20-chatgpt-tools/
编程小技巧:尽早汪汪汪的狗才是好狗;少用胶水;避免被僵尸吃掉脑子
尽早汪汪汪的狗才是好狗
我们的工作是去野外采摘药草,然后卖给药店,为了提高效率,我们打算买条狗,此刻有甲乙两条狗,可以购买...
甲狗:一旦发现药草,就立刻汪汪汪!
乙狗:发现药草后,默不作声,然后向随机方向走上100米,然后汪汪汪...
我们应该选择哪条狗?乙狗显然没啥用
对应到日常编程中,我们的代码,接收到不合理变量输入时,应尽快报错(汪汪汪),而不是等到程序崩溃了,再去回头找错误。
少用胶水
我买了个手办,需在墙上固定一个木板,把手办摆上去,有两个方案:
方案A: 搞瓶胶水,然后把木板侧面与墙粘合在一起。
方案B: 在墙上打孔,然后在孔里加两根棍,形成一个支架,在支架上放一个木板。
胶水方案方便,问题在于,黏到墙上,就完全无法调整,而支架可以加小垫片精调。
需求也会随时间变化,多放几个手办,胶水粘性无法承担更大的重量,自然被废弃。
写码不是一锤子买卖,要留出精调的参数,也要方便修改,适应不断增长的需求
避免被僵尸吃掉脑子
内存泄漏是一个经典问题,用Javascript写程序,我们需要使用定时器,监听器,如果我们用完后忘记清理,就会造成内存泄漏。这些定时器,监听器就像一只只僵尸(Zombies),在地下室里蹒跚而行(参考植物大战僵尸中的普通僵尸)

这些幽灵般的不死不灭的僵尸会吃掉大脑,让记忆外泄(内存泄漏), React Hook这类工具也给出了 useEffect return 函数的方式,专门清理这些僵尸;
内存泄漏无小事,关注代码运行的副作用,规范编码,不要让僵尸吃掉脑子。
本文永久更新地址:
https://fangyuanxiaozhan.com/p/2023-02-04-14-57-27-good-code/
土地财政锁死了中国年轻人的未来,买房变租房,一念天地宽
原贴 本人目前是码农,关于是否要在 35 前进入体制内,和女朋友有了如下对话,不知道大家怎么看 https://v2ex.com/t/912179

在V站看到篇帖子,发帖的老哥和他女朋友因为房子,体制,35岁后码农就业的问题,进行了一波儿深入的探讨。
我的看完后的,直观感受是,这也太没劲了。作为一个程序员,我和帖子中的老哥处境类似。
作为一个创业公司的程序员,我连下个月做什么需求都无法确认,当然也无法预测10年后某地段的房子会不会升值。
为了10年后所谓的资产升值,疯狂压榨当下的自己,并不是正常的做法。
儿孙自有儿孙福,如果父母很聪明,下一代的智商,大概率是比不上父母的,但智商比不上父母,并不代表下一代不幸福,还未结婚,就考虑下一代孩子阶级跌落,本就是一件很无厘头的事,那些疯狂鸡娃的人,就好比是宫崎英高世界里追求永生的人,无一例外全是悲剧。
我所在的小区,离腾讯滨海大厦很近,有三十多层楼,距今已有二十年,我感觉已经不太宜居了,物业也都是50岁左右的人,配合超高的楼层,再过十年,不知道还有多少户人家。
人要给自己留余裕,不要勉强自己,活得久比什么都重要。
本文永久更新地址:
https://fangyuanxiaozhan.com/p/2023-02-01-20-08-34-it/
赚钱之外的爱好有什么用?
按照主流的价值观,除了赚钱,其它的兴趣什么的都是不误正业。
想要了解一个人,我会先询问一个人的兴趣
如果一个人的兴趣是玩游戏,玩的还是超高难度的魂类游戏,那他是个有坚韧精神的人。
如果一个人的兴趣是长期写博客,那他是个乐于分享且乐于探索新事物的人。
如果一个人的兴趣是长期健身,而且身材好于普通人,那他是个严于律己的人。
如果一个人的兴趣是疯狂抽烟,且除此之外别无爱好,那他可能是个热爱祖国痴迷纳税的乐子人…
兴趣体现了生命的质量与能量,一个人兴趣多一分,应付复杂环境的自由度就大一分。
本文永久更新地址:
https://fangyuanxiaozhan.com/p/2022-12-08-19-34-54-hobby/
2022年终总结
这篇文章总结一下2022年做了啥...
换工作
zhaoolee年初换了份工作,从一家金融公司转到一家互联网公司,金融公司会儿比活儿多,互联网公司活儿比会儿多。
研究开发桌面端应用
进入新公司,更新了一波技术栈,开始做Electron技术栈的桌面端应用,把已有的Web端应用,扩写为桌面端应用,路由适配,多窗开发,开机启动,托盘信息,日志收集,进程通讯,sdk集成,签名发版,自动更新...
与macOS Windows原生开发相比,Electron优化不够极致,优势是很省人力,一套核心代码打通Web, Windows, macOS, Linux ,目前的腾讯QQ也在切Electron技术栈,人力成本优化真的无处不在。
我翻阅了大量Electron开发相关的中文资料,普遍写的很烂,Electron相关的中文书籍也已经过时,水平很一般,废话多,关键地方一笔带过。
zhaoolee打算以一线开发者的身份,写一套实用的Electron开发经验博客,选用Github Wiki作为载体,挖个坑,留给2023年
更新一些树莓派家庭服务以及内网穿透玩法相关的博客
去年10月份zhaoolee开了一个把树莓派变身家庭服务器的开源项目 https://github.com/zhaoolee/pi 目前已经有1K Star, 但写了7篇后,树莓派就变成了理财产品(变得毫无性价比),比显卡价格还坚挺。不过zhaoolee还是保持了项目的更新,目前更到了15篇。
关于内网穿透,树莓派家庭服务器很多玩法都是基于frp内网穿透技术,最近几周,zhaoolee在普通Windows笔记本上,基于frp和v2ray,实现BT种子的双向网络穿透,可以和海外老哥进行硬盘资源的p2p交流。
更新受欢迎的开源项目,折腾新的开源项目
较多维护的已有项目:
今年又开了一些新坑:
为了消除魔幻新闻的的负面影响,玩了一些「后悔没早点玩到」的单机游戏
2022年有很多魔幻新闻,那些新闻总让人觉得很消极,后面我找到一种方法来抵消这种消极,那就是玩单机游戏,很感谢这些游戏,把我暂时拉到了另一个世界去逃避现实。
今年把异度神剑2 和 异度神剑3 通关了,也许是对日式RPG情有独钟,目前在玩最终幻想7重置版;
玩游戏其实是一件很奢侈的事,一需要设备,二需要时间,三需要找到自己喜欢的游戏;
好的游戏让玩家感觉时间没有虚度,听到异度神剑2的配乐 One Last You 响起,配合大结局的动画,让我后悔没有早点玩到这样的游戏。女神异闻录5的美术风格,让我发出游戏居然可以做成这样的赞许,也理解了P5天下第一这个梗。

2022年是艰难的一年,三国耗尽英雄气 两晋皆是鼠辈出,小丑们粉墨登场,给全国人民演出一场场闹剧,这些小丑其实一直存在,只不过有了互联网,小丑们的荒诞直接呈现在了全国人民面前。
控制饮食锻炼身体
今年尝试了5个月左右的过午不食,体重下降到了比较理想的范围,控制饮食和进行锻炼,都有助于体重下降,但实践下来,控制饮食的效果远好于锻炼。
另外,控制饮食还有一个好处,吃不饱只有一个烦恼,吃饱了会有无数烦恼,保持相对饥饿的状态,能避开很多精神内耗。
新一年的计划
- 持续更新技术博客,树莓派和内网穿透系列会持续更新(Just for fun)
- 保持身体健康,避免二次感染新冠
- 开坑Electron实用开发技巧系列博客
- 能做到以上三点,我就很满足

本文永久更新地址:
https://fangyuanxiaozhan.com/p/2022-12-31-12-18-02-2022-mark/
年青人为什么会变成愤青
初入社会的年轻人,相信奋斗就能改变人生,然而大多数情况下,父母因素的决定性更大。
领导们倡议,给年轻人更多的生存空间,一个个都要一本正经地胡说一通,很享受那种唾星四溅的快感,但又不许年轻人讲话,于是,网络环境越来越扭曲变形。
由于太缺乏改变人生的正常途径,才导致任何可能暴富的东西,都异乎寻常的流行,比如股票,炒房,P2P,传销,互联网金融,加密货币,赌球…
以上套路被年青人探索完成后,毫无收获,就容易变成愤青。有人说,青年是一个国家的希望,准确来讲,愤青才是一个国家的希望。
本文永久更新地址:
https://fangyuanxiaozhan.com/p/2022-12-08-19-06-38-young-people/