编程语言中的线程安全

当前冯诺依曼体系下所谓的并行安全,就是那几种模式的,rust也不例外。 据我个人所知,并行只有

  1. 锁死竞争: 各种锁或原子操作
  2. 不可变: 共享的都是只读的
  3. 隔离:没有竞争,也就没有所谓的安全问题了。 其他各种手段也都是这几种基本做法的调优和组合。 针对变成语言提供的所谓线程安全:
  4. C/C++ 是默认不优先使用任何一种而已。
  5. Rust只是默认用了 不可变 ,提供了 锁/原子 而已。
  6. Go和erlang是默认提供 隔离 方式,然后基于隔离又提供了一套通讯机制。 所谓并发语言,也就是提供了优选机制,把此机制用语法糖 好用了而已。

大模型高效沟通的技巧

一、 核心心态:把AI当作“超级实习生”

和AI沟通最有效的心态是:把它想象成一个能力超强、知识渊博、但缺乏常识和背景信息的实习生。

  • 它不会读心术:你必须清晰地交代背景、目标和约束条件。
  • 它非常听话:你的指令越精确,它的产出越符合预期。
  • 它会犯错:你需要像导师一样,检查、追问、纠正它的输出。

记住这个黄金法则:垃圾进,垃圾出。你输入的提示词质量,直接决定了输出的质量。


二、 提问的基本规范与结构

一个高质量的提问,通常包含以下四个要素。你可以把它看作一个万能公式:

1. 角色

  • 是什么:明确你希望AI扮演什么角色。
  • 为什么:这能设定对话的基调和知识领域,让AI使用更专业的语言和思维模式。
  • 示例
    • ❌ “写一份市场计划。”
    • ✅ “请你作为一名资深市场营销总监,为一款新的低碳水化合物能量棒制定一份进入中国市场的初步计划。”

2. 任务/目标

  • 是什么:清晰、具体地说明你要它做什么。
  • 为什么:避免模糊不清的目标,导致AI自由发挥。
  • 示例
    • ❌ “介绍Python。”
    • ✅ “用比喻的方式,向一个10岁的小孩解释Python编程语言是什么,以及它能做什么。

3. 背景/上下文

  • 是什么:提供与任务相关的必要信息。
  • 为什么:让AI的理解和输出更具针对性和实用性。
  • 示例
    • ❌ “帮我优化简历。”
    • ✅ “我是一名有3年工作经验的前端工程师,精通Vue.js和React,现在想申请一家跨境电商公司的Senior前端岗位。请根据这个背景优化我的简历。

4. 要求/格式

  • 是什么:对输出的格式、风格、长度等提出具体要求。
  • 为什么:直接获得你想要的成果,节省后续调整的时间。
  • 示例
    • ❌ “列出学习步骤。”
    • ✅ “请用Markdown列表的形式,输出一个为期3个月的入门级吉他学习计划,包括每周的目标和练习建议。

三、 核心提示词技巧

1. 零样本、单样本、少样本提示 这是最重要的技巧之一,用于“教”AI你想要的格式或风格。

  • 零样本:不给示例,直接给指令。适合简单任务。
    • 把这句话翻译成法语:"你好,世界。"
  • 单样本/少样本:提供一个或多个输入-输出的例子,让AI模仿。
    • 输入把“我很开心”变得更文艺。
    • 输出我的心中绽开了万朵繁花。
    • 你的指令请模仿上面的风格,把“天气很好”变得更文艺。
    • (AI可能会输出:“天空澄澈得如同一块无瑕的蓝宝石。”)

2. 链式思考 对于复杂问题,要求AI“一步步思考”或“展示推理过程”。这不仅能得到更准确的答案,还能让你检查它的逻辑。

  • 示例
    • Q:一个篮子里有5个苹果,你拿走了2个,又放进去了3个,然后吃掉了1个,最后还剩几个?请一步步思考。
    • (AI会展示:初始5个 -> 拿走2剩3 -> 放进3剩6 -> 吃掉1剩5 -> 所以答案是5个)

3. 分隔符的运用 当你的提示词很长或包含多部分内容时,使用分隔符(如"""---, ““等)能让结构更清晰,避免AI混淆。

  • 示例

    请根据以下用户信息和产品描述,写一封个性化的推荐邮件。
    
    用户信息:
    """
    - 姓名:李华
    - 最近购买:笔记本电脑
    - 兴趣:编程、效率工具
    """
    
    产品描述:
    """
    产品名:CodeMaster Pro
    类型:订阅制代码编辑软件
    特点:AI代码补全、云端同步、团队协作
    """

4. 正面与负面指令 明确告诉AI要做什么,以及不要做什么

  • 示例写一篇关于人工智能的短文,要求:积极正面,面向大众,语言通俗。**不要使用专业术语,不要讨论伦理风险。**

四、 进阶策略与避坑指南

1. 迭代式提问 很少有复杂问题能一次就得到完美答案。把与AI的对话看作一个迭代过程

  • 示例流程
    1. 给我一些关于新媒体运营的文章标题创意。
    2. (得到10个标题)
    3. 我喜欢第3个和第7个的风格,再给我生成5个类似风格的,但要侧重于“小红书”平台。
    4. 把这5个标题扩展成小红书笔记的正文大纲,要求包含emoji和热门话题标签。

2. 利用“继续”功能 如果AI的回答在中间被截断,只需输入 继续请继续,它通常会从断点接着输出。

3. 提供外部文本 如果问题涉及一段具体的文字(如修改、总结、分析),最好直接将文本粘贴进对话框,而不是让AI自己去“想象”或“搜索”。

4. 核查事实与逻辑 最重要的一点: AI(尤其是我)可能会“一本正经地胡说八道”,产生看似合理但完全不正确的内容(这被称为“幻觉”)。对于关键信息、数据、公式、法律条文、医疗建议等,务必通过权威来源进行二次核实


总结:一个优秀提示词的模板

你可以用下面的模板来组织你的复杂提问:

【角色】
请你扮演一个 [具体的角色,如:资深产品经理、文学评论家、风趣的科普作家]。

【任务】
我的任务是 [清晰描述你的最终目标]。

【背景】
相关背景信息如下:
- [背景点1]
- [背景点2]
- ...

【要求】
请按以下要求输出:
1. 格式:[如:一份包含5个要点的列表、一篇800字左右的文章、一个JSON对象]。
2. 风格:[如:专业严谨、幽默风趣、简洁明了]。
3. 其他:[如:避免使用“首先、其次”之类的词、用中文成语、附上英文翻译等]。

掌握这些技巧后,你将从一个被动的信息接收者,转变为主动的“AI驾驶员”,真正利用好这项强大的工具。祝你使用愉快!

不如D:D语言GC暂停时间简单测试

注:测试不严谨,只是为了了解下D语言GC不同堆下暂停情况,目的是为了根据实际项目使用部分@nogc进行堆大小控制。实际情况下堆中一般还有string,ubyte[]等一些可以块跳过扫描的,理论上暂停会更小

D 语言默认GC算法

D语言默认是保守式扫描清除算法。默认执行时期为 新分配内存,GC堆中可用内存不足时才触发(也就是如果欲分配堆够大,并且手动归还GC内存,GC堆中一直有可分配内存就不出触发GC)。D的GC使用的算法比较简单,GC耗时主要在标记和清除两个阶段。其中标记是GC增加的耗时,清除是不可避免的耗时,只是清除是把原来手动管理散点式,集中起来一起执行(RC可能出现集中清除产生的短暂暂停)。GC标记时程序会STOP THE WORLD(暂停程序所有线程执行),这个耗时也就是大家常说的GC暂停时间。GC清除时间只会占用启动GC的线程。GC标记的时间受堆大小与存活对象数量相关,GC清除与不存活对象数目相关。

触发GC的执行工作流程:

  1. 停止除了分配内存的当前线程外的所有受GC管理的线程(core.thread新建的线程,以及thread_attachThis的线程)(STOP THE WORLD开始)。
  2. 劫持当前线程开始GC工作(分配逻辑转而调用GC收集工作)。 继续阅读“不如D:D语言GC暂停时间简单测试”

不如D:Dlang(D语言)下ARM嵌入式板子开发

最近自己开发一个板子上的数据处理与转发。无需UI,本来都是基于Qt/C++进行板子开发的。但是不同型号和板子基本都是靠厂商的虚拟机开发。于是想到之前用Dlang支持交叉编译的,于是测试了下Dlang下ARM嵌入式开发,结果让人惊喜。十分愉快。 Dlang进行ARM开发基于LDC,可以选择完全betterC或完整D语言。本次小项目考虑周边的库,就采用的完整D语言开发的方案。至于GC,作为一个安全的内存池使用。

开发依赖:

  • Linux 主机,因为基本ARM交叉编译GCC都是linux运行的,我是在 openSUSE-Tumbleweed下
  • LDC 编译器,dmd不支持arm,需要使用LDC
  • arm-gcc 交叉编译器(开发板厂家会提供,只需要C语言编译器就行。)

    开发步骤:

    1. 交叉编译 DRuntime 和 Phobos
    2. 配置LDC交叉编译的依赖库和链接器(GCC)
    3. 使用D语言编写程序(注意依赖,如果依赖需要C库,相应库也需要交叉编译)
    4. 进行交叉编译程序(dub build –compiler=ldc2 –arch=你的交叉编译配置)

继续阅读“不如D:Dlang(D语言)下ARM嵌入式板子开发”

记一个QSharedPointer 和 QTcpsocket一起使用的断开连接导致段错误问题

记一个QSharedPointer 和 QTcpsocket一起使用的断开连接导致段错误问题

写了一个简易的TCPserver,需要很多回调需要socket再回调内写数据,就需要保证回调执行的时候,socket不能被删除,所以采用智能指针老保证QTcpSocket 类的生命周期,加上本地管理,写了如下代码: 继续阅读“记一个QSharedPointer 和 QTcpsocket一起使用的断开连接导致段错误问题”

格局,经历与读书

格局

格局是一个人的上限。就如你人生的容量,如果格局太小,就是在多的财富,在多的福气,你也接受不了的,会很快散尽的。 犹若水桶,你就一个1L的水桶,一下给你10L的水(运来),也只是从你这不断的溢出而已,等注入结束(运去)你最多也就剩下1L而已,而一般这样的大水流(大运)是冲击较大的,等去了,你其实1L也不会满的。 继续阅读“格局,经历与读书”

查找bug原因的一些个人经验

今天知乎看到别人问《老程序员解bug有那些通用套路?》 就总结了下自己的方法,回答了下。罗嗦了不少字,就摘出来了。


个人经验和操作:

根据实际情况步骤会有跳过和循环。

1. 弄清楚环境

  • 1.1 对于客户端和偏硬件的,环境影响很大的,可能是某地方兼容没做好,或者直接没支持。
  • 1.2 对于 server 端, 依赖的的内核或者某个dll版本不对,功能异常或者直接崩溃都有可能。 继续阅读“查找bug原因的一些个人经验”

不如D:3)从输出hello说起

此篇开始不如D系列正式开始D语言的一系列教程。本系列非系统性教程,对于一些基本概念和约定很多都不会介绍,而且地方会与其他语言对比。笔者设想的思路是从例子入手,面向有编程基础的人士,一篇处理一个例子,在解释例子的同时,引入D语言的一些特性介绍和使用教程。这就注定不会有完全整体的教程顺序和很详细的基础介绍。如果想完整的学习D语言,可以先把《D语言程序设计》(百度网盘下载) 这本书过一下(注:D语言发展很快,书中有的细节在最新编译器下已经有不适用的地方了。此书也比较基础,D的高级用法很多都未提及)。由于笔者没有经验和角度已经不完全新手新手,可能行文的顺序和侧重点比较乱。有不足之处还请评论指出。

Hello World

说到编程语言,开篇地一个教程例子,非hello world莫属。我们也就先学习和分析D中的hello world。

import std.stdio;

int main() 
{
    writeln("Hello world!"); // 输出 Hello world 到控制台
    return 0;
}

继续阅读“不如D:3)从输出hello说起”

不如D:2)官网主页例子解析

这篇,我们先从进入官网的例子开始见识下D的强大。

此篇不是入门介绍,没有D基础,不要深究里面的实现细节,当开阔眼界即可。

进入D官网,就有一个例子,那个例子加上注释也就17行代码, 真正main函数里就一句代码,但是却完成了:从控制台按行读取,然后正则提取可能是浮点数的数,把其替换为四舍五入后的整数,然后在输出。 继续阅读“不如D:2)官网主页例子解析”

不如D:1)开篇说明

想写个D的系列介绍和用法的想法有很长时间了,但是由于个人比较懒惰,而且写作不及格,一直迟迟没有动手。今天在知乎上又看到rust和kotlin的专栏了,就决定必须动手了。

这两年用D语言,也算入门了,应该不会出现误人子弟的错误,自己写作向来没有条理,也希望能组织出来条理, 继续阅读“不如D:1)开篇说明”