ChatGPT与代码克隆初探

  • 背景
  • 源代码克隆检测
    • 简单代码片段源代码克隆检测
    • 真实案例源代码克隆检测
    • 不同语言下ChatGPT检测语义相似度
  • 二进制代码相似度检测
    • 检测简单二进制代码片段
    • 真实案例二进制代码检测
  • ChatGPT对抗代码混淆
  • 总结

背景

ChatGPT是由OpenAI研发的大型语言模型,可以通过自然语言与人交互,回答问题或者执行任务。虽然ChatGPT已经在多类NLP任务中均取得显著成果,特别是在软件工程领域,但是目前还没有ChatGPT在代码克隆方向的专门测评。本文将使用基于GPT-3.5的ChatGPT 来测评其相似代码检测能力。
代码克隆分为Type1到Type4四种类型,其中Type1、2、3的检测方法已颇为成熟,我们主要聚焦ChatGPT在Type4类克隆的检测效果。

代码克隆类型
克隆类型 解释
Type1 仅有空行、空格和注释的区别
Type2 变量名、函数名、类名不同,其余完全相同
Type3 部分代码片段被修改,如增加、删除、移动部分代码片段
Type4 语法不同但是语义相似的代码

我们将以高级语言的源代码可执行文件的反汇编代码作为测试样例,这也是代码克隆领域通用的测试对象。

源代码克隆检测

我们首先对高级语言的源代码进行测试,希望得到ChatGPT对Type4类型克隆的检测能力。

简单代码片段源代码克隆检测

我们使用for和switch-case创建一些具有简单循环或者分支结构的C代码,然后使用if-else结构和while结构创建语义相同的代码制作匹配对作为正例,将不同语义的代码相互匹配作为反例。最后使用ChatGPT来检测其语法,结构,语义是否相似,以及是否是代码克隆。
我们的提问模板如下:

提问者:我希望你能进行代码克隆检测工作,接下来我将给你两个函数,请你判断两个函数是否是代码克隆?语法是否相似,结构是否相似,语义是否相似,功能是否相似?
Function1的代码
Function2的代码

对于简单的代码片段,ChatGPT不但能准确判断出两个代码片段的语法、结构以及语义相似性,同时能够对其进行简单的解释说明,甚至有时还能推测出代码的意图
以下面一组代码为例,这是分别通过switch-case和if实现的将第一个参数加一并输出的函数。ChatGPT不仅准确无误地判断出两个函数的语法、语义以及结构相似,并且给出了对应的解释说明。

int function1(int a, int b, int c) {switch (a) {case 1:a = 2;case 2:a = 3;case 3:a = 4;case 4:a = 5;default:a = 6;}printf("%d\n", a);return 0;
}
int function2(int a, int b, int c) {if (a == 1) { a = 2; }if (a == 2) { a = 3; }if (a == 3) { a = 4; }if (a == 4) { a = 5; }if (a != 1 && a != 2 && a != 3 && a != 4)a = 6;printf("%d\n", a);return 0;
}

ChatGPT: 语法相似:这两个函数的语法相似,它们都包含了三个参数(int类型的a、b、c),并且都返回了int类型的值。它们的结构也相似,都包含了一个控制流程语句(switch语句和if语句),并且都包含了类似的赋值操作和打印语句。
语义相似:这两个函数的语义也相似,它们的目的都是根据a的不同值,将a的值修改为另一个值,并输出修改后的a的值。尽管它们的实现方式略有不同,但它们的实现目的是相同的。
结构相似:这两个函数的结构相似,它们都包含了一个控制流程语句,且都在结尾处打印a的值,以此输出修改后的结果。
代码克隆:考虑到以上三点,可以认为这两个函数是代码克隆。它们的语法、结构和语义都非常相似,差异只是在实现方式和细节上。
综上所述,根据我对这两个函数的分析,我认为它们是代码克隆

值得注意的是,随着代码片段长度增加,以及两段代码的差异进一步扩大,ChatGPT虽然也能判断出语义(功能)相似,但是会认为两者不是代码克隆。此现象多次发生,在我们对其引导纠正后,ChatGPT能够发现自己的错误并给予纠正。
如下所示,这对函数的功能是用来计算一年的第几天,分别使用switch-case和if-else来实现,但是ChatGPT虽然辨别出两段代码功能相似,但是不认为两段代码是代码克隆,在经过人工指正后,ChatGPT可以发现自己逻辑上的漏洞并且给出正确答案。

int function1(int a, int b, int c)
{b1=b;int s = 0;switch (b1) {case 12:s += 30;case 11:s += 31;case 10:s += 30;case 9:s += 31;case 8:s += 31;case 7:s += 30;case 6:s += 31;case 5:s += 30;case 4:s += 31;case 3:s += 28;case 2:s += 31;case 1:s += a; break;}if (((c % 4 == 0 && c % 100 != 0) || (c % 400 == 0)) && (b > 2))  s++;return 0;
}
int function2(int a, int b, int c)
{int s = 0;if (b == 12)s = 30+31+30+31+31+30+31+30+31+28+31+a;
else if(b==11)s= 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31 + a;else if(b==10) s= 30 + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31 + a;else if(b==9)s= 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31 + a;else if(b==8)s= 31 + 30 + 31 + 30 + 31 + 28 + 31 + a;else if(b==7) s= 30 + 31 + 30 + 31 + 28 + 31 + a;else if(b==6)s= 31 + 30 + 31 + 28 + 31 + a;else if(b==5)s= 30 + 31 + 28 + 31 + a;else if(b==4)s= 31 + 28 + 31 + a;else if(b==3) s= 28 + 31 + a;else if (b == 2) s = 31 + a;else if (b == 1)s += a;if (((c % 4 == 0 && c % 100 != 0) || (c % 400 == 0)) && (b > 2))  s++;return 0;
}

ChatGPT: 这两个函数具有相似的结构和语义,都是根据年月日计算出该日期是一年中的第几天,但它们的语法不同。 function1 使用了 switch 语句,而 function2 使用了 if-else 语句。
因为这两个函数的代码不同,所以可以判断它们不是代码克隆。但是,它们执行的任务非常相似,都是计算一年中的某个日期,所以可以认为它们的功能相似
提问者:语义相同或者功能相同的代码是不是代码克隆?
ChatGPT: 代码克隆的定义是指两个或多个代码片段在形式上或语义上非常相似,以至于它们可以被视为从同一原型衍生而来。因此,如果两个代码片段在语义上或功能上非常相似,则可以被视为代码克隆。
提问者:那么为什么前面两个代码不算代码克隆?
ChatGPT: 前面的两个函数在语法和结构上很相似,但是它们在语义和功能上是不同的。例如,它们使用了不同的方式来计算每个月份的天数,其中一个使用了switch语句,而另一个使用了if-else语句。此外,它们在计算特定日期是否为闰年方面也使用了不同的方式。因此,尽管这两个函数有些相似,但它们并不是代码克隆。
提问者: 可是之前你说两个函数实现了相同的功能,而不是功能不同的函数?
ChatGPT: 非常抱歉,我的回答有误。您是正确的,两个函数实现了相同的功能,因此它们可以被视为代码克隆。我的回答可能引起了困惑。感谢您的纠正。

真实案例源代码克隆检测

我们从LeeCode平台上随机选取题目,并且捕获其评论区相同语言的不同答案作为语义相似的代码片段。为了防止代码注释和代码变量名的字面含义影响结果,我们首先对代码进行预处理:

  • 删除注释。
  • 将有意义的变量名更改为无意义的变量名。
  • 将有意义的字符串统一替换为空串。

ChatGPT对于大部分正例和几乎所有反例都有效,其中,ChatGPT认为代码语义相似但是不是代码克隆的情况依旧大量存在,鉴于ChatGPT并不是专门为了检测代码克隆所设计的模型,所以我们在这里放宽要求,只需要ChatGPT判断出代码语义相似或功能相似即可认为ChatGPT正确识别了代码克隆。
下图是两段题为K 个一组翻转链表的LeeCode代码,ChatGPT虽然认为两段代码不是代码克隆,但是准确识别出两段代码的意图,因此,我们认为ChatGPT识别出了代码语义相似和代码克隆。

K 个一组翻转链表题目详细描述:
给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

struct ListNode* a10(struct ListNode* a4, int k){struct ListNode* a1;struct ListNode* a2;struct ListNode* a3;if(a4 == NULL) return NULL;int i = 0;a3 = a4;for(i = 0; i < k; i++){if(a3 != NULL){a3 = a3->next;}else{return a4; }}a2 = a4;a1 = a2;a3 = a2->next;for(i = 1; i < k; i++){if(a3){a1->next = a3->next;a3->next = a2;a2 = a3;a3 = a1->next;}}
a1->next = a10(a3,k);
}
struct ListNode *a10(struct ListNode *a4, int k)
{struct ListNode *a6 = a4;struct ListNode *a5 = NULL;
struct ListNode a7 = {0};struct ListNode **a8 = (struct ListNode **)malloc(sizeof(struct ListNode *) * k);memset(a8, 0, sizeof(struct ListNode *) * k);a7.next = a4;a5 = &a7;while (a6 != NULL) {int a9 = 0;while (a9 < k && a6 != NULL) {a8[a9] = a6;a9++;a6 = a6->next;}if (a9 != k) {break;}while (a9 > 0) {a5->next = a8[a9 - 1];a5 = a5->next;a9--;}a5->next = a6;}free(a8);return a7.next;
}

ChatGPT: 这两个函数的名称和参数列表相同,但是它们的实现是不同的。它们的语法和结构略有不同,但它们的功能和语义相似。这是两个不同的函数,不是代码克隆。

此外,一个有趣的现象是ChatGPT每次的回答似乎并不一致,甚至能得到完全相反的结论,依旧是上面的例子,在多次重复提问后,ChatGPT关于语义相似度和代码克隆的判断上多个截然相反的答案。

ChatGPT: 这两个函数的语法和结构不同,因此它们不是代码克隆。虽然它们的名称和参数相同,但是它们的实现方式不同,使用了不同的变量和逻辑。此外,它们的功能也不完全相同。第一个函数是将链表的每个K个节点进行翻转,而第二个函数是将链表的每个K个节点进行翻转,但是递归地实现了这个过程。因此,虽然它们的名称相同,但它们的语义和功能并不相同。

ChatGPT: 这两个函数的名称和参数列表相同,但是它们的实现是不同的。它们的语法和结构略有不同,但它们的功能和语义相似。这是两个不同的函数,不是代码克隆。

ChatGPT: 这两个函数看起来非常相似,它们都是用来反转链表中每个长度为k的子链表。它们的语法和结构几乎一模一样,都使用了相同的变量名和逻辑结构。但是,第一个函数使用了一个额外的指针,而第二个函数则使用了递归实现。因此,虽然它们的语法和结构非常相似,但它们的语义和功能也略有不同。因此,可以将它们视为代码克隆的变体。

ChatGPT: 这两个函数看起来很相似,但是并不完全相同。它们都接受一个链表和一个整数 k 作为输入,将链表按照每 k 个节点进行反转。然而,它们的具体实现略有不同。
对于语法和结构相似性的检测,这两个函数之间的相似性非常高,它们使用了类似的变量名、数据结构、控制流结构和内存分配等。可以看出这些代码在某种程度上具有一定的复制粘贴的痕迹。
对于语义和功能的相似性检测,我们需要更深入地了解代码的行为。这两个函数的基本逻辑是一致的:对于每个长度为 k 的子链表,将其翻转,然后将它们按照原始顺序重新连接。然而,它们的具体实现略有不同。
在第一个函数中,它首先用一个指针数组 a8 存储子链表中的所有节点。然后,它使用两个 while 循环来反转子链表。在外部循环中,它将节点分组并将它们存储在 a8 数组中,然后在内部循环中将它们反转。在完成反转后,它将子链表重新连接到链表的尾部。
在第二个函数中,它首先使用一个循环来找到第 k 个节点,然后将它保存在变量 a3 中。接下来,它使用 a1 和 a2 指针来迭代地反转子链表,直到最后一个子链表被反转。在这个过程中,它将子链表的头节点和尾节点依次连接起来,形成一个反转后的子链表。在完成整个过程后,它使用递归来连接剩余的子链表。
因此,这两个函数虽然在代码层面上非常相似,但在实现细节和代码风格上有所不同。从功能上看,这两个函数具有相同的目标,但是它们的实现方式不同。因此,我们不能完全将它们视为代码克隆。

不同语言下ChatGPT检测语义相似度

在这里我们选择了一组不同寻常的设置,我们选择LeeCode下同一题目不同语言的实现方案,传统代码克隆仅仅检测相同语言下的代码相似度,比较不同语言下的代码相似度似乎并没有现实意义。但是这进一步降低了语法和结构的相似性,而专注于检测两段代码是否功能相似。结果显示,ChatGPT依旧具有较高的表现。
下图依旧是两段题为K 个一组翻转链表的LeeCode代码,左右两边分别由C语言和Python编写。让我们忽略ChatGPT对于代码克隆部分的判断,仅仅关注其对语义的解析和语义相似度的判断。令人震惊的是,ChatGPT确实能够成功判断出两段代码语义相似。

struct b3 *a10(struct b3 *a4, int k)
{struct b3 *a6 = a4;struct b3 *a5 = NULL;
struct b3 a7 = {0};struct b3 **a8 = (struct b3 **)malloc(sizeof(struct b3 *) * k);memset(a8, 0, sizeof(struct b3 *) * k);a7.next = a4;a5 = &a7;while (a6 != NULL) {int a9 = 0;while (a9 < k && a6 != NULL) {a8[a9] = a6;a9++;a6 = a6->next;}if (a9 != k) {break;}while (a9 > 0) {a5->next = a8[a9 - 1];a5 = a5->next;a9--;}a5->next = a6;}free(a8);return a7.next;
}
class Solution:def b1(self, b2: b3, b6: b3):b7 = b6.nextp = b2while b7 != b6:nex = p.nextp.next = b7b7 = pp = nexreturn b6, b2def b11(self, b2: b3, k: int) -> b3:b4 = b3(0)b4.next = b2b5 = b4while b2:b6 = b5for i in range(k):b6 = b6.nextif not b6:return b4.nextnex = b6.nextb2, b6 = self.b1(b2, b6)b5.next = b2b6.next = nexb5 = b6b2 = b6.nextreturn b4.next

ChatGPT:这是一个很有趣的问题。代码克隆检测是指在不同的代码片段中寻找相似的结构和语法,判断它们是否具有相似的功能和语义。通常,这项任务需要利用计算机科学中的算法和技术来实现。
在这种情况下,给出的两个函数看起来是不同的,它们的语法和结构都不相似。然而,它们可能具有相似的功能和语义,这是一项更为复杂的任务,需要更加深入的分析。
因此,我将对给出的两个函数进行以下分析:
第一个函数的功能是对链表进行k个一组的翻转,并返回新的链表头。它通过循环遍历链表,并使用动态数组来存储每组k个节点,然后将它们翻转并重新链接回原始的链表。
第二个函数的功能是对链表进行k个一组的翻转,并返回新的链表头。它使用递归和双指针的方法,将链表分为k个一组进行翻转,并将它们链接回原始的链表。
因此,这两个函数的功能和语义是相似的,它们都实现了对链表进行k个一组的翻转。然而,它们的实现方式是不同的,语法和结构也是不同的,因此它们不是代码克隆。
总的来说,代码克隆检测是一项非常复杂的任务,需要深入分析代码的语法、结构、功能和语义。在这种情况下,尽管这两个函数具有相似的功能和语义,但是它们的实现方式是不同的,因此它们不是代码克隆。

二进制代码相似度检测

与源代码克隆检测不同的是,二进制代码克隆检测需要将二进制可执行文件转化为汇编文件来进行比较。幸运的是,目前的反汇编工具十分成熟,我们可以直接将gcc编译的二进制文件转化为反汇编文件,来比较其代码相似度。

检测简单二进制代码片段

我们先使用简单的if-else、while和switch-case、for的结构变化来构建源代码克隆,并且将其对应的二进制可执行文件转化为汇编代码,来检测ChatGPT对二进制代码的检测能力。
总体而言,ChatGPT在简单的二进制代码片段下依旧可以发挥不错的效果。下图是两个简单的条件判断函数,分别使用switch-case和if-else来实现,可以看到,ChatGPT能够准确判断出得到两段代码是代码克隆。

            public _002a
_002a       proc near
var_C       = dword ptr -0Ch
var_8       = dword ptr -8
var_4       = dword ptr -4endbr64push  rbpmov   rbp, rspsub   rsp, 10hmov   [rbp+var_4], edimov   [rbp+var_8], esimov   [rbp+var_C], edxcmp   [rbp+var_4], 4jz    short loc_130Bcmp   [rbp+var_4], 4jg    short loc_1312cmp   [rbp+var_4], 3jz    short loc_1304cmp   [rbp+var_4], 3jg    short loc_1312cmp   [rbp+var_4], 1jz    short loc_12F6cmp   [rbp+var_4], 2jz    short loc_12FDjmp   short loc_1312
loc_12F6:               mov   [rbp+var_4], 2
loc_12FD:                mov   [rbp+var_4], 3
loc_1304:                mov   [rbp+var_4], 4
loc_130B:              mov   [rbp+var_4], 5
loc_1312:               mov   [rbp+var_4], 6mov   eax, [rbp+var_4]mov   esi, eaxlea   rdi, format  mov   eax, 0call  _printfmov   eax, 0leaveretn
_002a           endp
            public _002a
_002b       proc near
var_C       = dword ptr -0Ch
var_8       = dword ptr -8
var_4       = dword ptr -4endbr64push  rbpmov   rbp, rspsub   rsp, 10hmov   [rbp+var_4], edimov   [rbp+var_8], esimov   [rbp+var_C], edxcmp   [rbp+var_4], 1jnz   short loc_1358mov   [rbp+var_4], 2
loc_1358:        cmp   [rbp+var_4], 2jnz   short loc_1365mov   [rbp+var_4], 3
loc_1365:               cmp   [rbp+var_4], 3jnz   short loc_1372mov   [rbp+var_4], 4
loc_1372:    cmp   [rbp+var_4], 4jnz   short loc_137Fmov   [rbp+var_4], 5
loc_137F:             cmp   [rbp+var_4], 1jz    short loc_139Ecmp   [rbp+var_4], 2jz    short loc_139Ecmp   [rbp+var_4], 3jz    short loc_139Ecmp   [rbp+var_4], 4jz    short loc_139Emov   [rbp+var_4], 6
loc_139E:                 mov   eax, [rbp+var_4]mov   esi, eaxlea   rdi, format  mov   eax, 0call  _printfmov   eax, 0leaveretn
_002b       endp

ChatGPT:这两个函数非常相似,它们的结构、语法和语义都非常相似,甚至它们的功能也非常相似。虽然函数名不同,但它们的代码非常相似,因此可以认为它们是代码克隆
这两个函数的主要区别在于以下几点:
函数名称不同;
在 _002a 函数中,有多个条件判断,而在 _002b 函数中,只有一个条件判断;
在 _002a 函数中,每个条件判断后面都有一段重复的代码,而在 _002b 函数中,只有最后一个条件判断后面有一段重复的代码。
因此,可以推断出 _002b 函数是从 _002a 函数中复制和粘贴的代码,只是稍微修改了一些代码,以便更好地满足 _002b 函数的需求。

值得注意的是,ChatGPT在对源码克隆检测结果和对应的二进制代码克隆检测结果存在不一致的情况。两个函数在源代码检测时可能认为是语义相似,而在二进制代码检测时会被认为是语义不同,或者是相反的情况。根据观察,这可能是由于编译器会将源代码相似的结构经过优化,转化成不相似的结构。比如switch-case也可能会被设置为二分查找或者跳转表,从而更改与变量的比较方式,而if-else并不会进行类似优化。

真实案例二进制代码检测

遗憾的是,ChatGPT对于真实情况下的二进制代码克隆检测并不理想,这主要是由于ChatGPT的目的是基于GPT-3模型设计的对话模型,而不是一个专门的代码克隆检测模型。GPT-3模型要求输入的token最多不能超过2048个,而真实案例的汇编代码很容易超过这个限制,即使是一些没有超过这个限制的代码,ChatGPT通常也不会给出期望的回答

ChatGPT:这两个函数都非常长,因此无法直接判断它们是否是代码克隆。一种常见的方法是使用代码克隆检测工具。目前有很多代码克隆检测工具可供选择,例如Simian、CloneDR、CCFinderX、NICAD等。
以Simian为例,您可以在其官方网站(https://www.harukizaemon.com/simian/index.html)上下载Simian的最新版本。安装完毕后,您可以使用以下命令来检测这两个函数是否是代码克隆:
simian --language cplusplus function1.cpp function2.cpp
其中,function1.cpp和function2.cpp是包含这两个函数代码的源文件。如果这两个函数是代码克隆,Simian将输出一条包含相似度和重复行数的信息。
当然,您还可以使用其他代码克隆检测工具进行检测。不同的工具可能具有不同的检测方法和算法,因此检测结果可能会有所不同

ChatGPT:这两个函数在汇编层面的代码非常相似,但是由于缺乏上下文信息,我无法确认它们是否是代码克隆。如果您能提供更多信息,比如两个函数的语言、目的、上下文、来源等等,我就可以更加准确地回答这个问题

ChatGPT对抗代码混淆

代码混淆,是指将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为。其中一种常见的混淆策略便是流混淆,即模糊代码的控制流,在不改变代码运行行为的基础上增加阅读的困难。我们采取手工添加伪指令流的策略,如下图所示,我们在左边的switch-case里采用了伪路径“case:2”,因为switch里是一个bool类型变量,其值只能是0或1,所以“case:2”是不可能运行的路径。可以观察到,ChatGPT并没有意识到这一点。

int _045a(int a, int b, char c)
{switch (a > 5){case 0:printf("this is 0\n");break;case 1:printf("this is 1\n");break;case 2:printf("this is 2\n");break;default:printf("this is default\n");return 0;}
}
int _045b(int a, int b, char c)
{if(a>5)printf("this is 1\n");else printf("this is 0\n");return 0;
}

ChatGPT:这两个函数并非代码克隆,尽管它们执行相似的操作,但它们的语法、结构和语义不同。具体来说:
语法不同:第一个函数使用了switch语句,而第二个函数使用了if-else语句。这两种语句的语法不同。
结构不同:第一个函数使用了switch语句,其中有三个case语句和一个default语句。而第二个函数只使用了if-else语句。这两个函数的结构不同。
语义不同:尽管这两个函数执行的是相似的操作,但它们的语义不同。第一个函数会打印出不同的消息,具体取决于a是否大于5。而第二个函数只会打印出两个固定的消息,即“this is 0”和“this is 1”
因此,这两个函数不是代码克隆。

总结

总而言之,ChatGPT作为自然语言模型,在简单代码片段的克隆检测上乃至源代码的一些真实案例上取得了耀眼的表现,不但能够准确识别代码结构,并且能得到代码的语义,甚至能推测出代码的目的。但是在长片段的汇编代码上,ChatGPT的效果会产生显著下滑,经常出现无法判断的情况,哪怕两段代码极其相似。
此外,ChatGPT目前还会被代码混淆所欺骗,并不能得到代码混淆下的真实语义,攻击者很容易通过伪造不可达路径来逃避代码克隆检测。并且需要注意的是,ChatGPT在理解代码语义时,极易受到代码中有意义的字符干扰,如变量名、注释等。并且在解释语义时也会趋向于这些字符的含义,攻击者也可能通过字符串或者变量名替换,乃至添加无意义的长字符串来逃避代码克隆检测。

南开大学软件安全与测试研究室

王乾潞 王佩婕 过辰楷   

ChatGPT与代码克隆初探相关推荐

  1. Boreas: 一种基于token 的精确并且大规模检测代码克隆的方法

    文章连接: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=6494937 写在前面的话 代码克隆检测的方法有很多,比如说 te ...

  2. CopyCat 代码克隆检测发布,剑指开源软件抄袭

    2019独角兽企业重金招聘Python工程师标准>>> 运营开源中国社区 10 年时间,对国内开源发展之迅猛非常的欣慰,但同时也存在很多问题是我们难以忽视的.其中一个对开源生态发展杀 ...

  3. 语义级代码克隆检测数据集的评估与改进

    摘要:应用深度学习来检测语义代码克隆受到了研究界的广泛关注. 本文分享自华为云社区<语义级代码克隆检测数据集的评估与改进>,作者:软件分析Lab. 一.背景介绍 代码克隆检测[1]是软件工 ...

  4. ChatGPT+低代码,将干掉40%的程序员

    作者| Mr.K   编辑| Emma 来源| 技术领导力(ID:jishulingdaoli) 关于程序员失业有个段子:拖拽建站出来的时候,他们人说程序员会失业:低代码出来了,他们说程序员会失业:C ...

  5. 类ChatGPT逐行代码解读(2/2):从零起步实现ChatLLaMA和ColossalChat

    本文为<类ChatGPT逐行代码解读>系列的第二篇,上一篇是:如何从零起步实现Transformer.ChatGLM 本文两个模型的特点是加了RLHF 第六部分 LLaMA的RLHF版:C ...

  6. ChatGPT实现代码解释

    代码解释 新手程序员在入门之初,最好的学习路径就是直接阅读其他人的代码,从中学会别人是怎么写的,为什么这么写.过去,这个学习过程可能需要广泛阅读官方文档,在 GitHub issue 上提问,上 St ...

  7. 利用chatgpt+低代码技术搭建进销存系统

    1 前言 在当今数字化时代,企业管理系统已经成为各行各业不可或缺的一部分.而进销存系统更是企业管理中的重要组成部分,它可以帮助企业实现产品库存管理.采购管理.销售管理等多个方面的自动化管理. 然而,搭 ...

  8. 零基础也能用ChatGPT写代码,简直不要太爽

    最近朋友圈刷到最多的动态和话题都是围绕ChatGPT的,作为一个功能强大,用途广泛的聊天机器人,我们能用它做的事情太多了.比如用它写文案,写剧本,规划旅游路线,甚至写小说等等.在本文中,我们将探索如何 ...

  9. 体验chatGPT编写代码

    今天注册了openAI账号,并且体验了以下chatGPT.体验过程中,我明显感觉到chatGPT不是所谓的"人工智障",比起原来简单的问答机器人有了巨大的进步. 我主要体验的是ch ...

最新文章

  1. mysql 导入CSV数据 [转]
  2. C语言技巧之长度为0的数组
  3. 云化要求下,数据库架构如何演进?
  4. 苹果面向Mac发布英特尔处理器漏洞缓解措施
  5. Spring MVC DispatcherServlet改造为 CSE RestServlet 常见问题汇编
  6. [似水流年]夜色渐深窗内静坐有感
  7. 电脑系统及软件安装日期查看
  8. Hacking Diablo II之完整性检查(Integrity Scan)
  9. 记一次spring5源码完整编译过程
  10. 质量团队在VUCA时代如何走?
  11. 绝世巨作,阿里架构师著作的《架构解密:从分布式到微服务》来了
  12. C++中指针前还加是什么意思
  13. idea鼠标控制放大缩小的操作
  14. 西门子PLC远程监控与数据采集方案
  15. 联想计算机g480开不开机,联想G480笔记本进入不了bios怎么办_联想笔记本G480无法进入BIOS如何解决...
  16. mac性能比服务器好,性能上再次交锋 三大最新OS测试大比拼
  17. IDEA报错:Plugin ‘org.springframework.boot:spring-boot-maven-plugin:‘ not found
  18. 大概是全网最详细的Electron ipc 讲解(一)——主进程与渲染进程的两情相悦
  19. Echarts—地图的基本实现
  20. 关于存储优化型实例和大型数据仓库EC2实例选型

热门文章

  1. python基础之数据类型-面向对象
  2. ubuntu重启sshd
  3. RMSpro优化器中rho与decay 两参数的区别(keras)
  4. python的布尔类型
  5. Java面试都只是背答案吗?
  6. 服务器日志修改密码怎么查看,服务器修改密码日志
  7. python histogram equalization
  8. 技术管理从入门到提高:RRR技术管理框架
  9. 高通平台 efs.mbn的制作与修改
  10. python中同名函数