目录
在AI元年后,作为一名程序员,相信各位友友已经深切地感受到了它带来的变革。作为一个从小白到资深码农的过来人,我是深有感触的:曾经我被繁重的开发任务、无尽的文档编写和棘手的代码问题所困扰。然而现在,有了AI的加持,我团队的小伙伴们好幸福!大家仿佛置身于Google的轻松工作氛围之中,从容不迫地享受着编程的乐趣。
1.提高编写开发日报的效率
记得以前,每次编写代码后,每天我都要花费时间和精力去编写开发卷宗(就是现在各位的老板要求的工作日志,相信大家已经深恶痛绝了)。编写开发卷宗可以确保每一步的改动都有据可查。而现在,AI成了我的得力助手。它不仅能快速分析我的代码变更,还能自动提炼出完成任务的情况,一键生成详尽的开发卷宗。这让我感到无比的轻松,仿佛拥有了超能力。
比如今天你完成了下面一段代码:
#include "stdafx.h"
#include <stdio.h>
#include "malloc.h"
#include "UTF8ToUnicode.h"
#include <windows.h>
// 这是导出变量的一个示例
UTF8TOUNICODE_API int nUTF8ToUnicode = 0;
// 这是导出函数的一个示例。
UTF8TOUNICODE_API int fnUTF8ToUnicode(void)
{
return 42;
}
extern "C" __declspec(dllexport) int Hello()
{
int a = 10, b = 2;
return a + b;
}
extern "C" __declspec(dllexport) unsigned char* PrintUtf8String(char *pUTF8Str)
{
unsigned char* pszGBK;
int nLen = 0;
pszGBK = UTF8ToGBK((unsigned char*)pUTF8Str, &nLen);
//
//FreeConvertResult(pszGBK);
return pszGBK;
}
int WTC(unsigned char * pUTF8Str, unsigned char * pGBKStr, int nGBKStrLen);
int CTW(unsigned char * lpGBKStr, unsigned char * lpUTF8Str, int nUTF8StrLen);
extern "C" __declspec(dllexport) unsigned char * UTF8ToGBK(unsigned char * pUTF8Str, int * nLen)
{
unsigned char * pGBKStr = NULL;
int nRetLen = 0;
nRetLen = WTC(pUTF8Str, NULL, 0);
(pGBKStr) = (unsigned char *)malloc((nRetLen + 1) * sizeof(char));
if ((pGBKStr) == NULL)
return 0;
*nLen = WTC(pUTF8Str, (pGBKStr), nRetLen);
return pGBKStr;
}
extern "C" __declspec(dllexport) unsigned char * GBKToUTF8(unsigned char * pGBKStr, int * nLen)
{
unsigned char * pUTF8Str = NULL;
int nRetLen = 0;
nRetLen = CTW(pGBKStr, NULL, 0);
(pUTF8Str) = (unsigned char *)malloc((nRetLen + 1) * sizeof(char));
if ((pUTF8Str) == NULL)
return 0;
*nLen = CTW(pGBKStr, (pUTF8Str), nRetLen);
return pUTF8Str;
}
int WTC(unsigned char * pUTF8Str, unsigned char * pGBKStr, int nGBKStrLen)
{
wchar_t * lpUnicodeStr = NULL;
int nRetLen = 0;
if (!pUTF8Str) //如果GBK字符串为NULL则出错退出
return 0;
nRetLen = MultiByteToWideChar(CP_UTF8, 0, (char *)pUTF8Str, -1, NULL, 0); //获取转换到Unicode编码后所需要的字符空间长度
//lpUnicodeStr = new WCHAR[nRetLen + 1]; //为Unicode字符串空间
lpUnicodeStr = (WCHAR *)malloc((nRetLen + 1) * sizeof(WCHAR)); //为Unicode字符串空间
if (lpUnicodeStr == NULL)
return 0;
memset(lpUnicodeStr, 0, (nRetLen + 1) * sizeof(WCHAR));
nRetLen = MultiByteToWideChar(CP_UTF8, 0, (char *)pUTF8Str, -1, lpUnicodeStr, nRetLen); //转换到Unicode编码
if (!nRetLen) //转换失败则出错退出
return 0;
nRetLen = WideCharToMultiByte(CP_ACP, 0, lpUnicodeStr, -1, NULL, 0, NULL, NULL); //获取转换到UTF8编码后所需要的字符空间长度
if (!pGBKStr) //输出缓冲区为空则返回转换后需要的空间大小
{
if (lpUnicodeStr)
//delete []lpUnicodeStr;
free(lpUnicodeStr);
return nRetLen;
}
if (nGBKStrLen < nRetLen) //如果输出缓冲区长度不够则退出
{
if (lpUnicodeStr)
//delete []lpUnicodeStr;
free(lpUnicodeStr);
return 0;
}
nRetLen = WideCharToMultiByte(CP_ACP, 0, lpUnicodeStr, -1, (char *)pGBKStr, nGBKStrLen, NULL, NULL); //转换到UTF8编码
if (lpUnicodeStr)
//delete []lpUnicodeStr;
free(lpUnicodeStr);
return nRetLen;
}
int CTW(unsigned char * lpGBKStr, unsigned char * lpUTF8Str, int nUTF8StrLen)
{
wchar_t * lpUnicodeStr = NULL;
int nRetLen = 0;
if (!lpGBKStr) //如果GBK字符串为NULL则出错退出
return 0;
nRetLen = MultiByteToWideChar(CP_ACP, 0, (char *)lpGBKStr, -1, NULL, 0); //获取转换到Unicode编码后所需要的字符空间长度
//lpUnicodeStr = new WCHAR[nRetLen + 1]; //为Unicode字符串空间
lpUnicodeStr = (WCHAR *)malloc((nRetLen + 1) * sizeof(WCHAR)); //为Unicode字符串空间
if (lpUnicodeStr == NULL)
return 0;
nRetLen = MultiByteToWideChar(CP_ACP, 0, (char *)lpGBKStr, -1, lpUnicodeStr, nRetLen); //转换到Unicode编码
if (!nRetLen) //转换失败则出错退出
return 0;
nRetLen = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, NULL, 0, NULL, NULL); //获取转换到UTF8编码后所需要的字符空间长度
if (!lpUTF8Str) //输出缓冲区为空则返回转换后需要的空间大小
{
if (lpUnicodeStr)
//delete []lpUnicodeStr;
free(lpUnicodeStr);
return nRetLen;
}
if (nUTF8StrLen < nRetLen) //如果输出缓冲区长度不够则退出
{
if (lpUnicodeStr)
//delete []lpUnicodeStr;
free(lpUnicodeStr);
return 0;
}
nRetLen = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, (char *)lpUTF8Str, nUTF8StrLen, NULL, NULL); //转换到UTF8编码
if (lpUnicodeStr)
//delete []lpUnicodeStr;
free(lpUnicodeStr);
return nRetLen;
}
void FreeConvertResult(unsigned char * pConvertResult)
{
if (pConvertResult)
{
free(pConvertResult);
pConvertResult = NULL;
}
}
// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 UTF8ToUnicode.h
CUTF8ToUnicode::CUTF8ToUnicode()
{
return;
}
把代码发给AI,它就会给你生成如下的开发日志:
2.提高编写代码注释的效率
代码注释是编程中不可或缺的一部分,但有时候,我会因为赶进度而忽略它(尤其是当你由小白逐渐成为自我感觉良好的“大牛”时)。于是这自然而然被项目经理看到,在每次代码走查会上,要求大家一起“晒代码”,于是你的996有增加一项补注释的工作。然而,有了AI的帮助,你再也不用担心这个问题了。它可以根据代码的逻辑和结构,自动生成准确且清晰的注释,让我的代码更加易读易懂。这不仅提高了代码的可维护性,还让我有更多的时间去关注复杂业务逻辑相关的代码的功能和性能。
3.提高代码重构的效率
代码重构是一项复杂而繁琐的任务,但有了AI的协助,一切都变得轻而易举。AI能够智能地分析代码结构,识别出潜在的问题和风险,并提出优化建议。当然一般而言,我仅用它来消除重复代码,而不用向马丁那样“一步一步地谨小慎微”。不夸张地说,你在编写某一功能函数时甚至可以无脑地使用CV大法快速实现功能,不用考虑复用、编码规范等,然后让AI帮你进行重构,目前以我的经验看,它干得似乎还不错(下面是AI给出的重构建议和示例:
4.编写测试用例及测试报告
QC注意了,告诉你们一个好消息:AI还能根据我的代码编写测试用例和测试报告。以前,大家需要花费大量的时间去设计测试用例,编写测试脚本,并执行测试。而现在,你们只需告诉AI的测试需求,它就能自动生成符合要求的测试用例和测试报告,让我省心又省力,甚至你把一段代码发给AI,它就能干的很好:输出markdown格式的测试报告给你。
例如:你编写了如下代码:
private int GetFitArea(Control control, string str, out SizeF size)
{
int fontInitSize = 80; //根据测试目前界面上的PictureBox适合的字体大小为76,此处由大到小循环计算
using (System.Drawing.Graphics g = control.CreateGraphics())
{// 获得一个Graphics实例
int margin = 10; //边距,对于多字组成的词语输出时有用
using (FontFamily fontFamily = new System.Drawing.FontFamily(theme.FontName))
{
using (System.Drawing.Font font = new System.Drawing.Font(fontFamily, fontInitSize))
{
size = g.MeasureString(str, font);
}
while (((control.Size.Width - size.Width) < margin) || ((control.Size.Height - size.Height) < margin)) //循环计算合适的大小
{
fontInitSize--;
using (System.Drawing.Font font = new System.Drawing.Font(fontFamily, fontInitSize))
{
size = g.MeasureString(str, font); // 计算字符串所需要的大小
}
}
}
}
return fontInitSize - 1;
}
AI可以生成测试用例代码:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Drawing;
using System.Windows.Forms;
// 假设你的GetFitArea方法在某个类中,比如名为GraphicsHelper
[TestClass]
public class GraphicsHelperTest
{
[TestMethod]
public void TestGetFitAreaWithLongString()
{
// 创建一个模拟的Control对象,并设置其大小
Control control = new Control();
control.Size = new Size(200, 100); // 假设控制的大小是200x100像素
// 调用被测试的方法,并传入一个较长的字符串
string testStr = "This is a relatively long string to test the fitting area.";
SizeF measuredSize;
int fontSize = new GraphicsHelper().GetFitArea(control, testStr, out measuredSize);
// 断言字体大小是否在预期范围内(这个范围需要根据实际情况调整)
Assert.IsTrue(fontSize > 0 && fontSize < 80, "Font size should be between 1 and 79.");
// 可以添加更多的断言来验证measuredSize是否符合预期,比如是否小于control的大小等。
}
[TestMethod]
public void TestGetFitAreaWithShortString()
{
// 创建一个模拟的Control对象,并设置其大小
Control control = new Control();
control.Size = new Size(200, 100); // 假设控制的大小是200x100像素
// 调用被测试的方法,并传入一个较短的字符串
string testStr = "Hi!";
SizeF measuredSize;
int fontSize = new GraphicsHelper().GetFitArea(control, testStr, out measuredSize);
// 对于短字符串,字体大小应该接近初始设定的最大值(比如70左右,具体数值需要根据实际情况调整)
Assert.IsTrue(fontSize > 70, "Font size should be greater than 70 for a short string.");
// 可以添加更多的断言来验证measuredSize是否符合预期。
}
}
同时还可以生成测试报告文档:
5. 协助进行代码走查与工作量分析
除了以上这些功能外,AI还能协助项目经理进行代码检查、统计代码编写的工作量,并给出更好的开发建议。它的出现,让各位团队Leaders和小伙伴有了更多的空闲时间,去享受一杯香浓的咖啡,或者去找前台实习小姐姐聊聊天。
例如我将一段代码发给AI后,它得出如下工作量分析:
AI的加入,让如今的Developers工作变得更加轻松、自由。相信将AI使用熟练后,各位会仿佛置身于Google的工作环境之中,享受着高效、愉悦的工作氛围,更加热爱程序员这个大有前途的职业了。
各位亲,你在开发工作中有没有使用到AI工具呢?