将AI融入项目开发工作中去吧

news2024/11/27 0:41:15

目录

1.提高编写开发日报的效率

2.提高编写代码注释的效率

3.提高代码重构的效率

4.编写测试用例及测试报告

5. 协助进行代码走查与工作量分析


在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,它就会给你生成如下的开发日志:
 

开发日期:[填写日期]

开发人员:[填写姓名]

一、概述

本项目旨在实现一个UTF-8编码与GBK编码之间的转换库。通过调用库中的导出函数,用户可以轻松地将UTF-8编码的字符串转换为GBK编码,反之亦然。项目采用了Windows平台的API函数进行编码转换,同时提供了C++类封装以便于扩展和集成。

二、主要模块与功能

  1. 编码转换函数
    • fnUTF8ToUnicode:示例导出函数,实际不执行编码转换,返回固定值42。
    • Hello:导出函数,演示功能,简单返回两个整数的和。
    • PrintUtf8String:将UTF-8字符串转换为GBK编码并返回转换结果(注意:当前实现存在内存泄漏风险,需调用FreeConvertResult释放内存)。
    • UTF8ToGBK:将UTF-8编码的字符串转换为GBK编码,并返回转换后的字符串指针及长度。
    • GBKToUTF8:将GBK编码的字符串转换为UTF-8编码,并返回转换后的字符串指针及长度。
  2. 辅助函数
    • WTC:内部函数,用于将UTF-8编码转换为GBK编码。
    • CTW:内部函数,用于将GBK编码转换为UTF-8编码。
    • FreeConvertResult:释放由PrintUtf8StringUTF8ToGBKGBKToUTF8函数分配的转换结果内存。
  3. 类封装
    • CUTF8ToUnicode:已导出类的构造函数,当前实现为空,用于未来可能的类扩展。

三、实现细节

  1. 编码转换流程
    • 使用MultiByteToWideChar函数将源编码字符串转换为宽字符(Unicode)字符串。
    • 使用WideCharToMultiByte函数将宽字符字符串转换为目标编码字符串。
    • 在转换过程中动态分配内存以存储中间结果和目标编码字符串。
  2. 内存管理
    • 动态分配的内存需由调用方负责释放,以避免内存泄漏。
    • 提供了FreeConvertResult函数作为辅助,用于释放由转换函数分配的内存。

四、待解决问题与改进点

  1. 内存泄漏风险
    • 当前PrintUtf8String函数存在内存泄漏风险,因为返回的GBK编码字符串未被释放。建议调用方在使用完转换结果后调用FreeConvertResult函数释放内存。
    • 考虑在转换函数中自动管理内存,如使用智能指针或提供释放内存的回调函数。
  2. 错误处理
    • 当前实现未对转换过程中的错误进行充分处理。建议添加错误代码和错误消息,以便调用方能够获取转换失败的原因。
  3. 性能优化
    • 对于频繁进行编码转换的场景,可以考虑缓存转换结果或使用更高效的转换算法来提高性能。

五、测试与验证

  •  对UTF8ToGBKGBKToUTF8函数进行单元测试,验证转换的正确性。
  •  对内存泄漏风险进行验证,确保调用方正确释放了转换结果内存。
  •  在实际应用场景中进行集成测试,验证库的稳定性和性能。

六、总结

本项目实现了一个功能基本完备的UTF-8与GBK编码转换库。通过导出函数和类封装,用户可以方便地集成和使用本库进行编码转换。然而,当前实现仍存在一些待解决的问题和改进点,需要在后续开发中进一步完善和优化。

2.提高编写代码注释的效率

代码注释是编程中不可或缺的一部分,但有时候,我会因为赶进度而忽略它(尤其是当你由小白逐渐成为自我感觉良好的“大牛”时)。于是这自然而然被项目经理看到,在每次代码走查会上,要求大家一起“晒代码”,于是你的996有增加一项补注释的工作。然而,有了AI的帮助,你再也不用担心这个问题了。它可以根据代码的逻辑和结构,自动生成准确且清晰的注释,让我的代码更加易读易懂。这不仅提高了代码的可维护性,还让我有更多的时间去关注复杂业务逻辑相关的代码的功能和性能。

3.提高代码重构的效率

援引Martin Fowler的话,“养成重构后即运行测试的习惯非常重要。犯错误是很容易的——至少我知道我是很容易犯错的。做完一次修改就运行测试,这样在我真的犯了错时,只需要考虑一个很小的改动范围,这使得查错与修复问题易如反掌。这就是重构过程的精髓所在:小步修改,每次修改后就运行测试。如果我改动了太多东西,犯错时就可能陷入麻烦的调试,并为此耗费大把时间。小步修改,以及它带来的频繁反馈,正是防止混乱的关键。”

《重构 改善既有代码的设计》这本书在10年刚出的时候,我就迫不及待地给我的团队成员每人赠了一本。再次感谢人邮!BTW:我发现人邮、机工的书总是比电子那啥的要好一些-_-||b

代码重构是一项复杂而繁琐的任务,但有了AI的协助,一切都变得轻而易举。AI能够智能地分析代码结构,识别出潜在的问题和风险,并提出优化建议。当然一般而言,我仅用它来消除重复代码,而不用向马丁那样“一步一步地谨小慎微”。不夸张地说,你在编写某一功能函数时甚至可以无脑地使用CV大法快速实现功能,不用考虑复用、编码规范等,然后让AI帮你进行重构,目前以我的经验看,它干得似乎还不错(下面是AI给出的重构建议和示例:

重构这段代码的主要目标是提高代码的可读性、可维护性和复用性。以下是对原始代码的重构建议:

  1. 提取方法:将大方法分解为多个小方法,每个方法负责一个具体的功能。
  2. 避免使用Tag属性来存储状态Tag属性不是为这种用途设计的,且可能导致意外的副作用。考虑使用其他机制来跟踪状态。
  3. 减少参数数量:对于过多的参数,考虑使用对象或结构来封装它们。
  4. 避免在方法内部直接操作UI元素:考虑将绘图逻辑与UI元素分离。
  5. 处理异常情况:添加对可能的异常情况的处理,例如当pictureBoxnull时。

以下是重构后的代码示例:

public class PictureBoxDrawHelper  
{  
    private readonly Theme theme; // 假设Theme是一个包含字体名称和颜色的类  
  
    public PictureBoxDrawHelper(Theme theme)  
    {  
        this.theme = theme;  
    }  
  
    public void DrawLetterInPictureBox(PictureBox pictureBox, string str, Brush color, bool isClearArea, PointF? letterPoint = null, int? letterSize = null)  
    {  
        if (string.Equals(str, "[手写区]") || !ShouldRedraw(pictureBox, str))  
            return;  
  
        ClearAreaIfNeeded(pictureBox, isClearArea);  
  
        PointF drawPoint = GetDrawPoint(pictureBox, str, letterPoint, letterSize);  
        DrawString(pictureBox, str, color, drawPoint, letterSize ?? GetFitFontSize(pictureBox, str));  
  
        UpdateTag(pictureBox, str);  
    }  
  
    private bool ShouldRedraw(PictureBox pictureBox, string str)  
    {  
        // 逻辑来确定是否需要重新绘制  
        // ...  
    }  
  
    private void ClearAreaIfNeeded(PictureBox pictureBox, bool isClearArea)  
    {  
        // 清除区域的逻辑  
        // ...  
    }  
  
    private PointF GetDrawPoint(PictureBox pictureBox, string str, PointF? letterPoint, int? letterSize)  
    {  
        // 计算绘制点的逻辑  
        // ...  
    }  
  
    private int GetFitFontSize(PictureBox pictureBox, string str)  
    {  
        // 获取适合区域的字体大小的逻辑  
        // ...  
    }  
  
    private void DrawString(PictureBox pictureBox, string str, Brush color, PointF drawPoint, int fontSize)  
    {  
        // 绘制字符串的逻辑  
        // ...  
    }  
  
    private void UpdateTag(PictureBox pictureBox, string str)  
    {  
        // 更新Tag的逻辑,或者使用其他机制来跟踪状态  
        // ...  
    }  
}
注意:上述代码中的Theme类、ShouldRedraw方法、ClearAreaIfNeeded方法、GetDrawPoint方法、GetFitFontSize方法和UpdateTag方法的具体实现需要根据原始代码的逻辑和需求来编写。此外,我还假设了一些类和方法的存在,例如Theme类,它可能包含字体名称和颜色等属性。
这个重构示例将原始方法分解为多个更小、更专注于单一功能的方法,并使用了一个帮助类来封装绘图逻辑。这样做可以提高代码的可读性和可维护性,并使其更易于测试和扩展。

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是否符合预期。  
    }  
}  


同时还可以生成测试报告文档:

测试用例表:

测试用例编号测试用例名称测试目标测试准备测试步骤预期结果测试结果测试结论
TC001测试长字符串在控件中的适配情况确保GetFitArea方法能够准确计算出长字符串在指定控件中的最佳字体大小1. 创建一个尺寸为200x100像素的Control对象1. 向GetFitArea方法传入一个长字符串1. 返回的字体大小应在1至79之间☐ 通过 ☐ 失败
2. 设定长字符串内容2. 验证返回的measuredSize与Control对象尺寸的关系2. measuredSize的宽度和高度均应小于或等于Control对象的对应尺寸
TC002测试短字符串在控件中的适配情况确保GetFitArea方法能够准确计算出短字符串在指定控件中的最佳字体大小1. 创建一个尺寸为200x100像素的Control对象1. 向GetFitArea方法传入一个短字符串1. 返回的字体大小应大于70☐ 通过 ☐ 失败
2. 设定短字符串内容2. 验证返回的measuredSize与Control对象尺寸的关系2. measuredSize的宽度和高度均应在Control对象尺寸范围内

测试执行记录

测试执行人:__________________

测试执行日期:__________________

测试环境描述:______________________________________

备注:

  1. 测试准备中提到的“长字符串”和“短字符串”应事先定义好,并在测试步骤中明确指出其内容。

  2. 在“测试结果”一栏中,填写实际返回的字体大小和measuredSize值。

  3. 根据实际测试结果,在“测试结论”一栏中勾选相应的选项(通过或失败)。

  4. 如测试失败,请详细描述失败原因,并考虑是否需要重新设计测试用例或修改被测试的代码。

5. 协助进行代码走查与工作量分析

除了以上这些功能外,AI还能协助项目经理进行代码检查、统计代码编写的工作量,并给出更好的开发建议。它的出现,让各位团队Leaders和小伙伴有了更多的空闲时间,去享受一杯香浓的咖啡,或者去找前台实习小姐姐聊聊天。

例如我将一段代码发给AI后,它得出如下工作量分析:
 

假设这是一个简单的Windows Forms应用程序中的一部分,负责在PictureBox控件中绘制文本,并且这个任务是相对独立的(不依赖于其他复杂的系统或库)。以下是对工作量的粗略估计:

  1. 代码理解与分析
    • 阅读并理解现有代码的功能和结构(大约1-2小时,取决于开发者的经验和代码复杂性)。
  2. 重构准备
    • 识别需要重构的部分(根据提供的重构建议,这可能需要1-2小时)。
    • 设计新的类和方法结构(大约1小时)。
  3. 代码重构
    • 提取方法(每个方法大约30分钟到1小时,取决于方法的复杂性)。
    • 处理异常情况(添加必要的错误处理和日志记录,大约1小时)。
    • 使用对象或结构封装参数(大约1小时)。
    • 更新UI逻辑,避免直接操作UI元素(大约2小时)。
    • 实现新的状态跟踪机制(如果不再使用Tag属性,大约2小时)。
    • 编写单元测试(假设需要,大约2-4小时,取决于测试覆盖率)。
  4. 测试与验证
    • 手动测试重构后的功能(确保所有功能都按预期工作,大约2小时)。
    • 运行单元测试(如果有编写,大约1小时)。
  5. 文档编写
    • 更新或编写相关开发文档(如类和方法注释、用户指南等,大约1-2小时)。
  6. 代码审查和合并
    • 如果是在团队环境中工作,可能需要进行代码审查(大约1小时)。
    • 将重构后的代码合并到主分支或相关分支(大约30分钟到1小时)。

总工作量估计:大约6-12小时,具体取决于上述各个步骤的详细要求和开发者的技能水平。请注意,这只是一个粗略的估计,实际情况可能会有所不同。

AI的加入,让如今的Developers工作变得更加轻松、自由。相信将AI使用熟练后,各位会仿佛置身于Google的工作环境之中,享受着高效、愉悦的工作氛围,更加热爱程序员这个大有前途的职业了。

各位亲,你在开发工作中有没有使用到AI工具呢?
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1659757.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【c++线程】condition_variable的简单使用

尝试用两个线程交替打印1-100的数字&#xff0c;要求一个线程打印奇数&#xff0c;另一个线程打印偶数&#xff0c;并且打印数字从小到大依次递增。 #include <iostream> using namespace std; #include <thread> #include <mutex> #include <condition_…

海外邮件群发工具的使用方法?有哪些限制?

海外邮件群发工具怎么选择&#xff1f;使用邮件群发工具的优势&#xff1f; 海外邮件群发工具成为了企业开展海外推广、联系客户、推广产品和服务的重要工具。但如何有效地使用这一工具&#xff0c;成为了众多营销人员关注的问题。接下来&#xff0c;AokSend将详细探讨海外邮件…

文件批量重命名技巧:文本内容即文件名,打造个性化文件命名新体验

在日常工作和学习中&#xff0c;我们经常需要处理大量的文件&#xff0c;而给这些文件命名则成为了一个既繁琐又重要的任务。传统的文件命名方式&#xff0c;如使用数字、字母或简单的描述性词汇&#xff0c;往往难以体现出文件的实际内容和特点。那么&#xff0c;有没有一种方…

搭建一个vue3+vant4+vite4+pinia 的移动端h5模板

效果图 项目的创建和组件库的安装 项目创建 pnpm create vite vue3-vant4-vite-pinia-pro-h5注意&#xff1a; node版本控制在 18&#xff0c; 可以通过nvm来管理本地的node版本&#xff0c;具体可以看这篇文章 nvm的简单使用 vant-ui库的安装【这里安装的是 ^4.6.0 版本的】…

云南区块链商户平台优化开发

背景 云南区块链商户平台是全省统一区块链服务平台。依托于云南省发改委、阿里云及蚂蚁区块链的国内首个省级区块链平台——云南省区块链平台同步上线&#xff0c;助力数字云南整体升级。 网页版并不适合妈妈那辈人使用&#xff0c;没有记忆功能&#xff0c;于是打算自己开发…

不想让Win系统更新,那就让它暂停一万年

按照下图所示进行操作 winR 输入 regedit&#xff0c;进入注册表编辑器 随后依次点击 HKEY_LOCAL_MACHINE ⬇ SOFTWARE ⬇ Microsoft ⬇ WindowsUpdate ⬇ UX ⬇ Settings 最后在右侧空白处 文件类型 新建DWORD&#xff08;32位&#xff09;值&#xff08;D&#xff09; 命名…

sharding-jdbc如何实现分页查询

写在文章开头 在之前的文章中笔者简单的介绍了sharding-jdbc的使用&#xff0c;而本文从日常使用的角度出发来剖析一下sharding-jdbc底层是如何实现分页查询的。 Hi&#xff0c;我是 sharkChili &#xff0c;是个不断在硬核技术上作死的 java coder &#xff0c;是 CSDN的博客…

私域流量优化:如何利用 AIPL 模型洞察客户生命周期价值

在当今这个数字化时代&#xff0c;商业战场的硝烟从未如此浓烈。随着互联网红利的逐渐消退&#xff0c;公域流量的成本水涨船高&#xff0c;企业间对于有限用户资源的争夺已进入白热化阶段。每一次点击、每一个曝光背后&#xff0c;都是企业不得不承担的高昂代价。在此背景下&a…

1725 ssm资产管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java ssm资产管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/…

本安防爆手机在电力行业中的应用

在电力行业这一充满挑战与风险的领域中&#xff0c;安全始终是最为首要的考量。电力巡检、维修等作业往往涉及易燃、易爆环境&#xff0c;这就要求工作人员配备能够在极端条件下保障通讯和作业安全的专业设备。防爆手机应运而生&#xff0c;以其独特的设计和卓越的性能&#xf…

Kafka 执行命令超时异常: Timed out waiting for a node assignment

Kafka 执行命令超时异常&#xff1a; Timed out waiting for a node assignment 问题描述&#xff1a; 搭建了一个kafka集群环境&#xff0c;在使用命令行查看已有topic时&#xff0c;报错如下&#xff1a; [rootlocalhost bin]# kafka-topics.sh --list --bootstrap-server…

es关闭开启除了系统索引以外的所有索引

1、es 开启 “删除或关闭时索引名称支持通配符” 功能 2、kibanan平台执行 POST *,-.*/_close 关闭索引POST *,-.*/_open 打开索引3、其他命令 DELETE index_* // 按通配符删除以index_开头的索引 DELETE _all // 删除全部索引 DELETE *,-.* 删除全…

产品推荐 | 基于Xilinx Kintex-7 FPGA K7 XC7K325T PCIeX8 四路光纤卡

01 产品概述 板卡主芯片采用Xilinx公司的XC7K325T-2FFG900 FPGA&#xff0c;pin_to_pin兼容FPGAXC7K410T-2FFG900&#xff0c;支持8-Lane PCIe、64bit DDR3、四路SFP连接器、四路SATA接口、内嵌16个高速串行收发器RocketIO GTX&#xff0c;软件具有windows驱动。 02 技术指标…

【数据结构】栈的实现以及数组和链表的优缺点

个人主页&#xff1a;一代… 个人专栏&#xff1a;数据结构 1.栈 1.1栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进…

小程序(三)

十三、自定义组件 &#xff08;二&#xff09;数据方法声明位置 在js文件中 A、数据声明位置&#xff1a;data中 B、方法声明位置methods中&#xff0c;这点和普通页面不同&#xff01; Component({/*** 组件的属性列表*/properties: {},/*** 组件的初始数据*/data: {isCh…

在Ubuntu安装Carla时按照官方的教程将下载好的资源包解压放到Unreal\CarlaUE4\Content\Carla后执行./Update.sh

在Ubuntu安装Carla时按照官方的教程将下载好的资源包解压放到 Unreal\CarlaUE4\Content\Carla后执行./Update.sh 结果出现&#xff0c;将原来的Carla文件夹备份了有创建了一个新的空白Carla文件夹 原来自己下载解压后就不用再执行./Update.sh这个了&#xff0c;这个命令就是…

【Redis分布式缓存】分片集群

Redis 分片集群 搭建分片集群 集群结构 分片集群需要的节点数量较多&#xff0c;这里我们搭建一个最小的分片集群&#xff0c;包含3个master节点&#xff0c;每个master包含一个slave节点&#xff0c;结构如下&#xff1a; 这里我们会在同一台虚拟机中开启6个redis实例&…

逻辑回归和神经网络(原理+应用)

目录 一、背景介绍 二、题目要求 三、逻辑回归&#xff08;Logistic Regression&#xff09;与神经网络 四、输入输出变量 五、效果评估Gains介绍 六、模型构建 具体应用&#xff1a;预测客户是否有意预订有线电视交互服务 一、背景介绍 当今时代&#xff0c;有线电视交…

【JavaEE 初阶(四)】多线程进阶

❣博主主页: 33的博客❣ ▶️文章专栏分类:JavaEE◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你了解更多线程知识 目录 1.前言2.常见的锁策略2.1悲观锁vs乐观锁2.2轻量级锁vs重量级锁2.3自旋锁vs挂起锁2.4读写…

JS控制台代码:淘宝PC网页付款页面定时确认付款

淘宝定时抢东西用的 必须先输入完正确密码&#xff0c;考虑上了网络延迟&#xff0c;程序提前一秒钟点击确认&#xff0c;可自行修改&#xff1a; function checkTime() {var now new Date();var hours now.getHours();var minutes now.getMinutes();var seconds now.getS…