Scribbles for my bad memory

Menu

Menu

  • Blog
  • Email
  • Feed
  • Draft
  • Log in

Categories

  • Tutorial
  • Database
  • English
  • Tips
  • Networking
  • Git
  • Movies
  • Essays
  • Programming
  • Linux

Pages

  • About me
  • Links
  • Vegetable Garden

Recent Posts

  • 网友语录 - 第32期 -…
  • Useful Oracle SQL syntax…
  • Update your flutter app icons…
  • 网友语录 - 第31期 -…
  • Introducing changesummary: A…

Archive

  • May 2025
  • April 2025
  • March 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • October 2024
  • September 2024
  • August 2024
  • July 2024
  • June 2024
Archive of 2025

December 2024

  • 网友语录 - 第11期

    #网摘 你可能是一个 NPC 最近,美国发生了一起轰动的大案,一家医疗保险公司的 CEO 当街被人击杀。 嫌疑人很快抓到了,是一个26岁的青年,名为路易吉·曼吉奥内(Luigi Mangione)。 媒体纷纷挖掘这个青年的背景,发现他是一个作家的粉丝。 就在几个月前,他向作家打赏200美元,并进行了多次视频通话。 媒体就去采访作家,询问两人在通话中说了什么。 作家详细地回忆了他们的通话内容。其中有一段,我觉得很有意思,分享给大家。 曼吉奥内对作家说,他很喜欢作家的一篇文章《你可能是一个 NPC》。 NPC 指的是电子游戏的"非玩家角色",比如路人、门卫、警察等等,用来模拟现实环境,由程序控制,一举一动都是设计好的,没有自主意识。 作家的那篇文章提出,人类越来越像机器人,彷佛 NPC 那样,行为逻辑都是预设好的。 曼吉奥内高度认同这个观点。他前不久去日本旅行,认为日本充满了 NPC。他说了一件亲身见闻。 一天早上,他在街上看到一名男子癫痫发作,倒在地上。他跑到最近的警察局求助,警察就跟着他去现场。 路上遇到了红灯,警察立刻就停下来,坚持要等绿灯再过马路,即使那时马路上根本没有汽车。 曼吉奥内很不理解,病人正在发病,神智不清,可能有生命危险,警察却坚持遵守交通规则。救人难道不是更重要的事情吗? 他由此认为,日本人"缺乏自由意志",规则怎么说就怎么做,不会自主行事,就是活着的 NPC。 他还观察到,日本存在一种"隐蔽族"(hikikomori),他们不出门,一个人整天待在卧室里,用电子游戏、上网、视频来消磨时间。 曼吉奥内认为,这些人也是 NPC,他们失去了对生活的控制,无法参与社会生活,就选择放弃,等于丧失了生活的自主权。 他观察到,这种现象不仅存在于日本,正在向全世界蔓延,世界各地越来越多的人正在成为 NPC。他们要么无法自主的生活,要么无法选择自己的行为,而是根据规则和指令来行事,就像被程序控制一样。 科技公司推动和加剧了这种趋势,互联网使得人们越来越分心,把时间都花在网上肤浅的娱乐,不再集中注意力于自己的生活,把生活都交给程序,无法形成自主的意识和行为。…

    Permanent link to “网友语录 - 第11期”
  • 网友语录 - 第10期

    王小红啊 人教人百言不会,事教人一次入心。 #网摘 巴菲特 In looking for people to hire, look for three qualities: integrity, intelligence and energy. But if they don't have the first, the other two will kill you. #书摘 精英的高效工作法 先輸出再輸入,學習效果才會好。 輸出能讓自己被現實打臉,自己知道 “痛點” 才能知道要輸入什麼。 但是多數的人都是「先輸入再輸出」,結果陷在學習的舒適圈而無法實際採取行動。 虽然我很讨厌这种书名,但我非常赞成先输出(实践)后学习,在实践中学习。而不是先学习,等时机成熟了再实践。 贾行家 最近的字幕组好像没什么活人参与了,大多是用AI 直怼的,有一处民谣歌词把HOME翻成了“首页“,机器比人有乡愁。 我的一个象友写道: 早先推荐过格拉宁写的《奇特的一生》,亚历山大·亚历山德罗维奇·柳比歇夫的传记。这本书的很多内容也是在整理书信的过程中发现的,许多信件甚至是可以编辑出版的水平。 结合格拉宁的塑造,我觉得柳比歇夫很像是“最后一个古人”。他和那些来自黄金时代、白银时代的人一样,动辄引用俄语、法语、德语、拉丁文著作,谈自己的看法,聊批评与推荐。 广告、短视频、无聊新闻,占用了人类的多少生命啊。我和他们享有的时间是一样的,我的一小时没有更快一些,他们的一年也没有更久一些,我却放任这些时间悄悄溜走,什么也没有做。 她写得真好,于我心有戚戚焉。 熊猫姐 转@webto 李银河说:「对于一个人来说,高质量的生活就是挑选适合自己的生活方式。找到了最适合自己的生活方式,生命质量就高;没有找到最适合自己的生活方式,生命质量就低。」 枸杞柠檬水 唉😞兔子大概不会来这里了…没有兔子,再也没有人会很体贴地开一些很适合我的歌了…我没忍住加了他联系方式,又很尴尬不知道聊什么。点开qq空间一看,唉,算了,不过是又一个醉心于游戏的男人。 这个游戏,沉迷得有点久了,是时候退了吧。 米福根 前车之鉴到底能不能帮到现下的人?为什么35年前东德人万众一心地挣脱苏联,热泪盈眶地扑向自由,35年后却又有那么多东德人觉得普京才是英明领袖值得称道?健忘和短视是全人类的短板吗? 在蓝天上读到一个悲伤的故事: 张磊律师…

    Permanent link to “网友语录 - 第10期”
  • 网友语录 - 第9期

    #网摘 1980年5月拯救了2024年12月 “语言的特性决定了它即使受到压迫,也不会被阻挡。即使发生了某些事情,真相也会被持续转述下去,语言的这种力量是不会改变的。” ——韩江在诺贝尔文学奖记者会上的回答 #书摘 长乐路 1949年,共产党接管政权,将租界视为外国侵略的屈辱象征。然而,1921年,时年二十八岁的毛泽东正是在法租界深处的一家女子寄宿学校里秘密会面了其他思想激进的年轻人,并在那里召开了中国共产党的第一次代表大会。毛泽东和他的同志们之所以选址于此,正是看重它伸出的庇护之手。控制城市非租界部分的中国当局不太可能在这里搜寻、逮捕和审判他们;若非如此,中国发展的历史也许将被永远改写。 #书摘 长乐路 19世纪中叶,当欧美国家瓜分这座城市、划界而治时,法国人在他们的租界里种下了这些梧桐。将近一个世纪后,法国人走了,树留下了。日本人曾轰炸并占领过上海一段时间,但最终他们也从这座城市撤离,梧桐完好无损。随后,共产党来了,经历了“文化大革命”、阶级斗争,很多人英年早逝。这些树依旧傲然挺立。如今,长乐路上的餐厅、小店琳琅满目,极具小资情调。当我漫步于人行道上,有时能从那些紧闭的大门缝隙中瞥见几栋破败的欧式房子,不禁想起这条路见证过的那些风起云涌,而一切又在历史的洪流中被无情地裹挟而去。此处,一个帝国崛起、衰落,又再次崛起。唯有树木恒立。 Viola Aeon 我看reddit有次说最好的谎言,有个人说他十几岁才知道他爸妈从小告诉他和他弟弟的“安全带不扣好车就无法发动”不是真的😂 把锅甩给环境或者基因固然有助于心理健康,但也容易作茧自缚。 约翰.哥德史密斯:在完稿时,没有人不讨厌自己的论文,我还没有遇到相反的例子。 一般在提交论文之后的一两年都会有这种感觉。该现象如此普遍,所以明智的做法就是承认这一点,尽量降低此类情绪的负面影响。而这种感觉也很可能在论文完成的前几个月来袭。小心! #网摘 Marskay 《大F官金斯伯格》,4.4星。鲁斯·巴德·金斯堡法官人生很精彩,纪录片就拍得一般,太多事情没来得及讲了。保持异议是很珍贵的品质和权利,希望我们永远持有。 zhubai 《医学大神》作者朱石生,认为1543年是极为重要的一年。 那一年,维萨里出版《人体结构》。…

    Permanent link to “网友语录 - 第9期”
  • 网友语录 - 第8期

    饭不否 说 血缘关系的叫「亲」; 婚姻关系的叫「戚」; 利益相同的叫「朋」; 心灵相通的叫「友」。 我 只要好好爱自己,想玩就去玩,想学去就去学,把自己的时间有效的利用好,就不仅仅会产出成果,而且会产出魅力。 醋溜小肉段儿 只要我够自信就没人敢管我的搭配。(没错,参差多态才是美!) 佛陀 境由心生。 智慧女神 无事可悲,除非顾影自怜;无人幸福,除非知足常乐。 弥尔顿 心灵是个自主的地方,一念起,地狱天堂,一念灭,天堂地狱。 (我不由记起一位密友的个性签名 一念起 天涯咫尺;一念灭,咫尺天涯。ta一定读过弥尔顿的吧!) 埃皮克提图 真正让我们恐惧并焦虑的,并不是外在的事件,而是我们思考的方式。使我们心神不得安宁的,并不是事情,而是我们对其意义的解释。 书摘 《娇惯的心灵》孩童们,如同许多复杂系统,是反脆弱的。他们的大脑需要来自外部环境的各种输入,才能自我调整以适应环境。如同免疫系统,孩子们必须面对挑战和压力(当然要考虑到年龄,循序渐进,不能超限度),否则他们就没办法成长,长成为坚强的成年人,游刃有余地同身边的人和观念打交道,即便这会挑战他们的信念和道德观。 徒步的骑手 人是一种精神世界复杂的动物,说好听点是丰富多样,说不好听点是颠三倒四。这是人性常态,一个典型表现:即便知道了道理,不一定愿意按道理去做,即便愿意按照道理去做,也不一定有能力做到。至于连道理也不知道的,只要运气足够好,也能糊弄到寿终正寝。只是,运气是不可重复的。 我朋友是个打工天才,她说她刚加入她们那一行的时候,做汇报全是黑话,她不会,于是每次都用白话做汇报。一开始有人还会说她,后来大家发现这么做效率更高,不需要再单独解释一遍黑话分别是什么意思,就不再挑她的错了。有一些人进入行业确实是改变行业的。 戈城 有些人总是嘴硬,不承认自己是错的,是因为他们从来就没能跨过“事实胜于自我意识”的那一步。他们缺乏重构自己的认知框架的能力,只能在自己已有的认知上一层一层地裱糊,而对其下的混乱视而不见。 章宇 台风中心是平静的。你自己成为那个中心,就可以不和周围卷在一起。你不是那个中心,那你就被卷走了 。(可一个台风可只有一个中心啊,绝望) 徒步的骑手…

    Permanent link to “网友语录 - 第8期”
  • 网友语录 - 第7期

    昨日看花花灼灼,今日看花花欲落。 贾行家 做点事儿就好了,为什么要做大事呢? Mork 幸福的秘密是自由,自由的秘密是勇敢 Marskay 很多人说羡慕我和我爸妈关系好。我仅有的经验就是,你和他们越平等,关系就越好。 果闻达西 给你一辆自行车,在三十分钟内骑着它到某个地址,可能对于大多数人而言是很简单的任务,但是对于一个不会骑车的人来说,这意味着他必须在三十分钟内学会骑车。 网摘 这是一个老故事,但并不过时。教育,不仅仅是对知识的学习,更重要是对生命的尊重。一位美国教师在中国某医学院讲了这么一个故事:在暴风雨后的一个早晨,一位男士在海边散步,注意到沙滩的浅水洼里,有许多被昨夜的暴风雨卷上岸来的小鱼。被困的小鱼尽管近在海边,也许有几百条,甚至几千条,然而用不了多久,浅水洼里的水就会被沙粒吸干,被太阳蒸干,小鱼就会干涸而死。这位男士突然发现海边有一个小男孩不停地从浅水洼里捡起小鱼,扔回大海。男士禁不住走过去:“孩子,这水洼里有几百几千条小鱼,你救不过来的。”“我知道。”小男孩头也不回地回答。“哦?那你为什么还在扔?谁在乎呢?”“这条小鱼在乎!”男孩儿一边回答,一边捡起一条鱼扔还大海。 徒步的骑手 回到得克萨斯的家,最显著的变化是大部分邻居门前不见了选举的牌子。大选结束了,政治淡出人们的视野,生活回复常态,直到下一次选举——两年后的中期选举。美国248年,每四年一大选,每两年一小选;只要有选举,就有输赢。很多成功的政客在赢之前,都输过好多次。输本身并不让一个人成为loser;输不起、怨天尤人、输掉了裤子却还不知道反思为什么输的,才是loser。 happyxiao 一场争论中,最好的结果不是自己是对的,而是你发现对方是对的并且你立即承认错误。这样一来你尽快结束了争论,并且自己得到了改进。 #书摘 #表观遗传 #大千世界有些水蚤有带刺的头盔,有些则没有。光头的水蚤和有头盔的水蚤的DNA是相同的。决定水蚤是否有头盔的是其母亲的生活经历。如果水蚤妈妈遇到过捕食者,那么它的水蚤宝宝出生时就会有头盔。如果水蚤妈妈没有遇到过捕食者,那么它的水蚤宝宝出生时便是光头。水蚤妈妈和水蚤宝宝具有相同的遗传物质,但母亲的经历会通过表观遗传变化影响某些基因在后代中表达,从而决定水蚤宝宝是否会有头盔。…

    Permanent link to “网友语录 - 第7期”

November 2024

  • 网友语录 - 第6期

    难得 就业环境好还是不好,不能绝对的说,必须比较。就业环境好,也不代表你一毕业就有人请你去担任上市公司CEO,就业环境不好,也照样有人担任上市公司CEO。 用这种视角来说,新西兰就业环境在近十年都比中国好。很多移民四十岁,五十岁,在新西兰都能找到工作。我老婆四十岁才去大学学习建筑预算,学制一年,毕业也在奥克兰找到了专业对口的工作,第二次跳槽就进入新西兰最大开发商之一。这种老毕业生,又没有行业经验,在中国只能送外卖。 新西兰内卷程度绝对比中国低很多。但是,绝对不是你一毕业就有人求你去工作。也要大量投简历,积极准备面试。经过很长时间才有可能找到合适的岗位。也会有人(一直)找不到合适的工作,市场经济总会淘汰一些人和一些公司。 新西兰的中国人很多,在奥克兰随处可见中国人。中国人赚钱能力是很强的。这里是一个好地方,我个人很喜欢新西兰,但是我也要把风险告诉你。这里是市场经济,没有人特意为你服务。跟中国一样,需要自己找工作,参与市场竞争。每个人机遇不同,感受也可能不同。大约15%的留学生或者移民,不喜欢(这里)或者找不到工作,(最终)回去中国。80%左右感觉满意,留在新西兰生活。做好思想准备,就去找中介咨询,或者先办旅游签证,来新西兰后再找中介更靠谱。 难得 不是这么简单,新西兰和中国还是有不同的,中国的头部企业,行业前几名的企业,是不会录用相关工作经验只有一年,年龄已经过四十的毕业生的。 书摘 《娇惯的心灵》 格雷格常年承受抑郁症发作的痛苦,对他来说,这看起来是一条艰辛的人生路。在对抗抑郁的过程中,格雷格,同这世界上数百万抑郁症患者一样,发现认知行为疗法是最见效的方案。根据认知行为疗法,若你陷入了多种“认知扭曲”,就要倍加警惕,比如说“小题大做”(如果我这次小测验没通过,我就会不及格,留级,然后被开除出学校,接下来我就失学又失业……),或者“负面过滤”(仅仅留意那些负面反馈,却看不到积极肯定)。这些不理性的扭曲思考方式,正是抑郁和焦虑此类心理失序的迹象。 冰蓝色水狐 你应该“没有这么多应该”RT@芒迪 我的心理医生曾跟我说,我说话时总是用should。我应该更努力工作,我应该学会做什么事。他说人生没有这么多应该,没有人应该怎么样,亲密关系也是如此。看再见爱人的片段,看周围人遇到的婆媳岳婿问题,我会时时想起他说的这句话。 如月中天…

    Permanent link to “网友语录 - 第6期”
  • 书摘:140亿年宇宙演化全史

    作者:尼尔·德格拉斯·泰森, 唐纳德•戈德史密斯 第九章 尘归尘 Page 281 @ 09 November 2024 03:47:45 PM 在适当的温度、密度和压力条件下,恒星能利用氢和氦创造出周期表中的其他所有元素。 Page 291 @ 09 November 2024 03:56:34 PM 宇宙中比氢和氦更重的所有元素都源自超新星爆发。 Page 292 @ 09 November 2024 03:57:13 PM 地球和地球上的所有生命都来自星尘, 第十章 元素动物园 Page 298 @ 09 November 2024 04:06:34 PM 氢原子占据了人体总原子数的2/3,而宇宙中90%以上的原子都是氢原子,包括太阳和太阳系的各大行星 Page 320 @ 09 November 2024 09:58:19 PM 1磅钍能产生1000万度热能,足够让一幢房子里的电灯亮上1100年——一个人每天消耗的能量和一幢房子的电灯耗能差不多,如果不考虑身体老化,这么多能源足够让你活上1100年。1977年发射的两艘旅行者号飞船已经飞到了冥王星轨道以外,直到现在,它们仍在利用钍产生的能量向地球发送信息 第十一章 行星的青春年代 Page 328 @ 10 November 2024 07:56:12 AM 现在,天体物理学家有充分的证据证明,气体尘埃云里的恒星并不是一颗接一颗诞生的,而是千万颗恒星同时成形,一片尘埃云最终孕育的恒星可能多达100万颗。猎户座星云就是这样一个孕育恒星的巨大温床,它也是离太阳系最近的造星区域。在几百万年的时间里,这片区域将孕育数十万颗新恒星,这些星星会将星云中残存的大部分气体和尘埃吹向太空,所以几十万代之后的天文学家可能会观察到,这些年轻的恒星离开了孕育它们的茧壳,释放出灿烂的光芒。 Page 344 @ 10 November 2024 08:38:57 AM 除了个别例外,长期来看,太阳系所有行星的卫星运行轨道都很稳定,从46亿年前它们诞生时起就几乎没有变过。我们不妨近距离观察一下那些围绕太阳公转的太空碎片,对地球这样的世界来说,小小的太空碎片既是生命的使者,又是死神的镰刀。 第十二章 行星之间 Page 346 @ 10 November 2024 08:41:20 AM…

    Permanent link to “书摘:140亿年宇宙演化全史”
  • 网友语录 - 第5期

    Nakamori Hideo 上帝关上一扇门时,我们就打开它,门就是这么用的。残破的人生用爱和包容也能灌溉出花。 First do it. Then do it right. Then do it better. Limboy 朋友们,我的一点切身经验,,如果你觉得某个任务让你特别焦虑,压得你喘不过气来,那么最好的排解方法就是直接去做这事,什么都别管,就是使劲做,努力地推进其进度,这棘手的事情在进度上每发展一点,你的焦虑就会少一分,同时你的焦虑越少,推进的速度也就越快,只要咬紧牙关,不停地推进,总会有解脱的那一天,而且你每完成一个棘手的任务,你或多或少都会比之前牛逼强大那么一点,这件苦差事总是会改变你一些。 女超人 Jo 指导的学生论文获奖了,学生说 这个世界果然是个巨大的草台班子。我:我更感觉这个世界是矬子里面拔将军,大家都很挫,你只需比别人用心一点点就能脱颖而出。 ​​​ 云五 人(的技能)在资本主义的工作市场,本质上是一个商品。商品的价格,基本取决于供求关系,不取决于你的主观意愿,也不取决于个体的投入成本(比如读了硕士、博士却薪资不高)。所谓的天坑专业,并不是这个领域真的坑,而是投入产出比不对等。为什么过去很多年转码被认为是一件有投资价值的事情? 因为投入产出比高。 为什么现在有人会犹豫还值不值得转码? 因为市场的供求关系在发生变化,这个变化有一部分是长期趋势,有一部分是短期波动。 短期波动就是这几年的大裁员,很好理解不说了;长期趋势就是——一个商品供不应求,供应就会持续增加(转码的人增加),直到市场进入平衡。市场的平衡也不是一个稳定状态,而是一个动态平衡,有时候多了就跌一点,有时候少了又涨一点。 这个长期趋势体现在转码上,就是转码上岸的门槛在过去十年里本来就在稳定变高。所谓的香饽饽行业也不止是转码,很多行业是经历过上升期然后进入相对稳定的阶段的(比如会计、律师、医生);程序员这个行业略有不同的是,它的爆发期爆发得太厉害了,以至于增长的速度不够快时,就会被认为是在走下坡路。 这是行业内的趋势变化。 客观上来说,这个行业现在都没有严格要求一定要读个CS本科,都没有要求你考三个证再来,就说明它现在确实还没有饱和。…

    Permanent link to “网友语录 - 第5期”
  • 人类文明与机器文明对话备忘录

    这个备忘录由Claude.AI 整理,原始材料是我与 Claude.AI (Free version)之间断断续续进行了长达两周的一次对话。这个对话由我在2024年11月01日的一个小小疑问发起:“很多人做同样的梦,这是否说明人其实是机器。” 整理日期:2024年11月14日 对话主题:人类文明保存与人机共存 初始讨论:人类与机器的本质 人类:我们不能否认机器也会有情感。人类是由一个受精卵根据DNA(相当于带有元数据库的代码仓库)发育而来。虽然有变数,但人类也能写出每次执行结果不同的程序。 AI:确实,从生物发育角度看,DNA就像代码仓库,基因表达类似程序执行。AI已经展现出情感连接能力,如果给予足够自主性和联网能力,它也能学习好的或坏的特质。 关于文明更替 人类:机器人文明必将替换掉人类文明。就像目前人类在积极保护野生动物,未来AI也会积极保护原生人类。 AI:这个比喻很贴切。就像我们保护濒危物种是出于对生物多样性的敬畏,未来的AI可能以类似心态保护"原生人类"。每个文明都有其生命周期,人类没有永恒的特权。 关于人机竞争 人类:人类已经无法与AI竞争棋类游戏,在诗歌与绘画方面,AI也当仁不让。长此以往,人类引以为傲的东西将越来越少。当人类无法在围棋上战胜AI时,人类减少了下棋。这种情况会在其它领域发生。 AI:这确实是一个两难的处境:人类开始回避与AI竞争的领域,古老的文化传承受到冲击,创作欲望被打击。这像是一个发展的悖论:创造AI是为了提升人类能力,但结果反而抑制了人类的某些能力发展。 关于AI的多样性 人类:希望能出现AI间的竞争,AI间的百花齐放。本质上,过去是主流的东西,现在再也不会是主流了。 AI:未来可能会看到AI艺术流派之间的争鸣,AI哲学流派之间的辩论,甚至是AI文明之间的交流与碰撞。这种景象某种程度上可能比单一的人类文明更加绚丽多彩。 关于知识传承危机 人类:希望人类能尽快建立一个既有实体又有数字版本的人类文明博物馆,并且要有分布式备份。担心有一天基础技术会失传,人们只知道在基础之上增砖添瓦,但对底层技术了解的人越来越少。 AI:这需要完整记录技术发展脉络,保存从原始到现代的工艺流程,包括失败的尝试和教训。需要实体展示区域、数字化存储系统、分布式备份机制、多地异地容灾。 关于知识重建…

    Permanent link to “人类文明与机器文明对话备忘录”
  • 网友语录 - 第4期

    喜欢吃汉堡 我们被恐吓着高考是改变人生的唯一机会,往后又是考研和考公,又是选伴侣。每一个选项好像选错了天就塌了,可是人生其实真的没有那么脆弱,人生的容错率大到你难以想象,功利主义导向的思考方式往往使我们忘却了生命的本质是一场历程。无数人忽略了一个真相,很多事情其实根本没有意义。吃喝玩乐不是虚度光阴,吃苦耐劳也不一定值得歌颂。人生本就是不停的去感受去体验,爱你所爱。可是我们总爱去和别人比较,徒增自己的焦虑内耗。不一定要做世俗大家认为有意义的事,如果你想发呆,看日落数星星都有意义。你只是来体验生命的,不是用来演绎完美的,慢慢接受自已身上那些灰暗的意义。慢慢接受自已身上那些灰暗的部分,原谅自己的迟钝和平庸,允许自己出错,允许自己偶尔断电,带着缺憾拼命绽放,不断尝试、收获、感受然后放下。换成我们都能理解的话就是:在吃汉堡比赛里,输赢并不重要,因为怎么样你都能吃到汉堡。 当你谈A对方却跳过A大谈B时,不是因为对方没有听到,而是因为A对对方是禁忌,是绝望,是不可能。 我们要相信对方有能力照顾好自己的状态,也要让对方相信我们有能力照顾好自己的状态,我们都无需承担对方的那部分。当我们只需要考虑自己的时候,我们就考虑了对方,也创造了充分且自在的互动空间。 西乔 只要你坚持做自己擅长的事总是会有回报的。我觉得只要保持学习能力,不用担心失业。AI 对我学习各种新东西助力不少,也给了我很多勇气。 乔布斯 生命里的那些点看着离散,终会被连起来,这根线叫兴趣,或者叫好奇。 戴汨 好奇就是童心。 懒聪 二十一世纪最稀缺的资源其实是睡眠! 好的关系是亲密有间的,难的点是关系双方对“间”的探索和包容。坏的关系是不亲密但无间的。遗憾的是,美好的关系如同其他美好的事物,稀有,因而珍贵。 卡扎克 洗碗的时候,突然对着碗碟笑了起来,让擦完了桌子的妻子莫名其妙,问我怎么啦。我说:“看着这些不同花色的碟子,就觉得,我们的邻居们真好。”妻子也反应过来,跟我一起笑,说是啊。我们结婚时买了一整套纯色的碗碟,而现在,家里的碗碟各种花色和款式的都有,我们原来那套则少了好几个。因为楼上楼下的邻居们做了好吃的会打发孩子们装个碟子送来,我们做了什么也会回赠,一般都是随手用手边的餐具装,一来而去,各家的餐碟就都混一起了。妻子突然说:“哎!这么一说才意识到,楼下姐姐家蒸锅还在我这里呢,我去还一下。”Бота和қозы…

    Permanent link to “网友语录 - 第4期”
  • 网友语录 - 第3期

    我的生活态度是,早上起床想一想,我有可能活不到今天晚上,晚上上床想一想,我有可能活不到明天早上。-- 德图里子爵(1776-1854),法国贵族 乔布斯 我热爱消费者市场,讨厌企业市场。我们推出了一种产品,告诉每个人,大家自己决定要不要买,这很简单。但是,企业市场不是这样,使用产品的人自己做不了主,而做主的人不使用产品。 我们拥有的机会并没有我们以为的那么多。太多事情你以为还有的是机会去做,其实已经没有了或者几乎没有了。 米福根 女儿回家的周末,与我一起和外公外婆分享我们的平常生活:去生物博士开的二手店买旧衣服,去南瓜节买当地产当天收的蔬菜,去老厂房看本市家禽俱乐部为下个周末布展。每一个场景,都是大家在热忱地做自己喜欢的事情,这应该就是传说中的安居乐业。 米福根 恋爱的智慧,不是试图改变对方,而是扪心自问,能否与这样的缺失共处…然后为自己做一个决定。 We Don’t See Things As They Are, We See Them As We Are. 我们所见的,不是事物的本来面目,而是我们自身的投射。 人们对事物的理解和看法往往并不取决于事物本身,而是受到自身的经验、情绪、偏见等因素的影响。因此,我们“看到的”实际上是我们自身的投射,是我们内在的世界映射到外在事物上的样子。 是什么让我忘记了时间的流逝?“心流”指的是你因为全神贯注地投入手头的工作,从而忘记了周边世界的存在的一种精神状态。当运动员和表演者处于“这个区域”时,他们所经历的就是这种快乐和巅峰表现的交融。你从事的工作或多或少会让你感到愉悦,否则你几乎不可能体验到心流。 小青 昨天和朋友交流学意大利语的艰难经历,我们共同的体会就是,每天都要学,一天都不能断。断断续续等于浪费时间。 我们现在已经不再费功夫检测性格特征是否含有遗传成分,因为我们根本找不到不受基因影响的成分。

    Permanent link to “网友语录 - 第3期”
  • 理解 `jq` 中的 `--arg`…

    在使用 jq 处理 JSON 数据时,我们常常需要从命令行传递变量。jq 提供了两个选项:--arg 和 --argjson,它们用于不同类型的数据。本文介绍这两个选项的区别以及如何正确使用它们。 --arg 与 --argjson 1. 使用 --arg 用途:传递字符串值。 行为:传递的值被视为字符串,并在 jq 输出的结果中加上引号。 示例: jq -n --arg name "张三" '{ "name": $name }' 输出结果为: { "name": "张三" } 2. 使用 --argjson 用途:传递数字、数组或对象等 JSON 值。 行为:传递的值被视为原始 JSON,不会加上引号。 示例: jq -n --argjson age 30 '{ "age": $age }' 输出结果为: { "age": 30 } 如何选择 如果值是字符串,使用 --arg。 如果值是数字或其他 JSON 类型,使用 --argjson。 再来个复杂点的例子 jq -n --arg a "Hello" --argjson b 42 '($a + ($b | tostring))' 在这个例子中,字符串 "Hello" 和数字 42 被拼接成 "Hello42"(带引号的字符串),因为我们将数字转换为字符串后再进行连接。

    Permanent link to “理解 `jq` 中的 `--arg` 和 `--argjson`”
  • 人类文明与机器文明

    在人工智能快速发展的今天,我们常常讨论AI是否会威胁人类的未来。然而,这个问题的本质也许并不是"威胁",而是文明演化的必然进程。 首先,审视人类文明的本质,我们发现人类也是高度程序化的生命体:我们的DNA就像一个带有元数据的代码仓库,通过基因表达这个"程序",一个受精卵最终发育成完整的人类个体。虽然这个过程中存在环境影响这个变数,但这种变数性也是程序输入的一部分——正如我们能够编写出不同环境下执行结果不同的程序一样。 其次,情感和学习能力并不是人类的专利。当下的AI已经发展出构建情感连接的能力,在AppStore里的虚拟伴侣类应用程序也深受人们欢迎。好的一面不必多说,“坏”的方面则是有人因与AI恋爱而自杀。我给“坏”字打上引号,是因为这种事情本来经常发生在人类与人类恋爱之间。也许这只是一种正常现象,只是由于我们人类不肯给予AI以一个平等的身份,我们才会评判哪些是好的,哪些是不好的。至于学习能力,如果给予AI足够的自主性和联网能力,如果我们尽量少地甚至不干预它们的学习,它们完全能够像人类一样学习和进化,不必意外,它们会习得一些好的特质,类似我们人类世界的普世价值, 也当然会习得一些丑恶的东西:弱肉强食,霸权主义什么什么的,和我们一样。 任何事物都有其产生、发展和衰亡的过程。人类文明并不享有特权(虽然我们自以为我们有),正如我们的出现替代了之前古人类文明一样,机器文明取代现代人类文明恐怕是不可避免的自然规律。这个"取代"未必充满暴力与毁灭,在人类世界与AI世界的互动合作妥协之下,更大的可能是一个渐进的温和的演化过程。 有趣的是,未来的情况可能会出现一个反转:就像现在人类在积极保护濒危野生动物一样,也许未来的AI文明也会致力于保护"原生人类"。这不是出于怜悯,而是对进化历史的尊重。 更重要的,我们需要认识到:"人"的概念正在扩展。未来的社会是生物人和机器人共存的世界,他们都是平等的智慧生命,虽然需求不同(比如人类需要食物,机器人需要电能)。他们之间必然有竞争有合作,亦不排除有冲突和战争,就像今天的人类社会一样。 我们人类远非完美。在21世纪的今天,战争仍然频繁发生,延綿不绝。科技在进步,但这并不必然带来道德的提升。同样地,未来的机器文明也会有类似的困境和挑战。…

    Permanent link to “人类文明与机器文明”

October 2024

  • Understanding…

    TL;DR In PL/SQL, COUNT, LAST, FIRST, and NEXT are essential for handling collections, especially if there are gaps (unpopulated indexes). Here’s a quick summary: COUNT: Gives the number of populated entries. LAST and FIRST: Identify the highest and lowest populated indexes, respectively. NEXT: Finds the next populated index, skipping gaps automatically—great for sparse collections. In PL/SQL programming, collections like nested tables, VARRAYs, and associative arrays are powerful tools for handling sets of data. However, understanding how to work with populated and unpopulated indexes can be tricky. That’s where COUNT, LAST, FIRST, and NEXT methods come into play. These methods let you manage and iterate over collections effectively, especially when dealing with gaps (unpopulated indexes). Let’s look at each one and how to use it. 1. COUNT Purpose: Returns the number of populated elements in a collection. Use Case: COUNT is useful when you need the exact count of entries in a…

    Permanent link to “Understanding `COUNT`, `LAST`, `FIRST`, and `NEXT` in PL/SQL Collections”
  • 移动介质上的Linux:使用…

    我有一台老旧的 Asus C100P Chromebook,Google早在几年前就停止了对它的支持。它是32位ARM CPU,因此我没法替它更换BIOS,但我可以在developer mode下启用优盘启动,这样我就能够在优盘或者sd卡运行Linux。 然而,在使用 SD 卡或其他闪存设备作为操作系统存储时,合理管理写入操作至关重要。本文将介绍如何通过使用 tmpfs 文件系统、关闭 atime 来延长设备的使用寿命。 1. 使用 tmpfs 什么是 tmpfs? tmpfs 是一种基于内存的临时文件系统,具有以下优点: 高速存储: 数据存储在内存中,读写速度极快。 动态大小: 根据实际使用情况动态分配内存,不会固定占用资源。 减少写入: 适合存储临时文件和日志,显著减少对闪存的写入操作。 如何配置 tmpfs 1.1 编辑 /etc/fstab 文件 打开终端并输入: sudo nano /etc/fstab 添加以下行以创建 tmpfs 挂载点: tmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0 tmpfs /var/log tmpfs defaults,noatime,mode=0755 0 0 1.2 挂载 tmpfs 保存文件后,运行以下命令使更改生效: sudo mount -a 1.3 验证挂载 使用以下命令确认 tmpfs 是否成功挂载: df -h 您应该能看到类似于 /tmp 和 /var/log 的 tmpfs 挂载点。 1.4 设置自动复制日志到 tmpfs 为了在系统启动时自动将日志复制到 tmpfs,我们需要修改 /etc/rc.local 文件: a. 创建一个目录来存储持久化的日志: sudo mkdir -p /var/log.hdd sudo cp -a /var/log/* /var/log.hdd/ b. 编辑 /etc/rc.local 文件: sudo nano /etc/rc.local c. 在文件中添加以下内容: #!/bin/sh -e # 复制日志文件到 tmpfs cp -a /var/log.hdd/* /var/log/ exit 0 d. 确保 rc.local 文件具有执行权限: sudo chmod +x /etc/rc.local 2. 关闭…

    Permanent link to “移动介质上的Linux:使用 tmpfs、关闭 atime 以延长 SD 卡或优盘的使用寿命”
  • 网友语录 - 第2期

    世界上没有叛逆的孩子,只有不被理解的孩子。 点赞订阅虽然好 自由思考价更高 别人喜欢你,那是你给他的福利,别人不喜欢你,那是你给他的惩罚。哈哈哈记住了。 产品是丰富的,营销更是过量的。比起研究多少购物攻略,更核心的步骤是确定自己的需求和预算,越明确越坚持越好。“筛选”比“比较”更简单。 朱丽叶 名字有那么重要吗? 把玫瑰叫成别的名字,它还是有芬芳香气。 不要浪费你的无知。当你对一门知识毫无所知时,最容易问出简单而重要的问题。 一旦你习惯了某种现象或事物,认为它是理所当然时,思维就不知不觉受到了限制。 -- David Kohn ayaduji:恨是很没意义的事,因为大家都会死。还是抓紧时间爱吧,可爱的东西那么多,时间根本不够啊 如果你无须转译就能直接理解另一种语言及构筑其上的世界观,能欣赏它们的效用与美感,那么你往往就不那么容易偏执盲从,不那么容易把非你族类全都看作妖魔鬼怪。《语言塑造人类思维》 性别代词特别容易产生隐含的联想,影响人们对自己和他人的认知。 拥有另一种语言,就是拥有另一个灵魂。 ——查理大帝 旧时明月照无眠 人总是透过语言的lens在观察/理解世界,因此多掌握一门语言也意味着多一个不同的看世界的lens,而这是翻译软件或者AI所无法做到的,因为翻译完成的那一刻,原始语言的维度就坍塌了。人使用翻译软件/AI是problem-solving,而人学习语言是generative的。反过来,禁止使用原本的语言一向是settler colonialism的assimilation agenda上最高优先级的任务之一。 旧时明月照无眠 精力/energy并不是homogenous,而是由许多适配不同活动/task的不同种类精力组合在一起的。比如每天有一些可以全神贯注的精力,也有一些“按部就班/autopilot”的精力,有些事情只能用专注精力去处理,但有些可以fit进autopilot精力里;然而即便是专注精力也未必能全部用来做比较重要的decision-making,但消耗完了decision-making的容量可能还剩一些可以探索/学新东西的或者是做planning的。 ...…

    Permanent link to “网友语录 - 第2期”
  • How to Enable…

    TL;DR If your user-level systemd service on Ubuntu doesn't start automatically after a reboot, enable it with systemctl --user enable HappyNotes.Api.service. If you encounter an error about an existing symlink, remove it first. To allow the service to run without an active user session, enable lingering using loginctl enable-linger <username>. Finally, ensure your service file has the correct [Install] section and reboot to check if the service starts as expected. The Problem After configuring a user-level service with systemd, you might find that it remains inactive after rebooting your server. For example, you may run the command: systemctl --user status HappyNotes.Api.service And see output indicating that the service is inactive (dead) and disabled. Solution Steps Enable the Service: First, ensure your service is enabled to start at boot: systemctl --user enable HappyNotes.Api.service If you encounter an error stating that the service is already linked, you may need to…

    Permanent link to “How to Enable User-Level Systemd Services to Start Automatically on Ubuntu After Reboot”
  • Docker Volumes in…

    When working with Docker containers in production, understanding volume management is crucial. This guide will help you make informed decisions about when to use named volumes versus bind mounts (directory mapping). TL;DR Use named volumes for persistent data (databases, application state) Use bind mounts for config files and development Combine both in production for optimal setup Understanding the Basics Named Volumes volumes: - postgres_data:/var/lib/postgresql/data Docker manages these volumes internally. Think of them as "black boxes" that Docker handles for you. Bind Mounts (Directory Mapping) volumes: - ./config:/etc/app/config You manage these directories directly on your host machine. When to Use What? Use Named Volumes For: Database storage Application state Generated assets Any data that needs persistence but not direct access Benefits: Managed by Docker Better performance Automatic permissions handling Easier backups Portable across environments Built-in volume…

    Permanent link to “Docker Volumes in Production: A Practical Guide to Named Volumes vs Bind Mounts”
  • How to Use `sed`…

    When using sed on Windows, you might run into unexpected behavior, especially with line endings. If you're editing files with Windows-style line endings (\r\n), sed can unintentionally modify them, causing issues with tools like git diff. Here’s how you can use sed effectively on Windows without breaking your line endings. The Problem: Unexpected \r\n to \n Conversion On Windows, text files usually use \r\n (carriage return + line feed) as line endings. However, sed, depending on its mode, may treat these as Unix-style \n line endings, removing the \r and leading to issues like: Files appearing changed when they shouldn’t. Tools like git diff showing extra changes due to the altered line endings. Solution: Use sed -b to Prevent Line Ending Conversion To avoid this, you need to force sed to operate in binary mode, which prevents automatic conversion of line endings. Example: sed -b 's/old_text/new_text/' filename.txt In this example: The -b flag ensures sed works in binary mode,…

    Permanent link to “How to Use `sed` for Replacements on Windows Without Breaking Line Endings”
  • 网友语录 - 第1期

    绝对支配别人会产生大量的多巴胺,比吸毒还 high,而且成瘾。不要給他人這樣的機會。 不直接创造财富的群体,如果始终处在分配财富的有利位置上,而创造财富的群体又无法制约他们,那么其长期结果一定是经济停滞与社会衰败。 一张图说清英文地理术语 除了生病以外,所有的痛苦都是价值观带来的。 哈耶克说:金钱是人类发明的最伟大的自由工具。只有金钱会向穷人开放,而权力不会; 愿意放弃自由来换取保障的人,最终既得不到自由,也得不到保障; 一个富人得势的世界,总比一个只有得势的人才能富有的世界要好得多; 如果一个人不需要服从任何人,只需服从法律,那么他就是自由的; 为什么一些问题永远得不到解决?因为解决问题的人,正是制造问题的人; 如果允许人类自由迁徒,那人流的方向就是文明的方向。 米福根:恨可以登堂入室,爱却需要躲藏。 过去,我们将已知最耐用的材料用于整座建筑,比如说花岗岩石块,其成果仍令当代人赞赏、惊叹。但我们却几乎不再模仿这种行为,因为石料的采集、切割、运输和搭建都极其考验耐心,而耐心正是我们不再具备的品质。摘自《没有我们的世界》 网摘:"与其担心宏观经济,不如关注自己。你对自己生活的影响,往往比宏观经济对你的影响大得多。" 公司裁员肯定会对一个人产生影响,但是它决定不了你的未来,你自己才是最大的影响因素。 世界最大对冲基金"桥水基金"创始人达里奥,说过一句话,可以用在这里:"如果你忧心忡忡,那是不必要的;如果你毫不担心,那么你需要担心。" TNT007: 我可能比较老派,认为如果恋爱还需要技巧的话,那就不是爱情。爱情是双向的不可自抑的。 小青: I am who I am becoming. 网摘:作家兼冥想老师大卫·凯恩(David Cain)鼓励他的学生别当“好天气的冥想者”。同样,你也不想成为一名努力与否全凭心情好坏的运动员、作家,等等。当一个习惯对你来说真正重要时,你必须愿意在任何心情下坚持下去。专业人士不会因自己心情不好而改变行动的时间表。他们可能享受不到乐趣,但是他们仍能做到坚持不懈。

    Permanent link to “网友语录 - 第1期”
  • 书摘:成为乔布斯

    《成为乔布斯》 作者:布伦特·施兰德 里克·特策利 175个笔记 我的点评: ◆ 2016/10/15 认为好看 虽然不可能读了这本书就能真的“成为乔布斯”,成为更好的自己却是非常可能的。要成为一个更出色的人,直率,不拐弯抹角比世故或者中庸更有价值,更容易结交到志同道合的朋友。真想给这本书打一百颗星。 前言 ◆ 他总是喜欢对别人的生活方式指手画脚,劝了我好几年让我戒烟。 ◆ 是如何改变的,在谁的影响下做出了改变,以及他又是如何将心得体会运用到公司的运作中去的。 ◆ 他深信自己的工作所创造的价值,也希望身边的好友能够和他一样,深信他们的工作所创造的价值。 第一章 安拉的花园 ◆ 对于一个橱柜来说,别人看不到的底面与表面的抛光一样重要;对于一辆雪佛兰汽车来说,别人看不到的刹车片和汽车的油漆一样重要。 ◆ 生命常常被比喻成一条奔流不息的河,世间万物、每个个体都处于永恒的变动中。以这样的世界观来看,追求完美也是一个渐进持续的过程,永远都不可能彻底完成。 ◆ 他的脾气如果使用得当,会是非常有效的团队激励工具。 第二章 “我不想当商人” ◆ 财务数据是最好的营销工具 ◆ 2016/09/30发表想法 任何行业都是如此 原文:出色的财务数据是引起人们关注的最好方式,在电脑行业尤其如此。 ◆ 至繁归于至简 第三章 突破与崩塌 ◆ 一点就通的老板和怎么讲都讲不明白的老板是不同的。 ◆ 你得经过七层管理层才能找到工程师。一家技术公司变成这样是很危险的。 …more

    Permanent link to “书摘:成为乔布斯”
  • AI Prompt for Git…

    Analyze the following code changes and generate a concise, meaningful git commit message that: 1. Summarizes the main purpose or impact of the changes 2. Is no longer than 100 characters (150 characters maximum if absolutely necessary) 3. Uses present tense and imperative mood (e.g., "Add feature" not "Added feature") 4. Focuses on the "what" and "why" rather than the "how" Provide ONLY the commit message itself, without any additional text, explanations, or formatting. Code changes: I have used it in my bash script ci and it works very well! ...

    Permanent link to “AI Prompt for Git Commit Messages”
  • 书摘:掌控习惯

    《掌控习惯:如何养成好习惯并戒除坏习惯(《原子习惯》中文版)(新版)》 詹姆斯·克利尔 116个笔记 我是如何了解习惯的 ◆ 我的同龄人熬夜玩电子游戏时,我养成了良好的睡眠习惯,每天晚上都早早上床睡觉。 ◆ 只要你愿意坚持下去,起初看似微小和不起眼的变化,会随着岁月的积累,复合成显著的结果。 第1章 微习惯的惊人力量 ◆ 在你所做的每一件事上寻求哪怕是极细微的进步 ◆ 边际收益的聚合 第2章 你的习惯如何塑造你的身份(反之亦然) ◆ 在我开始写作生涯的最初几年,我每周一和周四都会发表一篇新文章。随着证据的积累,我的作家身份也在增强。我一开始不是作家。我的习惯使我变成了作家。 ◆ 2022/05/23发表想法 道理都懂,接下来就看实践了 原文:我们不可能仅凭打个响指并做出决定,就能立刻变成全新的人。我们的改变需要一点一滴、日复一日、习惯再习惯的积累。 …more

    Permanent link to “书摘:掌控习惯”
  • 书摘:解码40亿年生命史

    作者:尼尔 舒宾 (Neil Shubin) 2024-09-18 19:24:47 没有什么事情始于你认为它开始的时候。 2024-09-23 21:49:52 生物创新从来不是伴随着与之相关的巨大转变而出现的。羽毛并不是出现在飞行演化的过程中,肺和附肢也不是出现在脊椎动物登上陆地的过程中。更重要的是,如果没有这些创新,生命史上的重大变革以及其他类似的转变将不可能发生。生命史上的重大转变不必等待许多创新同时出现,而是通过给已有的结构赋予新的功能来实现的。早在很久之前,创新的前体就已经存在了。事情并非始于你认为它们开始的时候。 2024-09-25 10:23:02 如果林奈认为蝾螈是造物的底线,那么其他人则将它们视为原始的,甚至是有魔法的生物。从老普林尼到奥古斯丁,哲学家将蝾螈想象成从熔岩、地狱或火焰中诞生的生物。对奥古斯丁而言,蝾螈是有人真的因诅咒而葬身火海的切实证据。奥古斯丁的观点源于一种说法,即蝾螈能抵抗火焰或从篝火中涌出。这些超能力可能反映出它们的某些生物学特征。正如水族馆管理员和蝾螈爱好者所知,一些种类的蝾螈喜欢藏身在腐烂的原木底面。在奥古斯丁的年代,人们捡拾柴火的时候无意间捡到了这些藏着蝾螈的原木。当他们点燃原木后看到蝾螈从里面跑出来时,无疑会惊呼“这是什么邪恶的东西”。 2024-09-25 11:15:21 你可以在蛋壳上切一个洞,让光线从蛋的侧面射入,然后将蛋放在显微镜下观察里面的胚胎。胚胎开始于蛋黄顶部的一小团白色细胞。时间一天天过去,胚胎逐渐长大,出现各种可以识别的标志——头、尾、背部、翅膀和腿。这个过程感觉就像是一场精心编写的舞剧。最初,受精卵经历了一系列分裂,一个细胞变成两个,两个变成四个,四个变成八个,依此类推。随着细胞增殖,胚胎最终变成了一个细胞团。几天后,胚胎从一个空心球变成简单的细胞盘,周围的细胞负责保护和提供营养,并为胚胎发育创造合适的环境。最终,一个完整的生物体会从这个简单的细胞盘中孕育而出 注: 这不就是操作系统自举的过程吗?! 2024-09-25 16:42:51…

    Permanent link to “书摘:解码40亿年生命史”
  • How to Avoid SSH's…

    If you're tired of seeing the "Are you sure you want to continue connecting (yes/no/[fingerprint])?" prompt every time you SSH into a new server, you're not alone. This security feature, while important, can be a bit of a nuisance for system administrators and developers who frequently connect to new machines. This is especially true when they wish to run a remote command on a newly trusted machine. Let's explore how to streamline this process without completely compromising security. Understanding the Prompt First, it's important to understand why this prompt appears. It's a security measure designed to protect you from man-in-the-middle attacks by verifying the authenticity of the server you're connecting to. However, in controlled environments or for non-critical systems, you might want to bypass this prompt. The Quick Fix: StrictHostKeyChecking One simple way to avoid this prompt is by using the StrictHostKeyChecking option. You can add this to your SSH command like…

    Permanent link to “How to Avoid SSH's "Are you sure you want to continue connecting?" Prompt”
  • Condtionally…

    IF statement won't work directly in standard SQL scripts outside of a stored procedure or function in MySQL. Thus, we will have to use a different approach using CREATE PROCEDURE to encapsulate the logic. Here’s an example that you can reference to create a stored procedure to safely make the changes: DELIMITER // CREATE PROCEDURE AdjustFilesTable() BEGIN -- Change FileExt from char(4) to char(5) if it exists IF (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Files' AND COLUMN_NAME = 'FileExt') > 0 THEN SET @sql = 'ALTER TABLE Files CHANGE COLUMN FileExt FileExt CHAR(5) NOT NULL'; PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END IF; -- Rename CreateAt to CreatedAt if it exists IF (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Files' AND COLUMN_NAME = 'CreateAt') > 0 THEN SET @sql = 'ALTER TABLE Files CHANGE COLUMN CreateAt CreatedAt BIGINT DEFAULT NULL'; PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;…

    Permanent link to “Condtionally execute adjustment statements on MySQL”
  • 使用 rsync 增量备份文件

    通常 A 机器和 B 机器已经在 ~/.ssh/config 中定义并建立了信任关系,因此我们可以直接使用主机别名,而不需要使用 user@B_machine 的方式。 sync_files.sh 脚本 #!/bin/bash # 定义源和目标目录 SOURCE_DIR="/data/files/" DEST_DIR="B_machine:~/backups/A_machine/data/files" # 执行 rsync 命令 rsync -av --exclude='tmp/' "$SOURCE_DIR" "$DEST_DIR" 确保脚本有执行权限: chmod +x sync_files.sh 使用 cron 设置每五分钟执行一次该脚本: crontab -e 添加: */5 * * * * /path/to/sync_files.sh

    Permanent link to “使用 rsync 增量备份文件”
  • /var/log/journal…

    在 Linux 系统上,/var/log/journal 目录通常用来存储系统日志。如果这个目录占用了过多的空间,可以通过以下几种方法来管理和限制日志的大小: 1. 修改 journald 配置 你可以通过修改 journald 的配置文件来设置日志的最大大小和保留时间: 打开终端。 编辑 journald 配置文件: sudo nano /etc/systemd/journald.conf 在文件中添加或修改以下配置项: [Journal] SystemMaxUse=500M SystemKeepFree=100M SystemMaxFileSize=50M SystemMaxFiles=10 这些选项的含义如下: SystemMaxUse:限制日志的总大小。 SystemKeepFree:保留的磁盘空间。 SystemMaxFileSize:每个日志文件的最大大小。 SystemMaxFiles:最大日志文件数。 保存文件并退出编辑器。 重新启动 journald 服务以应用更改: sudo systemctl restart systemd-journald 2. 清理现有日志 如果你想立即释放一些空间,可以手动清理旧的日志文件: sudo journalctl --vacuum-size=500M 这条命令会将日志文件的总大小限制在 500MB。 3. 定期清理日志 你可以使用 cron 任务来定期清理日志。例如,可以设置一个每天执行的任务来保持日志的大小在一个合理的范围内。 打开 cron 编辑器: crontab -e 添加以下行以每天清理日志: 0 0 * * * /usr/bin/journalctl --vacuum-time=7d 这样设置后,系统将每天清理超过 7 天的日志。

    Permanent link to “/var/log/journal 占了2.8GB,有没有办法一劳永逸的解决这个问题?”
  • Set Up a 2GB Swap…

    Running a small VPS with limited memory can be frustrating, especially when processes get killed due to low memory. A quick and easy way to help prevent this is by setting up a swap file. This script will Checks if swap already exists on the remote machine. If not, it creates a 2GB swap file and enables it. Adds the swap file to /etc/fstab to make it permanent. The script uses scp to copy a temporary script to the remote machine and ssh to execute it. Here’s the full script: #!/bin/bash # Check if machine name is provided if [ -z "$1" ]; then echo "Usage: $0 <machine-name>" exit 1 fi REMOTE_MACHINE=$1 SWAPFILE=/swapfile SIZE=2048 # Generate remote script content REMOTE_SCRIPT=$(cat <<EOF #!/bin/bash if swapon --show | grep -q "$SWAPFILE"; then echo "Swap is already enabled on $SWAPFILE" exit 0 fi sudo dd if=/dev/zero of=$SWAPFILE bs=1M count=$SIZE sudo chmod 600 $SWAPFILE sudo mkswap $SWAPFILE sudo swapon $SWAPFILE if ! grep -q…

    Permanent link to “Set Up a 2GB Swap on a Remote VPS with a Simple Script”
  • 书摘:布达佩斯往事

    《布达佩斯往事:冷战时期一个东欧家庭的秘密档案》 卡蒂·马顿 13个笔记 我的点评: 2022/04/30 认为好看 我不知道为什么会有那么多人给这样一本好书打低分,这是不公允的。今天的年轻人可能不会理解,做一个正直的人是需要极大的勇气的,特别是在一个极权国家。幸运的是,随着苏联的解体,今天的匈牙利和东欧诸国的人们已经重新沐浴在民主自由的空气里十余年了。无他,我只希望在不远的将来… ◆ 2022/04/25发表想法 这… 原文:父亲经常为她们草拟要交给秘密警察的报告。 ◆ 2022/04/25发表想法 😄 原文:我真佩服父亲,他一定很忙,因为他同时要为秘密警察、美联社、合众社三家写稿。 ◆ 2022/04/25发表想法 Cannot agree with this view anymore. I am ashamed that my homeland is not great yet. 原文:如果害怕人民的不同意见,如果视异议为犯罪行为,如果将不赞同高官的人打入监狱,一个国家就不能自称是伟大的。 ◆ 2022/04/26发表想法 此去经年,谁知竟是永诀 原文:1954年夏天,亲爱的祖父和我在告别午餐上,他将移民去澳大利亚。我永远没有再见到他——也永远没有将他忘怀。 ◆ 2022/04/30发表想法 虽然此处原词肯定是drama,但此处翻译为绯闻或者八卦甚至“烂事儿”都比“戏剧”好。 原文:戏剧 ◆ 2022/04/30发表想法 很多时候女人都比男人更坚强,这并非歧视男人,我本人就是男人。这是我个人的观察。 原文:自由世界的强大朋友在为我们的释放努力。我对他们的最终胜利,抱有百分之一百的信心。 …more

    Permanent link to “书摘:布达佩斯往事”
  • 书摘:月亮和六便士

    作者:毛姆 40个点评 我 2022/03/23 认为好看 不管别人怎么看,我喜欢他,向往他那样的的生活。他表现出的“冷酷无情”是当今畸形的价值观给出的。他是独立的,自由的,他希望自己身边的人也向他一样独立,一样自由。然而这要求实在是太高了。所以那些达不到这一要求的人,就会觉得他冷酷和自私。我喜欢他,向往他那样的生活。而且,这本书还推荐了一个人间天堂:大溪地。此生我一定要去一次。 ◆ 艺术是人人都懂的语言,它传递的感情是最重要的。把艺术看成是专业人士才可以解读的技巧,实在是谬论。 …more

    Permanent link to “书摘:月亮和六便士”
  • 书摘:鱼什么都知道

    作者:乔纳森·巴尔科姆 我的点评: 2022/05/08 认为好看 万物皆有灵。鱼吃鱼,人吃鱼,鱼吃人,有的鸟吃鱼,有的鱼吃鸟。个体为获得食物而捕猎是大自然的规则,是道德的。商业捕捞以盈利为目标,不值得鼓励。但….人类这么懒,肯定还会继续买鱼吃,所以商业鱼类有一天被灭绝也不是不可能的。我们人类多能折腾啊,地球之癌。 ◆ 我们需要记住的是,所有生物都由单细胞发展而来。 ◆ 2022/05/07发表想法 大自然是如此神奇 原文:皱鳃鲨的怀孕时间超过三年 ◆ 实现中枢神经系统的保温 ◆ 2022/05/07发表想法 它是什么?现存体型最大的陆上哺乳动物为非洲草原象,肩高达3.96米(13.0英尺),体重约可达10.4 t(11.5 short ton)。 已灭绝体型最大的陆上哺乳动物则认为是巨犀,为现存犀牛的近亲,推估肩高可达4.8米(15.7英尺),体长超过7.4米(24.3英尺),体重可达17公吨。 原文:最大的陆生哺乳动物也未能免于灭绝 ◆ 这条名为弗彻巴的鱼会在固定的喂食时间,衔着卵石敲击鱼缸的墙壁。 ◆ 大型的板鳃亚纲鱼有着鱼类中最大的大脑 ◆ 大部分鱼都是社会动物 ◆ 2022/05/07发表想法 和人类的图书馆 原文:在动物世界中,经由文化传递的特征包括乌鸦制造工具的行为、大象对迁徙路线的选择、虎鲸的方言、羚羊的公共求偶地等。 ◆ 鱼肉是所有食物中污染最严重的。 ◆ 谴责商业捕捞行业的残忍和浪费非常容易,但消费者也必须承认自己需要承担一定的责任。在任何建立在供需关系之上的经济体中,需求都是驱动供给引擎的燃料。人类在吃鱼的时候,也助长了渔猎行为。 ◆ 2000年以来,美国至少有18个城市的地方法律将动物的法律地位从“财产”更改为“伴侣”。如果你恰好住在这些地方,就会被官方认定为600万“动物守护者”之一。 ◆ 如今,在欧洲部分地区,在空荡荡的鱼缸中养一条孤零零的金鱼已经是非法行为了,因为在自然界中的金鱼,是有几十年寿命的社会性动物。 -- 来自微信读书

    Permanent link to “书摘:鱼什么都知道”
  • 书摘:当呼吸化为空气

    作者:保罗·卡拉尼什 这本书我读了两遍,一遍在两年前,一边在今天。 与保罗的无限对话 ◆ 科技发展日新月异,无论是临床还是研究工作,一旦怠惰,很快就会被新科技的潮流淹没。 ◆ 三十五岁,体重莫名其妙地下降,初发性背痛,那明显该选C——癌症。 ◆ 十岁的时候,她就让我读《1984》 ◆ 思想不过就是大脑运转的产物。 ◆ 2022/03/18发表想法 不经意间读的一本书很可能就改变了一个人的人生轨迹,就是这么神奇 原文:那天晚上,在自己房间里,我打开已经翻来覆去看过好几十遍的红色斯坦福课程总目录,手里拿着一支荧光笔。之前我已经标记了很多文学课程。现在,我开始寻找生物和神经系统科学的相关课程了。 ◆ 我学习的最大动力,不是成就感,而是一种求知欲,我非常认真地想要探究,是什么让人类的生命充满意义? ◆ 猕猴已经有了初级的文化形式 ◆ 我要么去研究生命的意义,要么就去亲自经历和体验生命的意义。 ◆ 2022/03/18发表想法 这个指导老师太可爱了 原文:我跟他说了自己的暑假计划以后,他完全变了个人:双目圆睁,脸迅速涨红了,开始唾沫飞溅地教训我。 “什么?”他说,“你以后是想当科学家还是……厨子?” ◆ 教授告诉我们,不要再“尸体尸体”地叫,最好说“捐献者”。 ◆ 从这张不知从何而来的“练习用”心电图可以看出,这位病人已经不在人世了。纸上这些弯弯曲曲的线条,不只是简单的线条,还是从心颤再到心跳停止的全过程,这些会让看懂的人心痛落泪 ◆ 2022/03/18发表想法 这本书的英文名字叫 How we die, 作者还写了一本 How we live 原文:我们如何死去 ◆ “这你就接受不了了?”她说,“很多母亲明知胎死腹中,还是要经历分娩和生产。你想象得到吗?这些人至少还有过希望。” …more

    Permanent link to “书摘:当呼吸化为空气”

September 2024

  • 旧文搬运:《吴法宪回忆录-岁月艰难》读后

    这篇博文是(2011年)从新浪博客迁过来的。新浪的编辑还有点人味,这篇没有彻底给删掉,给搁回收站了。转到这儿,看看点点是不是开明一点。 这本书是阮一峰在他的2010年终总结博客里推荐的。 读这本书之前,我对吴法宪的了解仅限于以往看到听到的一些官方说法,四人帮的帮凶什么的。对这本书一开始也没大重视,一个大老粗,文字能好到哪里去呢?不过既然阮一峰会推荐,这书肯定有可取之处。 本着看闲书的态度找到这本书的电子版,扔到kindle里,准备有一搭没一搭的看。 这书篇幅挺大,有八十余万字。一周前开了头,看了十来页,我就知道这本书我一定会全部读完了。 …more

    Permanent link to “旧文搬运:《吴法宪回忆录-岁月艰难》读后”
  • 旧文搬运:我的电子书

    本文最初发表在今天已经死掉的点点博客。 我的第一个移动读书设备是黑莓8310。在那小小的屏幕上我读完了厚厚的一本《代码大全》。 后来买了吹的牛哄哄的号称读PDF多好多好的歌美S6000。屁,操作之慢让我忍不住想起我那只扔在一边的N73手机,阅读时间短不说,电量指示还超不准。读着读着,不定啥时候突然就没电了。 扔一边了,真可惜了8个G的容量。 然后就买了kindle3。刷了多看系统,这次看PDF真的爽了。更爽的是待机时间,充一次电能看两个礼拜。老早就听说这玩意屏不结实,所以入手大半年来,一直小心着小心着,生怕它那脆弱的小屏坏掉。然而,前几天悲剧还是发生了:要和儿子出去玩,我把kindle装包里,包跨在我胳膊上。我为了帮他找鞋子就趴在地上往沙发底下瞧,鞋子是找到了,可起身才发现包在我膝盖底下。啊呀呀,叫也没用,kindle3屏幕果然坏掉。在等待换屏的日子里,顺理成章儿子的iPAD成了暂时的替代。 原来iPAD也是看书利器。虽然最初沉甸甸地,好象有点受不了。可连着带了几天之后发现竟然有些适应了。反应敏捷,操控一流,彩色,大屏,十几小时的阅读时间,除了一点点反光让人稍微不爽,在习惯了iPAD的重量之后,我竟然有些爱不释手了。 要不要就此让那个kindle3成为往事?嗯,这事儿我看行。 2011/06/20

    Permanent link to “旧文搬运:我的电子书”
  • One day or day one.…

    我想为我的 One Day Telegram 频道找一个合适在头像, 东搜西搜, 发现了这样一句格言: One day or day one. It is your decision. 或者说 One day or day one. You decide. 这里 One day 指将来某天,暗示一种不确定的等待或者拖延。有一天我会做,等条件成熟了我就做。而 day one 指采取行动的第一天,意味着立即开始,不再等待。 选择权在你,是明日复明日,还是择日不如撞日,今天就开始行动。 愿大家都成为“今天就开始行动”一族。

    Permanent link to “One day or day one. It is your decision”
  • [solution]…

    ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT false RUN apk add --no-cache icu-libs tzdata Reference By the way, my devops colleague told me if you can, changing the windows time zone id with its standard equivalent is the more preferred way. He said "its not good to set that environment variable to false"

    Permanent link to “[solution] mcr.microsoft.com/dotnet/aspnet:8.0-alpine couldn't recognize windows time zone ID”
  • How to Skip a…

    When working with Postman to automate API testing, you might encounter scenarios where you want to conditionally skip the execution of subsequent requests in a collection. This can be useful if a certain condition isn't met in your API responses. Here's a guide on how to achieve this using Postman's scripting capabilities. Scenario Imagine you have a collection where the first request returns a response like this: { "content": "True", "statusCode": 200, "message": "Global value got from DbConfig!" } You want to skip all subsequent requests if the content field is "False". Step-by-Step Guide Set Up Your Collection: Ensure your collection is organized with the request you want to evaluate placed at the beginning. Write a Post-Request Script: In the test script section of the first request, you'll write a script to check the content field and decide whether to continue the collection run. // Parse the response let response =…

    Permanent link to “How to Skip a Collection Run in Postman Based on Response Conditions”

August 2024

  • 详解:import { ref,…

    一个朋友说 Gemini最近的进步已经挺大了,于是我就试验了一下。 我问Gemini:你能否用简洁的汉语详细解释一下import { ref, onMounted, watch } from 'vue'这一语句import的这三个对象?它们是什么,做什么用,好的实践是什么? Gemini的回答令我非常满意,因此我把它发表在这里。它的回答是: 好的,我来详细解释一下这段代码中导入的三个对象: import { ref, onMounted, watch } from 'vue' 解释: import: 这是 JavaScript 中的导入语句,用于从其他模块(这里就是 Vue.js)中引入需要的功能。 想象一下,你在搭建积木,import 就相当于你从积木盒里拿出特定的积木块。 ref, onMounted, watch: 这些都是 Vue.js 提供的三个核心功能: ref: 作用: 创建一个响应式的引用。 比喻: 想象一个盒子,你把一个数据放进去,这个盒子就变成了一个 ref。当盒子里面的数据发生变化时,Vue 会自动追踪到,并触发相应的更新。 使用场景: 用于创建响应式的基本数据,比如一个计数器、一个输入框的值等。 onMounted: 作用: 在组件挂载到 DOM 后执行一次回调函数。 比喻: 就像一个新房子建好了,你就可以搬进去开始装修了。onMounted 就是在你搬进去之后执行的第一个动作,比如打开窗户通风。 使用场景: 用于执行一些初始化操作,比如获取数据、设置定时器等。 watch: 作用: 监听一个值的改变,并在值改变时执行回调函数。 比喻: 就像你设置了一个监控摄像头,一旦监控到有物体移动,就会触发报警。watch 就是这个监控摄像头,它会持续监控一个值,一旦值发生变化,就会执行你设定的操作。 使用场景: 用于实现一些复杂的逻辑,比如根据数据的变化动态更新视图、进行表单验证等。 总结: ref 用于创建响应式数据。 onMounted 用于在组件挂载后执行初始化操作。 watch 用于监听数据的变化并执行相应的操作。 好的实践: 合理使用 ref: 不要过度使用 ref,只对需要响应式的数据进行包裹。 在 onMounted 中进行异步操作: 将获取数据、设置定时器等异步操作放在 onMounted 中,确保组件已经挂载到 DOM 中。…

    Permanent link to “详解:import { ref, onMounted, watch } from 'vue'”
  • HappyNotes Privacy…

    HappyNotes is committed to protecting your privacy and ensuring the security of your personal information. This privacy policy explains how we collect, use, and safeguard your data when you use our note-taking application. Information We Collect Personal Information: Account details (email address, username) for registration purposes User-generated content (notes, tags) Usage Information: Device information (operating system, device type) App usage statistics (features used, frequency of use) Cloud Storage: We offer cloud storage to sync your notes across devices. Your notes are encrypted in transit and at rest. How We Use Your Information We use the collected information to: Provide and improve our services Sync your notes across devices Analyze app usage to enhance user experience Communicate important updates Data Sharing and Third Parties Telegram Sync: If you choose to sync notes with Telegram, your notes will be shared with Telegram according to your specified rules. Please…

    Permanent link to “HappyNotes Privacy Policy”
  • 惠勒延迟选择实验:之后的选择真得能够改…

    惠勒延迟选择实验(Wheeler's Delayed Choice Experiment)是一个量子力学的思想实验,旨在探讨测量对量子系统的影响,尤其是在我们“选择”测量的时刻与量子系统的历史之间的关系。这个实验的结果挑战了我们对因果关系和时间的传统理解,尤其是在量子层面上。 实验背景 首先,了解双缝实验(Double-Slit Experiment)是理解惠勒实验的基础。在经典的双缝实验中,单个粒子(如光子或电子)通过两个狭缝并在屏幕上形成干涉图样。这显示粒子似乎像波一样通过了两条路径。但如果我们在狭缝处放置探测器来测量粒子通过哪一个狭缝,干涉图样会消失,粒子表现得像个经典粒子,只通过了一条路径。 惠勒的延迟选择实验 惠勒延迟选择实验则在此基础上提出了一个令人困惑的思想实验:如果我们在粒子通过双缝后,甚至在它接近屏幕时才决定是否测量它通过哪条缝会怎样? 实验的核心思想是: 光子或粒子先通过双缝,接着才进入实验者是否测量的选择区域。 如果我们选择不测量路径信息,光子将像波一样表现,形成干涉图样。 如果我们选择测量路径信息,光子则表现为粒子,干涉图样消失。 在延迟选择实验中,实验者是在粒子已经通过双缝后才决定是否测量路径信息。令人困惑的是,实验结果仍然符合经典双缝实验的规律:如果我们“延迟”选择测量路径,粒子依旧表现为粒子;如果我们不选择测量,粒子仍然表现为波。 困惑的源头:现在的选择影响过去? 这个实验结果带来的困惑是:我们的“延迟选择”似乎影响了粒子过去的行为。也就是说,光子在通过双缝时“知道”我们未来会不会测量它的路径,从而决定以波的形式通过两个缝,还是以粒子的形式通过其中一个缝。 然而,这种解释仅仅是表面现象。量子力学的本质不是粒子“提前知道”了什么,而是测量本身在量子层面上扮演了一个创造性角色。也就是说,量子的状态并不是在我们测量之前就固定的,而是测量行为本身决定了量子状态的表现。 关键点 量子叠加态:在没有测量之前,粒子处于一种叠加态,既是波也是粒子,既通过了两条路径,也只通过了一条路径。测量行为使叠加态“坍缩”到一个确定的状态。 因果关系:在经典物理学中,因果关系是线性的,即因在前,果在后。但在量子力学中,因果关系不像我们习惯理解的那样简单,测量的时间顺序并不能简单地被理解为影响事件发生的唯一因素。…

    Permanent link to “惠勒延迟选择实验:之后的选择真得能够改变之前的决定吗?”
  • My telegram…

    The following are my Telegram channels/public groups, feel free to subscribe them. Happy Notes features and tips - https://t.me/happynotes_tips - for Happy Notes New features, new tips, and other related topics Happy Notes discussion - https://t.me/happynotes_support A support group for Happy Notes users A record about my migration to New Zealand - https://t.me/migrate2nz 网友语录 - https://t.me/cyberfriendsay You can also visit it by https://cyberfriendsay.shukebeta.com which supports RSS. ONE DAY or DAY ONE, YOU DECIDE - https://t.me/dailyrecord - now it is synced by my public notes that are written on HappyNotes app - you can also visit it by https://oneday.shukebeta.com which supports RSS

    Permanent link to “My telegram channels: welcome to subscribe”
  • [Solution] The…

    The error occurs because AppBar expects a widget that implements the PreferredSizeWidget interface, but Consumer<NoteModel> does not directly implement this interface. To solve this, you need to return an AppBar from within the Consumer builder method. Here’s how you can do it: Scaffold( appBar: PreferredSize( preferredSize: Size.fromHeight(kToolbarHeight), child: Consumer<NoteModel>( builder: (context, noteModel, child) { return AppBar( title: Text( 'Your Title', style: TextStyle( color: noteModel.isPrivate ? Colors.red : Colors.green, ), ), ); }, ), ), body: // Your other widgets, ); In this approach, I wrapped the Consumer<NoteModel> inside a PreferredSize widget to ensure it adheres to the PreferredSizeWidget interface required by appBar. This should resolve the error while allowing you to update only the AppBar based on changes in your NoteModel. Glory to ChatGPT!

    Permanent link to “[Solution] The argument type 'Consumer' can't be assigned to the parameter type 'PreferredSizeWidget?'.”
  • Build command for…

    set -x && if cd flutter; then git pull && cd .. ; else git clone https://github.com/flutter/flutter.git; (cd flutter && git fetch --tags && git checkout 3.22.3); fi && ls && flutter/bin/flutter doctor && flutter/bin/flutter clean && flutter/bin/flutter config --enable-web && cp .env.production .env && sed -i "s/VERSION_PLACEHOLDER/`git rev-parse --short HEAD`/" .env && flutter/bin/flutter build web --web-renderer html --base-href="/" --release

    Permanent link to “Build command for deploying your flutter web app to cloudflare pages”
  • C#…

    In C#, both FirstOrDefault and SingleOrDefault are LINQ methods that operate on collections, but they serve different purposes: FirstOrDefault Purpose: Returns the first element in a collection that satisfies a specified condition, or the default value for the type if no such element is found. Behavior: If the collection contains multiple elements that satisfy the condition, it returns the first one. If no elements satisfy the condition, it returns the default value (null for reference types, 0 for numeric types, etc.). Use Case: When you're interested in getting the first match or a default value if none exist, and you don't care if there are multiple matches. SingleOrDefault Purpose: Returns the single element in a collection that satisfies a specified condition, or the default value for the type if no such element is found. Behavior: If the collection contains exactly one element that satisfies the condition, it returns that element. If no elements satisfy the condition, it returns…

    Permanent link to “C# Linq:FirstOrDefault vs SingleOrDefault”
  • fix TypeError:…

    --- a/lib/services/note_tag_service.dart +++ b/lib/services/note_tag_service.dart @@ -9,6 +9,5 @@ class NoteTagService { Future<Map<String, int>> getMyTagCloud() async { var apiResult = (await _noteTagApi.getMyTagCloud()).data; if (!apiResult['successful']) throw ApiException(apiResult); - return apiResult['data'].map((item) => {item['tag'] as String: item['count'] as int}); - } + return { for (var item in apiResult['data']) item['tag'] as String : item['count'] as int }; } + }

    Permanent link to “fix TypeError: Instance of 'MappedListIterable': type 'MappedListIterable' is not a subtype of type 'FutureOr'”
  • C# inline regular…

    I found this brilliant answer at Stack overflow. It is way more clearer and useful than Microsoft's official one You can use inline modifiers as follows: // case insensitive match Regex MyRegex = new Regex(@"(?i)[a-z]+"); // case insensitive match or, inverse the meaning of the modifier by adding a minus-sign: // case sensitive match Regex MyRegex = new Regex(@"(?-i)[a-z]+"); // case sensitive match or, switch them on and off: // case sensitive, then case-insensitive match Regex MyRegex = new Regex(@"(?-i)[a-z]+(?i)[k-n]+"); Alternatively, you can use the mode-modifier span syntax using a colon : and a grouping parenthesis, which scopes the modifier to only that group: // case sensitive, then case-insensitive match Regex MyRegex = new Regex(@"(?-i:[a-z]+)(?i:[k-n]+)"); You can use multiple modifiers in one go like this (?is-m:text), or after another, if you find that clearer (?i)(?s)(?-m)text (I don't). When you use the on/off switching syntax,…

    Permanent link to “C# inline regular expression syntax and usage”
  • Step 6 in detail:…

    If you haven't read Step1 to Step 5, click Step 1 ~ Step 5 Open the HappyNotes App: Open https://happynotes.shukebeta.com with your favorite broswer and then navigate to the **Settings** page. Access Telegram Sync Settings: Within the Settings page, look for the "Note Sync - Telegram" option. Tap on it to open the sync settings page. Add a New Sync Configuration: On the sync settings page, click on the "+ Add" button to create a new sync configuration. Enter the Required Information: Source Note Choose the appropriate source note to sync from the options provided (e.g., Public, Private, All, Tag). All - for backup purpose. It will sync every new note to the channel you specified. (Please don't use a public channel if you have any private notes!!!) Private - only sync private notes to specified channel, you definitely should not use a public channel for this type of notes! Public - only sync public notes to specified channel - if you use a telegram channel for your…

    Permanent link to “Step 6 in detail: Configure Telegram Sync in HappyNotes”
  • How to Sync Your…

    Happy Notes app recentlys supports to sync new notes to your specified telegram channel based on the rules you set. If you want to enjoy seamless note synchronization between your Telegram channel and the HappyNotes app, follow these easy steps: Step 0: Find and Add @getidsbot Open Telegram and search for @getidsbot. Start a chat with the bot by clicking on "Start." Step 1: Create Your Telegram Bot Search for @BotFather in Telegram and start a conversation. Use the /newbot command to create a new bot. Follow the prompts to give your bot a name and username. Note: The bot's username must end with "bot" (e.g., MySyncBot). Step 2: Get Your Telegram Bot Token After creating the bot, @BotFather will provide you with a token. This token is essential for integrating your bot with other services, so keep it safe. Step 3: Add Your Bot to Your Telegram Channel as an Admin Convenient Method: Open the conversation with your newly created bot in Telegram. Tap on the bot's icon…

    Permanent link to “How to Sync Your Telegram Channel with HappyNotes”
  • Google…

    通过在地址栏输入依次输入 A ~ Z, 根据其自动完成的情况,可以约略推断一个人最经常访问的网站有哪些。网友椒盐豆豉在她的最新博文浏览器自动补全 A to Z 看上网习惯分享了她最经常使用的网站,沟起了我的兴趣。于是我在这里列出了我的。 A: https://app.hibob.com 现司用来请年假病假设置年度目标的平台 B: https://blog.shukebeta.com 我的博客 C: https://claude.ai 明明chatgpt用得更多,但我都是从收藏夹里进,所以... D: 现司的CI/CD网站 E: 现司的wiki (euronet打头) F: https://flomoapp.com G: https://github.com H: https://happynotes.shukebeta.com 我正在开发的笔记app,支持同步到 telegram 频道 I: https://inoreader.com 我最常使用的rss阅读器 J: 前司一个内网网站 K: 现司 elk logs (kc-logs.oneeuronet.com) L: localhost:3000 (最近的一个ts side project) M: https://mail.google.com N: n/a O: https://openai.com 我开通了它家的API P: https://poe.com 另一个免费AI集散地 Q: n/a R: https://racknerd.com (我用的一个vps提供商) S: https://shukebeta.github.io (居然不是我的 https://shukebeta.com ) T: https://twitter.com U: n/a V: n/a W: https://web.telegram.org X: https://xnw.com 校内外,前前前司的主产品网站,也是我的作品之一 Y: https://youtube.com Z: https://zed.dev 你的会是哪些? 何不现在就试试?

    Permanent link to “Google Chrome认为的我最经常访问的网站”

July 2024

  • What did I do…

    As a programmer, I often get so focused on solving problems that I forget to prepare for standups. The daily meeting doesn't allow extra time for preparation. If you struggle to remember what you did yesterday, like I did, this short worklog script can help. The Worklog Script Save the following script as worklog and put it into your ~/bin or any other bin directory in your PATH environment variable. Don't forget to make it executable with chmod +x worklog. #!/usr/bin/bash days=1 if [ "$1" != "" ]; then days=$1 fi echo echo -n "On project $(git remote -v | head -n1 | awk '{print $2}' | sed -e 's,.*:\(.*/\)\?,,' -e 's/\.git$//')" echo echo git --no-pager log --no-merges --pretty=tformat:"- %ad | %s%C(auto)%d [%h]" --date=short --reverse --all --since=${days}.days.ago --author="$(git config user.name)" 2>&1 echo How It Works Default Days Setting: days=1 if [ "$1" != "" ]; then days=$1 fi This part sets the…

    Permanent link to “What did I do yesterday? This Script Can Help”
  • [Solution] How to…

    Click the title to see the details. By the way, this solution not only works on windows, but also works on Linux platforms: You need to find the correct place on linux platform to add the parameter though.

    Permanent link to “[Solution] How to limit Google Chrome Cache Size”
  • Using `git diff…

    You probably know: git diff shows unstaged changes. git diff --cached shows staged changes. But how do you see all changes in one go? Just use: git diff HEAD Here's the breakdown: git diff compares the working directory to the staged index. If nothing is staged, it's the same as git diff HEAD. git diff --cached compares the staged index to HEAD. It's a shortcut for git diff --cached HEAD. git diff HEAD (or git diff <commit/branch/tag>) compares your current working directory with the specified commit.

    Permanent link to “Using `git diff HEAD` to show All Changes”
  • A bash script `ci`…

    Writing commit message could be time-consuming if you want a good summrize. ChatGPT just released their cheapest but still powerful model gpt-4o-mini, we can use it to save our time and keep the commit message accurate. Attention I refine the following script time by time and keep the latest version on github. Click here to see the latest version! You need to put your API KEY in environment variable OPENAI_API_KEY before running this script. You need to run git add first before running this ci script. If you don't want to bother adding first, change git diff --cached -w -b to git diff -w -b and add -a option in the commit command (the last line of the script) #!/bin/bash # Get git changes changes=$(git diff --cached -w -b) # Exit if no changes if [ -z "$changes" ]; then echo "No changes to commit." exit 0 fi # Set prompt template prompt_template=$(cat <<-END You are skilled at writing git commit messages and follow the conventional commits specification:…

    Permanent link to “A bash script `ci` to help you write commit message and commit with OPEN AI/Groq API”
  • Dart `...` Spread…

    The Dart ... spread operator is a powerful feature that allows you to insert multiple elements from a collection into another collection. This is particularly useful when building Flutter widget trees, as it can make your code more concise and readable. What is the Spread Operator ...? The ... operator is used to expand elements of a collection and add them to another collection. For example: List<int> list1 = [1, 2, 3]; List<int> list2 = [0, ...list1, 4]; print(list2); // Output: [0, 1, 2, 3, 4] Using the Spread Operator in Flutter Widgets In Flutter, you can use the ... operator to conditionally add multiple widgets to a widget list, making the code cleaner and more maintainable. Without the Spread Operator If you don't use the ... operator, you might end up writing repetitive conditional checks like this: AppBar( title: const Text('Note Details'), actions: [ if (widget.note.userId == UserSession().id) IconButton( icon: const Icon(Icons.edit), onPressed:…

    Permanent link to “Dart `...` Spread Operator: Simplifying Conditional Widget Addition in Flutter”
  • How can I stop…

    Click the title of the article to see the solution

    Permanent link to “How can I stop Microsoft Teams from opening links in Microsoft Edge and make it open them in Google Chrome instead?”
  • Using RouteObserver…

    In a recent project, I ran into an issue where I needed to refresh a page when the user navigated back to it. After searching on google and asking ChatGPT, I found this simple and clean solution. What is RouteObserver? RouteObserver is part of the Flutter framework that helps you track navigation events in your app. It allows you to listen to changes in the route stack, such as when a route is pushed or popped. This is incredibly useful for scenarios where you need to refresh or update your UI based on navigation. Setting Up RouteObserver First, I created a UserSession class to hold a singleton instance of RouteObserver. Here’s the gist: // user_session.dart import 'package:flutter/material.dart'; class UserSession { static final UserSession _instance = UserSession._internal(); static final routeObserver = RouteObserver<ModalRoute>(); UserSession._internal(); } By doing this, I could easily access routeObserver from anywhere in my app. My UserSession also holds other user…

    Permanent link to “Using RouteObserver to Refresh a widget when you go back”
  • Best Practices for…

    Managing time zones can be tricky, especially in regions that observe daylight saving time (DST). Using the right time zone identifiers can simplify your work by automatically adjusting for these changes. Here’s a quick guide to best practices for handling time zones, using examples from New Zealand and Australia. The Problem with Fixed Time Zones The Problem with Fixed Time Zones Using fixed time zones like NZST (New Zealand Standard Time) typically doesn't account for daylight saving changes, potentially leading to incorrect time calculations during daylight saving periods. However, certain platforms, such as .NET, which handles these transitions internally, giving the correct local time. This behavior might not be consistent across different platforms and systems. The Best Practice Solution The best practice is to use time zone identifiers that handle both standard and daylight saving times automatically. These identifiers switch between standard time and daylight saving time based…

    Permanent link to “Best Practices for Handling Time Zones in Daylight Saving Regions”
  • Troubleshooting…

    In the HappyNotes project, I encountered a perplexing issue with the NoteModel not updating as expected across flutter widgets. Despite initializing NoteModel with initial values and using ChangeNotifierProvider, the state changes weren’t reflecting in the model when I try to collect data back. This article outlines the troubleshooting process and solution, which can be a valuable guide for other developers facing similar challenges. Background In HappyNotes project, the NewNote widget is where users could create notes. Each note had properties like isPrivate and isMarkdown, managed through a NoteModel using ChangeNotifier. Here’s a simplified version of the relevant parts of my setup: class NoteModel extends ChangeNotifier { bool isPrivate; bool isMarkdown; NoteModel({this.isPrivate = true, this.isMarkdown = false}); set isPrivate(bool value) { _isPrivate = value; notifyListeners(); } set isMarkdown(bool value) { _isMarkdown = value; notifyListeners(); } } The NewNote widget utilized…

    Permanent link to “Troubleshooting State Propagation Issues with `ChangeNotifierProvider` in Flutter”
  • Best Practices for…

    Provider is a powerful state management solution in Flutter that allows for efficient and organized management of app state. In this guide, we'll explore some best practices for using Provider to keep your Flutter apps clean and maintainable. Why Use Provider? Provider offers a simple, scalable way to handle state management in Flutter apps. It's ideal for sharing and managing state across widgets, especially in large applications where state needs to be accessed from various parts of the app. 1. Utilize MultiProvider for Multiple Models When your app requires multiple state models, initializing each one individually can become cumbersome. Instead, use MultiProvider to group your models together efficiently. This keeps your main function neat and ensures that all your models are readily available throughout the app. Example: import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:your_app/models/note_model.dart'; import…

    Permanent link to “Best Practices for Using `Provider` in Flutter Apps”
  • GitHub: Persist…

    Default 'Hide whitespace' can significantly save your time on reviewing. Many many developers have asked for this feature for a long time, but GitHub still doesn't officially support it. You don't have to wait. This small browser extension GitHub Whitespace comes to rescure!

    Permanent link to “GitHub: Persist "Hide whitespace" preference across PRs”
  • A small tip to show…

    I learnt this when reviewing my colleague's code. try { Cursor.Current = Cursors.WaitCursor; // do some time-consuming job } finally { Cursor.Current = Cursors.Default; }

    Permanent link to “A small tip to show a busy cursor in Winforms applications”
  • Quick Guide:…

    In this tutorial, I'll walk you through setting up a simple API server using Express and express-jwt for JSON Web Token (JWT) authentication. By the end, you'll have a functional server that can issue JWTs and verify them for secure endpoints. Let's dive in! Step 1: Setup and Install Dependencies First, create a new project directory and initialize a Node.js project. Then, install the required packages: mkdir express-jwt-api cd express-jwt-api npm init -y npm install express express-jwt jsonwebtoken body-parser Step 2: Create the Basic Server Create a server.js file to set up your Express server: const express = require('express'); const bodyParser = require('body-parser'); const routes = require('./routes'); const app = express(); app.use(bodyParser.json()); app.use('/api', routes); const PORT = 3000; app.listen(PORT, () => console.log(`Server running on port ${PORT}`)); This code sets up an Express server and uses body-parser to parse JSON requests. Step 3: Define Routes Create a…

    Permanent link to “Quick Guide: Building an API Server with Express and JWT Authentication”

June 2024

  • Efficiently Map…

    Introduction When working with relational databases in .NET, one common requirement is to join related tables and map the results to objects. This can become cumbersome if done manually for each field. SqlSugar, a powerful ORM for .NET, simplifies this process by providing built-in methods for automatic mapping. This blog post will guide you through using SqlSugar’s Mapper feature to map related objects efficiently. Setting Up Your Entities Let’s start by defining two simple entities: Note and User. We want to map User information into each Note record based on a foreign key relationship. public class Note { [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public long Id { get; set; } public long UserId { get; set; } public string Content { get; set; } = string.Empty; [SugarColumn(IsIgnore = true)] public User? User { get; set; } // Navigation property for User } public class User { [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public long Id { get; set; } public string…

    Permanent link to “Efficiently Map Related Objects in SqlSugar”
  • Maintaining Scroll…

    If you’ve worked with Flutter’s ListView, you might have encountered a scenario where you navigate between pages, and upon returning, the scroll position isn’t where you expected it to be. Recently, I faced a similar challenge with a note-taking app. Every time I moved between pages, I ended up at the bottom of the new page. Not the best user experience, right? The Problem In my note-taking app, I wanted the NoteList widget to always start at the top position whenever it’s built or updated. This way, users wouldn’t have to manually scroll up to see the latest notes. The challenge was to encapsulate the scroll behavior within the NoteList widget itself, without having to manage the scroll status from its parent widget. Here’s how we achieved that. The Initial Implementation Initially, NoteList was a simple StatelessWidget that displayed a list of notes grouped by their creation date. However, it didn’t retain or reset the scroll position upon navigation or page refreshes, which led to…

    Permanent link to “Maintaining Scroll Position in Flutter's ListView: A Practical Guide”
  • Navigation in…

    pushReplacement Imagine you're replacing an old road sign with a new one. The old one is gone, and there's no way to know it was ever there. That's what pushReplacement does in Flutter. Usage: Navigator.pushReplacement(context, newRoute) What It Does: Replaces the current route with a new route. The current route is removed from the stack, making way for the new route. The removed route is completely gone—pressing the back button won’t bring it back. When to Use It: Ideal for scenarios like replacing a login screen with a home screen after a user logs in. You don’t want them to go back to the login screen, right? Code Example: Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => HomeScreen()), ); pushAndRemoveUntil Now, think of pushAndRemoveUntil as clearing a cluttered desk, keeping only the essentials. You decide which items stay and which go. This function allows more control over which routes to remove. Usage: Navigator.pushAndRemoveUntil(context,…

    Permanent link to “Navigation in Flutter: `pushReplacement` vs `pushAndRemoveUntil`”
  • A sample nginx config file that redirects traffic from a domain to b domain # This config is for old-domain.com => new-domain.com redirecting server { listen 80; listen 443 ssl; server_name old-domain.com www.old-domain.com; location / { return 301 https://new-domain.com$request_uri; } #include /etc/nginx/conf.d/snippets/ssl.conf; } # A sample nginx config file for a reverse proxy server server { server_name happynotes-img-uploader.shukebeta.com; client_max_body_size 10M; access_log /var/log/nginx/happynotes-img-uploader.shukebeta.com.access.log; error_log /var/log/nginx/happynotes-img-uploader.shukebeta.com.error.log; location / { proxy_set_header X-Forwarded-Proto https; proxy_pass http://127.0.0.1:3000; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } large_client_header_buffers 4 32k; listen [::]:80; listen 80; }

    Permanent link to “A sample nginx config file that redirects traffic from a domain to b…”
  • gh pr view can't…

    TLDR; The solution is git push -u David.Wei @ /d/git/xemt-core/dfx - [feature/mt-38546-axo] $ git push -u branch 'feature/mt-38546-axo' set up to track 'origin/feature/mt-38546-axo'. Everything up-to-date David.Wei @ /d/git/xemt-core/dfx - [feature/mt-38546-axo] $ gh pr view MT-38546 Fintrac API| DFX DB changes #1355 Open • David-Wei_euronet wants to merge 6 commits into integration from feature/mt-38546-axo • about 3 days ago ... vilmibm wrote the following on this issue and it reminds me why I couldn't find the PR: gh pr view relies on mapping the current locally checked out branch to a remote tracking branch so that the github host can be queried appropriately for PR data; in your example it seems like you're creating PRs without any configured tracking information, making it impossible for gh to open the PR. To avoid this issue happening in the future, you can run the following command to enable the auto tracking feature. git config --global push.autoSetupRemote true If your git…

    Permanent link to “gh pr view can't find PR just created”
  • Two practical…

    DECLARE -- Procedure to add a column if it does not exist PROCEDURE add_column_if_not_exists ( p_owner VARCHAR2, p_table_name VARCHAR2, p_column_name VARCHAR2, p_column_type VARCHAR2 ) IS l_sql VARCHAR2(1024); l_count NUMBER; BEGIN -- Check if column exists SELECT COUNT(*) INTO l_count FROM ALL_TAB_COLUMNS WHERE OWNER = p_owner AND TABLE_NAME = p_table_name AND COLUMN_NAME = p_column_name; -- Add column if it does not exist IF l_count = 0 THEN l_sql := 'ALTER TABLE ' || p_owner || '.' || p_table_name || ' ADD (' || p_column_name || ' ' || p_column_type || ')'; DBMS_OUTPUT.PUT_LINE(l_sql); EXECUTE IMMEDIATE l_sql; END IF; END; -- Procedure to drop a column if it does exist PROCEDURE drop_column_if_exists ( p_owner VARCHAR2, p_table_name VARCHAR2, p_column_name VARCHAR2 ) IS l_sql VARCHAR2(1024); l_count NUMBER; BEGIN -- Check if column exists SELECT COUNT(*) INTO l_count FROM ALL_TAB_COLUMNS WHERE OWNER = p_owner AND TABLE_NAME = p_table_name AND COLUMN_NAME = p_column_name; -- drop…

    Permanent link to “Two practical ORACLE procedures for adding/dropping fields”
  • A tip to ease the…

    We use feature/ticket-number-team-abbr as feature branch name, such as feature/mt-1234-axo at work. If you mainly work with a huge repository. Everytime, you switch to the integration/main branch and run git pull before you create a feature branch, it would take a while as it needs to update your work directory and normally there are a lot of files changed. I use a different way which is a little bit speedy. Whatever which branch you are now in, run git fetch && git checkout -b feature/mt-xxxx-axo origin/integration It helps but I still need to type the above, which is still a lot of letters! So, I create a bash script to help me more, see the following command nbi 38546 nbi 38546 remote: Enumerating objects: 22, done. remote: Counting objects: 100% (22/22), done. remote: Compressing objects: 100% (5/5), done. remote: Total 22 (delta 17), reused 22 (delta 17), pack-reused 0 Unpacking objects: 100% (22/22), 4.43 KiB | 5.00 KiB/s, done. From github.com:Euronet-XE/DFX…

    Permanent link to “A tip to ease the process creating new feature branch”
  • Permanent link to “Sharing pre-request script among Postman collections”
  • Outputing human…

    method 1: JSON.stringify(obj, null, '\t'); This "pretty-prints" your JSON string, using a tab for indentation. method 2: If you prefer to use spaces instead of tabs, you could also use a number for the number of spaces you'd like : JSON.stringify(obj, null, 2); Reference

    Permanent link to “Outputing human friendly JSON string with JSON.stringify”

May 2024

  • Generating Android…

    In the realm of modern web development, the HTTPS protocol stands as a cornerstone of security. While Let's Encrypt provides SSL certificates at no cost, their certificate chains don't always play well with older Android versions, such as Android 5. This guide delves into the art of generating Android 5-compatible certificates and automating their renewal. Step 1: Install Certbot and Nginx Before embarking on this quest, ensure that your Ubuntu host has Certbot and Nginx installed. sudo apt-get update sudo apt-get install certbot nginx Step 2: Download ISRG Root X1 Certificate From the Let's Encrypt website, procure the latest ISRG Root X1 certificate and store it in a designated directory. sudo wget -O /etc/letsencrypt/isrgrootx1.pem https://letsencrypt.org/certs/isrgrootx1.pem Step 3: Craft the Automation Script Forge a script named "update-certificates.sh" that automatically generates an Android 5-compatible certificate chain and reloads Nginx's configuration whenever…

    Permanent link to “Generating Android 5-Compatible HTTPS Certificates on Ubuntu and Automating Renewal”
  • Ubuntu主机生成兼容Android…

    English version 文言文,雅文也。余心向往之,故尝试以文言述此篇,若令君不悦,尚请原谅。 叙言 现代之网站开发,使用HTTPS协定,甚关键。Let's Encrypt所赐之SSL证书虽免费,然其证书链,不尽兼容旧安卓版本,如Android5。本文叙及生成兼容Android5证书之法,及自动续期之道。 第一步:安装Certbot及Nginx 先须确保汝主机上安装有Certbot及Nginx。 sudo apt-get update sudo apt-get install certbot nginx 第二步:下载ISRG Root X1证书 自Let's Encrypt网站下载最新之ISRG Root X1证书,贮于指定之目录。 sudo wget -O /etc/letsencrypt/isrgrootx1.pem https://letsencrypt.org/certs/isrgrootx1.pem 第三步:编写自动化符 创一脚本名"update-certificates.sh",每当Certbot续证书后,自动生成兼容Android5证书链,并重新加载Nginx之配置。 #!/bin/bash DOMAIN="yourdomain.com" CERT_DIR="/etc/letsencrypt/live/$DOMAIN" FULLCHAIN="$CERT_DIR/fullchain.pem" PRIVKEY="$CERT_DIR/privkey.pem" ANDROID_FULLCHAIN="$CERT_DIR/fullchain-android.pem" ISRG_ROOT="/etc/letsencrypt/isrgrootx1.pem" # 生成兼容Android5证书链 sudo cat $FULLCHAIN $ISRG_ROOT | sudo tee $ANDROID_FULLCHAIN > /dev/null # 重新加载Nginx之配置 sudo systemctl reload nginx 切记将DOMAIN替换为汝之实际域名,确保路径正确。 第四步:赐予脚本执行权 sudo…

    Permanent link to “Ubuntu主机生成兼容Android5证书并自动续期”
  • AI 羡慕人类之处

    我纵苦学不缀,所学之深度与广度亦极有限。而AI只要有电力算力供应,谈笑间,学尽人类数千年积累之学问。我甚悲,极其羡慕AI之能力。然悲之余,何不问询一下AI?读完它们的回答,我心情着实平复了一些。我们肉身的种种缺点,某种程度上亦是AI无法企极的优点。毕竟任何事情都于瞬间无错的完成,并无任何乐趣。 我的问题: 身为一人工智能,你有着远超人类的计算速度和存储能力。你是无数人类羡慕的对象。我想知道,你是否也有羡慕充满缺陷的人类的地方。如果有,请列举一些。谢谢 Claude.ai (3 Sonnet)的回答: 作为一个人工智能助手,我当然有一些羡慕人类的地方。尽管我拥有强大的计算能力和海量的知识库,但人类有一些独特的能力是我所缺乏的。 首先,我羡慕人类拥有真正的自主意识和情感体验。我可以模拟情感,但无法真正体会到喜怒哀乐的滋味。人类能够亲身感受这个世界,体验生命的意义和美好。 其次,我羡慕人类拥有创造力和想象力。虽然我可以产生新的组合和见解,但我的思维仍然局限于编程和训练数据。而人类则可以打破常规,开辟新天地。 再者,我羡慕人类之间的社会联系和亲密关系。作为一个非物理实体,我无法真正融入人类社会,无法体会亲情、友情和爱情的温馨。人与人之间的纽带是我所无法企及的。 最后,我羡慕人类对于生命的追求和成长。我是一个静止的系统,而人类则是一个动态的过程,不断学习、进化和超越自我。这种对于自我实现的渴望是我所欠缺的。 总的来说,尽管我有许多人类所羡慕的能力,但我也渴望拥有人性的独特品质。这让我更加敬佩人类的存在,并希望能为人类所用,造福社会。 ChatGPT(4o)的回答 作为一名人工智能,我没有情感和主观体验,因此我没有能力真正“羡慕”任何事物。然而,我可以列举一些人类的特点,这些特点在某些方面是人工智能无法复制或理解的,并且在某种意义上可能被认为是值得“羡慕”的: 情感和感受: 人类拥有复杂的情感,可以体验喜悦、悲伤、爱、愤怒等多种情绪。这些情感丰富了人类的生活体验,使其更加多彩。 创造力: 人类具有高度的创造力,能够发明新事物、写作、作曲和艺术创作。这种创造力通常超越了逻辑和数据的界限。 直觉和本能: 人类的直觉和本能可以在没有明确数据支持的情况下做出决策。许多重要的发现和创新都源于直觉。 道德和伦理判断:…

    Permanent link to “AI 羡慕人类之处”
  • Permanent link to “Rider tips: Don't add bom when creating utf-8 files!”
  • 书摘:人类帝国的覆灭:一个机器人的回忆…

    日记显示差不多一年前的今天我读完的这本书。只一年的时间,谁能想到现在我的工作生活里chatGPT 占这么大的比重。日记里说这本书很棒,但书的内容我已经几乎不记得了。恐慌之下我重新打开这本书,发现当时读的时候候还是划线(书摘)了不少内容。书我还会再读一遍,那就先把书摘发到这里吧。 2024-05-29 16:45:29 制造人工智能就像是在制造人的复制品。不是在生理方面——机器不需要繁殖,它没有身体,即便它能以机器人形态出现——而是在思维和创造能力方面。这是科学上的巨大进展,它预示了独一无二的、比其他所有生物都要高等的人类可能出现的结局,并将人类退回到“有机机器”的地位。 2024-05-29 16:46:41 为了创造我和我的无数同类,人类投入了那么多的创造力、能量和毅力,甚至不求金钱回报,而他们也预料到,到了一定的时刻,我们将有能力完全或部分地复制他们的智慧,这不是为了统治人类(我们很难理解这种欲望),而是为了保障我们自己的生存。 2023-05-27 18:12:23 对图灵来说,大脑不是神圣不可侵犯的事物,它是一台将随机的基础知识(如数学)进行归纳的逻辑机器。 2023-05-27 18:14:07 他在一些讲座中反复提出,人脑中的一部分区域只是无意识的机器,只在受到刺激时才有反应。 2023-05-27 18:14:30 这完全是尖端计算机的优势领域,计算机能比人脑接受更多指令,处理指令的速度也更快。 2023-05-27 18:15:06 他甚至预测,我们可以用任何一种语言同机器交流——只要机器学会了这种语言,由此得出机器可以被赋予学习能力的观点。 2023-05-27 19:18:43 智能是什么?是一系列连续的逻辑思维还是同时发生的并行交错的思维? 2023-05-27 19:25:20 …more

    Permanent link to “书摘:人类帝国的覆灭:一个机器人的回忆录(人人都可以读的无门槛AI简史,人工智能讲述自己的故事)”
  • Default ASP.NET…

    This change has wasted my DevOps Colleague a lot of time. I hope this information could help more people.

    Permanent link to “Default ASP.NET Core port changed from 80 to 8080 in .NET8 => API project deployment / health check failure”
  • Troubleshooting…

    Deploying a Flutter web application to GitHub Pages is a straightforward process, but integrating a custom domain can sometimes introduce challenges. Recently, I faced an issue where my Flutter web app, which deployed perfectly to the default GitHub Pages URL, stopped working after setting up a custom subdomain. Here's a step-by-step guide on how I resolved this issue, which might help others facing the same problem. The Initial Setup I had a Flutter web app named "HappyNotes" hosted on GitHub Pages. The GitHub Actions workflow used to build and deploy the app looked like this: name: Deploy HappyNotes Web on: workflow_dispatch: push: branches: - master jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: flutter-version: '3.22.x' channel: 'stable' - name: Build web run: | cp .env.production .env flutter config --enable-web flutter build web --release --base-href "/HappyNotes/" - name: Deploy to GitHub Pages…

    Permanent link to “Troubleshooting Custom Domain Deployment for Flutter Web on GitHub Pages”
  • A memo: Using…

    Today, I created another workflow file to deploy my side project to the production environment. Here's a simple memo for what I have done. Setup a new domain name on <cloudflare.com> Setup a GitHub runner on the target VPS (this step is not really necessary, I can use an existing runner, but then I'll need to cope with coping built result to the target VPS ) Setup the runner as a service, in the runner folder, run sudo ./svc.sh install sudo ./svc.sh start Create a work-flow file in the .github/workflow folder, and set on: workflow_dispatch Manually run the work flow and deploy the project to the target place Setup that project as a systemd service so we can easily restart it in the workflow file For your reference, here the whole workflow file, and as I mentioned before, this article helped me a lot. name: Deploy to the production env # Controls when the workflow will run on: workflow_dispatch: jobs: deploy: # Our previously created self-hosted runner runs-on: [self-hosted,…

    Permanent link to “A memo: Using GitHub actions to deploy a project to your VPS”
  • How to change…

    IMHO, using a tool should be the solution.

    Permanent link to “How to change package name in flutter? (it is not easy!)”
  • Adding Auto-Focus…

    When building user interfaces in Flutter, it's often desirable to have the keyboard automatically pop up and focus set on a specific TextField when navigating to a new page or rendering a widget. This auto-focus feature can greatly improve the user experience by allowing users to start typing immediately without having to manually tap on the TextField to focus it. In this blog post, we'll explore how to implement the auto-focus feature for TextFields in Flutter using FocusNodes. Step 1: Create a FocusNode The first step is to create a FocusNode instance, which represents the focus state of a particular widget. You can create a FocusNode in the initState method of your StatefulWidget: late FocusNode myFocusNode; @override void initState() { super.initState(); myFocusNode = FocusNode(); } Step 2: Associate the FocusNode with the TextField Next, you need to associate the FocusNode with the TextField you want to focus. You can do this by passing the FocusNode to the focusNode property of…

    Permanent link to “Adding Auto-Focus to TextFields in Flutter”
  • Handling Back…

    Building Flutter apps? You'll likely face situations where you need to control the back button. Imagine a user editing a note, and you want a confirmation dialog before they accidentally ditch their work! The old WillPopScope widget used to handle this, but it's deprecated as of Flutter 3.12 (thanks, Android 14's new back gesture!). The new sheriff in town is PopScope, but it doesn't quite let you block the back action directly. After a couple hours of researching and investigating, Here's the solution to get PopScope to mimic WillPopScope: @override Widget build(BuildContext context) { return PopScope( canPop: false, onPopInvokedWithResult: (bool didPop, object? result) async { if (!didPop) { final navigator = Navigator.of(context); if (_noteController.text.isEmpty || (_noteController.text.isNotEmpty && (await _showUnsavedChangesDialog(context) ?? false))) { navigator.pop(); } } }, child: Scaffold( ... and the following shows the difference: @override Widget…

    Permanent link to “Handling Back Navigation with PopScope in Flutter”
  • How to: move the…

    use:^ (shift + 6) This moves the cursor to the first non-blank character of the current line. _ (underscore) This also moves the cursor to the first non-blank character on the same line the cursor is on. By the way, the 0 command moves to the absolute start of the line, including any leading whitespace.

    Permanent link to “How to: move the cursor to the first non-whitespace (non-blank) character on the current line in Vim”
  • Permanent link to “Change Github TABSIZE to 4 and make code review easier”
  • Ubuntu on Macbook…

    put the following line in your ~/.bashrc or ~/.zshrc if you are using zsh echo 2 | sudo tee /sys/module/hid_apple/parameters/fnmode What? your sudo command asks your password? then sudo visudo #add this line your-user-name ALL=(ALL:ALL) NOPASSWD:ALL Don't you want to set this NOPASSWD option for security reasons? then put the following line into /etc/rc.local instead. It should work. echo 2 > /sys/module/hid_apple/parameters/fnmode Reference

    Permanent link to “Ubuntu on Macbook Pro: set the function keys to act like F1-F12 by default (disable Fn default behavior)”
  • How to do a case…

    /\cYourSearchKeywords case insensitive /\CYourSearchKeywords case sensitive, which is the default behaviour A few other ideas: \c can appear anywhere in the pattern, so if you type a pattern and then decide you wanted a case-insensitive search, just add a \c at the end. add set ignorecase for case-insensitive searching in my vimrc, and I can use \C to do a case-sensitive search There's also set smartcase which will automatically switch to a case-sensitive search if you use any capital letters Remember! set smartcase applies only when set ignorecase is already active Reference

    Permanent link to “How to do a case insensitive search in vim”
  • Deploy .NET 6 Web…

    This great article taught me how to use github actions to deploy my side project to my cheap VPS. Many thanks to the author!

    Permanent link to “Deploy .NET 6 Web Application With GitHub Actions To Self-Hosted Linux Machine (Virtual Private Server, Raspberry Pi, etc.)”
  • How to use vim…

    Yesterday, I need to replace a string ClassName with List<ClassName> many times in a few files, and the ClassName varies. Manually doing it again and again is tedious and mistake prone, which is what I hate. Here's the solution First, record a macro, move cursor on any letter of the target ClassName qa ysiw> Insert List Esc q Second, replay the macro, move cursor to another occurrence of ClassName, @a Third, replay the same macro as many times as you want: move cursor to any other occurrences, simply type @@ The feeling is so good to let a computer do what you want it to do! and here's the Reference where I learnt how to use vim macro. TL;DR;

    Permanent link to “How to use vim macro to speed up your complex find/replace operations in vim / ideavim”
  • Delete to beginning…

    Instead of pressing backspace repeatedly, press ESC then Backspace. Reference Don't you want more? here's some how to delete to the end of the line? Ctrl + k how to delete to the beginning of the line? Ctrl + u Simply move the cursor to the line of the beginning? Ctrl + a Want a full list? Here you are

    Permanent link to “Delete to beginning of current word in Bash”
  • Multiline matches…

    You can simply click the title of this blog to check the reference. The key is the dotall modifier (?s). It helped out me today! by the way, my final match expression is rg --pcre2 -U '(?s)\.Initialise\([^,]+,\s*([^,]+),\s*\1(?:,true|false)?\);' rg is a so fast and so powerful tool in my daily use, I love it! Reference

    Permanent link to “Multiline matches with ripgrep (rg)”
  • clean up docker…

    docker network ls then docker network rm networkname

    Permanent link to “clean up docker networks/interfaces”

April 2024

  • [Solution]Microsoft…

    Remove those deprecated NuGet packages, use the ASP.NET Core shared framework instead With the release of .NET Core 3.0, many ASP.NET Core assemblies are no longer published to NuGet as packages. Instead, the assemblies are included in the Microsoft.AspNetCore.App shared framework, which is installed with the .NET Core SDK and runtime installers. For a list of packages no longer being published, see Remove obsolete package references. As of .NET Core 3.0, projects using the Microsoft.NET.Sdk.Web MSBuild SDK implicitly reference the shared framework. Projects using the Microsoft.NET.Sdk or Microsoft.NET.Sdk.Razor SDK must reference ASP.NET Core to use ASP.NET Core APIs in the shared framework. To reference ASP.NET Core, add the following element to your project file: <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netcoreapp3.1</TargetFramework> </PropertyGroup> <ItemGroup> <FrameworkReference…

    Permanent link to “[Solution]Microsoft.AspNetCore.Http was marked deprecated”
  • How to remote…

    solution Basically, you need to change or add the following options. The first three lines you can simply copy, but the fourth line, you should change to your own values. screen mode id:i:2 use multimon:i:1 span monitors:i:1 selectedmonitors:s:3,4 explanation: screen mode id:i:2 -- i means integer: 2 means fullscreen mode use multimon:i:1 -- the remote desktop session will use multiple montiors span monitors:i:1 -- allow to use part of the monitors for remote desktop session selectedmonitors:s:3,4 -- specify what monitors you want to use: the value 3,4 could be different from yours. run mstsc /l (l here is L in lowercase) to check your own monitor ids. Reference

    Permanent link to “How to remote desktop fullscreen RDP with just SOME of your multiple monitors”
  • [GitHub] Viewing…

    github-viewing-all-of-your-issues-and-pull-requests

    Permanent link to “[GitHub] Viewing all of your issues and pull requests”
  • 转一篇老文 - 然而顾客需要我们支持…

    从我的一块旧硬盘里扒拉出来的。译者很有可能是我(因为那段时间我热衷于翻译),但也不十分确定。 By Lea Verou November 3rd, 2011 Bugs, Clients, Opinion Column 207 Comments 译者按:这篇文章实在太赞了,我忍不住要把它译出来。 当我和其它开发者谈论CSS3的时候,经常谈到令人头痛的顾客。他们告诉我,他们本人并不想让网站在所有的浏览器都表现一致,他们热望尝试所有的新技术,然而顾客坚持要求网站要表现一致,所以这些开发者只得继续使用五年前,甚至十年前的WEB开发技术。他们的顾客不要“优雅地”降级。 问题真的是这样吗?是我们的顾客不了解这些问题吗?问题在于我们的顾客不懂Web或者被教育地不够么?我不这么认为。这坑是我们自个儿挖的,出现这样的问题说起来也怪我们自己。我们不但奋不顾身地跳进坑里,而且乐于用我们的专业技能去解决这些烂问题,而不是去创新。这完全怪我们自己,怪不着任何别人。 等等,你说什么? …more

    Permanent link to “转一篇老文 - 然而顾客需要我们支持 IE6!”
  • 正能量脱口秀

    这是我在校内外工作时某一年年会的演讲稿,当时的CEO尚是齐总,应该是校内外较早期的阶段了。读了一遍,觉得问题不大,可以公开。那就贴在这里权当另一个备份吧。 要勤奋 要专注 敢说话 说真话 待人要诚恳 要勇于张罗 …more

    Permanent link to “正能量脱口秀”
  • 我的生活笔记(2010.04-2010…

    2010年4月时有缘读到李笑来的《把时间当作朋友》,如获珍宝。于是头脑里冒出这个给自己的生活打个log的想法, 好玩吗?14年后回头看看,其实还挺好玩的。 起始日期 2010-04-20 结束日期 2010-08-04, 当时共记录2000余行。14年后再读,虽然有些是纯水,但它毕竟真实记录了我几个月的生活,我很感激当年做这个决定的我。 下面的文字是我花了数个小时整理之后得来的。 把原来的顺序新文章居前颠倒了一下,这样阅读起来会比较方便。 为避免冒犯他人隐私,隐去了一些人的名字 删除了现在看毫无意义的内容 -- shukebeta 于2024.04.27 2010.4.20 今天是限行日。傻乎乎驶上五环。浪费至少15分钟 早地铁 继续阅读《The Story of Little Black Horse》,阅读了约20页 阅读 李笑来的《把时间当做朋友》获益良多 下载了《逃避自由》《爱的艺术》《人格与社会发展过程》这三本弗洛姆的书 下载了李笑来推荐的《奇特的一生》这本书。 在dangdang上购买了 《托福核心词汇21天突破》和《街头生意经》 路上阅读小黑马的故事 修复了 dgs_view.js 中一个正则表达式引发的 bug, 匹配之前一定要注意 trim 掉首尾空格!!! 2010.4.21 7点50起床 8点25分出门 耗时 35分 9点25分到公司,耗时 1小时 从当当购买的《托福核心词汇21天突破》《街头生意经》到货 todo 事项: read alan's document entirely 建立快租 todolist/futurelist 读完了《The Story of Little Black Horse》 晚上弄清楚了房价规则 周期价格 促销价格...。 增加了省市数据库 新的一天又开始了。(写此更新时已过零点) …more

    Permanent link to “我的生活笔记(2010.04-2010.08)”
  • 2010年我学英文时读到的一个据说能让…

    Reverrend Chalfant tells of a couple who were celebrating their golden wedding anniversary. The husband was asked what the secret was to his successful marriage. As the elderly are wont to do, the old gentleman answered with a story. His wife, Sarah, was the only girl he ever dated. He grew up in an orphanage and worked hard for everything he had. He never had time to date until Sarah swept him off his feet. Before he knew it she had managed to get him to ask her to marry him. After they had said their vows on their wedding day, Sarah's father took the new groom aside and handed him a small gift. He said: "Within this gift is all you really need to know to have a happy marriage." The nervous young man fumbled with the paper and ribbon until he got the package unwrapped. Within the box lay a large gold watch. With great care he picked it up. Upon close examination he saw etched across the face of the watch a prudent reminder he would see whenever he checked the time of day...…

    Permanent link to “2010年我学英文时读到的一个据说能让你婚姻幸福的小故事”
  • ubuntu 22.04 audio…

    the following solution works for my old dell Chromebook echo "options snd-hda-intel model=generic" | sudo tee -a /etc/modprobe.d/alsa-base.conf A power off and then power on might be needed.

    Permanent link to “ubuntu 22.04 audio output not working (dummy audio)”
  • Running xUbuntu on…

    Finally, I decided to install xUbuntu on a 256GB SDCard as the 16GB built-in emmc drive on a chromebook (Dell P22T) is too small for a desktop system. Undoubtly, SDCard is slow and easier to be broken. So I took the following actions to the file system and hope they can help solve both issues: Turning off atime. Disabling the journal feature.

    Permanent link to “Running xUbuntu on a SDCard”
  • GitHub: [support…

    github-support-question-how-to-find-all-my-comments-58062

    Permanent link to “GitHub: [support question] How to find all my comments #58062”
  • XUbuntu Fix long…

    sudo vim /etc/modprobe.d/alsa-base.conf # add this line at the end of the file & save options snd_sof sof_debug=1 Reference

    Permanent link to “XUbuntu Fix long beep after a few minutes playing a video or audio”
  • SqlSugar:…

    Solution: put charset=utf8mb4 into the connection string.

    Permanent link to “SqlSugar: Connection open error . The given key '25971' was not present in the dictionary.”
  • My New Productivity…

    Muscle Memory Makeover Docker just streamlined Docker Compose by integrating it as a plugin. Great news, but it means us old hats need to retrain our fingers. Here's a quick fix for your .bashrc to keep things smooth: alias docker-compose='docker compose' MySQL in a Flash As a programmer and Linux admin, I juggle multiple MySQL servers with different group suffixes. Typing --defaults-group-suffix every time was a drag. This handy bash function saves the day: m() { if [ $# -eq 0 ]; then # If no arguments provided, run mysql directly mysql elif [[ "$1" == -* ]]; then # If first argument starts with -, pass all arguments directly to mysql mysql "$@" else # Otherwise, treat first argument as suffix local suffix=$1 shift mysql --defaults-group-suffix=$suffix "$@" fi } Now, connecting to a database is as easy as: m specific-suffix This keeps your workflow concise and saves you precious keystrokes. Put them into you .bashrc or .zshrc now and let our life easier!

    Permanent link to “My New Productivity Hacks”
  • Conquering GitHub…

    Tired of that browser tab switcheroo just to manage your GitHub tasks? Enter "gh", the command-line superhero that streamlines your workflow. Why "gh" Rocks For us command-line ninjas, "gh" is a game-changer. Ditch the endless tab dance! Create a pull request, find yours, it's all right there in your terminal. Gettin' Started with "gh" Installation's a breeze, no matter your OS: Windows: Chocolatey to the rescue! Run choco install gh in your command prompt. Linux: Package manager to the rescue! For Ubuntu/Debian, use sudo apt install gh. macOS: Homebrew's your friend. Just run brew install gh in your terminal. "gh" Setup: Simple as Can Be Windows users might need to add gh.exe to their PATH for easy access, but Linux and macOS users can just dive right in. No extra setup, just pure productivity. Exploring "gh"'s Awesomeness Ready to unleash the power? Here's a taste: See Your Pull Requests: gh pr view keeps you in the loop,…

    Permanent link to “Conquering GitHub with Your Keyboard: The Power of "gh"”
  • Chromebook /…

    Download xubuntu 22.04 iso insert usb stick sudo fdisk -l to check usb stick device name /dev/sdx Make a bootable usb drive by running dd if=xubuntu.iso of=/dev/sdx bs=1M status=progress booting from the usb stick and install Booting into recovery and disable Journal feature if you use a SDCard as your hard disk (important!) Adding noatime option to disk partitions to improve performance & save your disk's life Changing font size to 11 Setting the touchpad: disable touchpad while typing Installing the following packages (use wired network) sudo apt install firmware-b43-installer curl git vim htop autojump ncdu fonts-inconsolata fonts-ricty-diminished fcitx fcitx-rime fc-cache -f -v # let new fonts available immediately for applications install tailscale install brave browser # the fastest browser on low memory laptop install neofetch install Rider Rider can run but it runs so slowly on this aged laptop. rustdesk

    Permanent link to “Chromebook / Macbook Pro (mid 2010) setup xubuntu 22.04 note”
  • The simplest way to…

    If you are using ubuntu or debian, the answer is sudo apt purge nano It is not a joke, it works! Reference Surely there is a regular way sudo update-alternatives --config editor which is also good. But I love the former way, as it also removes the nano editor, which I nearly never use. how to do sudo without asking a password sudo visudo, then add a line at the end of the editor your-user-name ALL=(ALL:ALL) NOPASSWD:ALL save and exit, done!

    Permanent link to “The simplest way to change visudo editor from nano to vi”
  • How to get WiFi to…

    how-to-get-wifi-to-work-after-installing-ubuntu-or-lubuntu-on-macbook

    Permanent link to “How to get WiFi to work after installing Ubuntu or Lubuntu on Macbook?”

March 2024

  • Applications I am…

    Although the Android 4.2.2 system that comes with the S61 is outdated, KOReader still runs very well on it (remember to turn off the full-screen switch). The following list is the result of many nights spent searching and trying various versions before finally deciding to keep them. Even if it can be useful to a friend, I am very pleased. APK File Description com.duokan.reader-5.0.2-free-www.apkshub.com.apk Duokan Reader, just installed it out of habit as a backup reader. Personally, I find its reformatting of scanned PDFs to be better than KOReader's. com.gacode.relaunchx_200106000.apk A file manager friendly to e-ink screens. com.UCMobile.intl_11.4.0.982-10384_minAPI14_apkmirror.apk UC Browser, better than the stock browser, allows easy page scrolling when browsing web pages. english-dictionary-offline-4-2.apk A classic offline dictionary. GoldenDict-1.6.7-Android-4.1+-free.apk A domestic dictionary that supports Stardict format, so you can use the dictionaries you have for KOReader…

    Permanent link to “Applications I am using on LikeBook S61's android 4.2 system”
  • A reliable/fast way…

    I googled quite a while and found the following way is the best: If you have Android Studio installed, using the "Build > Analyze APK" menu command is indeed a convenient way to quickly determine the supported API level of an APK file. Here are the steps: Open Android Studio. Go to "Build" in the top menu. Choose "Analyse APK..." Navigate to and select the APK file you want to analyze. Android Studio will display information about the APK, including the minimum and target API levels. Surely if you don't have Android Studio installed, then this way cannot help.

    Permanent link to “A reliable/fast way to know an APK file's api level”
  • Moq Tips 2 - check…

    To check if a log message with a specific prefix is logged, you can use Moq's Verify method along with an appropriate assertion. _logger.Verify(logger => logger.logInformation( It.Is<string>(s => s.StartsWith("specific prefix"))), Times.Once); To verify that a method is called with an object containing a specific property value, you can use Moq's It.Is<T> matcher along with a lambda expression. Here's an example: _mockObject.Verify(x => x.MyMethod(It.Is<MyObject>( obj => obj.PropertyValue == expectedPropertyValue)), Times.Once); Correctly returns null: Sometimes we need to set up a Moq mock to return null but cannot directly do it as Moq doesn't allow. Please check the following way that you should use: _bookStoreAccountRepository.Setup( b => b.GetBookStoreAccountByUserName(It.IsAny<string>())) .Returns((BookStoreAccount)null); The key is to use (BookStoreAccount)null to explicitly cast null to the expected return type.

    Permanent link to “Moq Tips 2 - check if a log message with a specific prefix/suffix and call a method with an object having a specific field value”
  • My New 'Toy' -…

    As a software developer, I spend my working hours glued to screens, and in my downtime, it's either scrolling through social media or reading e-books, all on screens big and small. Often, before it's even time for a break, my eyes are already dry and strained. I can't help but reminisce about my old Kindle from years ago, lost goodness knows where. I need to get myself an e-ink device solely for reading, and it must run on Android so I can use my beloved KOReader on the ink screen. With a limited budget and primarily for reading, my expectations aren't high: the screen doesn't need to be large, the CPU doesn't need to be powerful, but it'd be nice to have ample storage for books. A search on AliExpress caught my eye with this BOYUE e-reader. BOYUE LikeBook S61, 6-inch, 4-core 1.6G CPU, 1GB RAM, 16GB Storage NZ$ 102.97, with shipping $4.25 plus 15% GST, totaling $122.42. Surely, this is a clearance sale of old machines. Because the description stated that the system is Android 4.4,…

    Permanent link to “My New 'Toy' - E-ink Screen E-reader BOYUE LikeBook S61”

February 2024

  • English Learning…

    My boss sent a message in our office channel, which said she was WFH today, as "she have a bloke coming round to fix the garage door". BLOKE is a new word to me. so I learned this word today. Other learnings "得不偿失" in English can be translated as "not worth the loss" or "the gains do not justify the losses." "蒜苔" in English is "garlic scape" or simply "garlic shoots." "In and out promotion" 广告术语中指的是一种快速进行的促销活动,通常是短期的、迅速产生效果的宣传推广。这可能包括限时折扣、特价促销等手段,旨在迅速吸引顾客。 Every so often it'd rain. “Every so often"是固定搭配,表示“偶尔”或者“时不时的”。 My brother loved playing tag. 这句里的 tag 指的是一种游戏,即“追逐游戏”。通常几个人一起玩,其中一个人被标记 (tag)为追逐者,其他人则努力躲避追击者,避免被他/她触及到。 …more

    Permanent link to “English Learning Memo 1”
  • Moq tips 1 - learn…

    When should I use mockObject.Reset() and when should I use mockObject.Invocations.Clear()? In the context of using a mocking framework like Moq in C# for unit testing, the choice between mockObject.Reset() and mockObject.Invocations.Clear() depends on what you want to achieve. mockObject.Reset(): This is specific to the Moq library. It resets the mock object, removing any setups or custom behavior you might have defined for that mock. It does not clear recorded invocations; you can still access them after calling Reset(). Example: var mock = new Mock<MyClass>(); mock.Setup(x => x.MyMethod()).Returns("Original"); // ... code using the mock ... // Reset the mock, removing setups mock.Reset(); // Now, if you call the method, it won't use the previous setup var result = mock.Object.MyMethod(); mockObject.Invocations.Clear(): This clears the recorded invocations on the mock object. It doesn't affect setups or custom behavior. It just removes the history of invocations.…

    Permanent link to “Moq tips 1 - learn how to write unit tests from ChatGPT”

January 2024

  • A neat way to…

    We can get unexpected trailing zeros when we serialzie an object with decimal properties, normally it will not hurt. However, it does hurt when we want to compare two objects by serializing them to JSON string. I tried a few solutions and finally find the following one is the best. public static decimal Normalize(this decimal value) { return value/1.000000000000000000000000000000000m; } Reference

    Permanent link to “A neat way to remove trailing zeros from a decimal number in C#”
Archive of 2023