• [常见FAQ] 选手程序输出异常
    本地和判题器交互正常,有最终得分。但是线上提交显示:选手程序输出异常。
  • [问题求助] atlas 300,在开发环境中(x86),安装样例中samples/cplusplus/common/acllite库时,make报错
    报错如下:/usr/bin/ld: cannot find -lavdevice /usr/bin/ld: cannot find -lavfilter collect2: error: ld returned 1 exit status make: *** [out/x86_64/libacllite.so] Error 1 在路径下THIRDPART_PATH,目前只有安装好的ffmpeg包,/usr/local/Ascend/thirdpart/aarch64/ffmpeg/环境变量如下:开发端--x86export INSTALL_DIR=/usr/local/Ascend/ascend-toolkit/latest export INSTALL_DIR_ARM=/usr/local/Ascend/ascend-toolkit/ascend-toolkit_arm/latest/aarch64-linux export PATH=$PATH:/usr/local/bin/cmake:${INSTALL_DIR}/atc/ccec_compiler/bin:${INSTALL_DIR}/atc/bin:${INSTALL_DIR}/bin:${INSTALL_DIR}/compiler/ccec_compiler/bin export LD_LIBRARY_PATH=${INSTALL_DIR}/acllib/lib64:${INSTALL_DIR}/atc/lib64:/usr/local/Ascend/ascend-toolkit/6.3.RC1.alpha001/runtime/lib64/stub:$LD_LIBRARY_PATH export ASCEND_OPP_PATH=${INSTALL_DIR}/opp export ASCEND_AICPU_PATH=/usr/local/Ascend/ascend-toolkit/latest/aarch64-linux export PYTHONPATH=${INSTALL_DIR}/atc/python/site-packages:${INSTALL_DIR}/opp/built-in/op_impl/ai_core/tbe:$PYTHONPATH export TOOLCHAIN_HOME=${INSTALL_DIR}/toolkit export ASCEND_HOME_PATH=${INSTALL_DIR} export DDK_PATH=/usr/local/Ascend/ascend-toolkit/latest/arm64-linux export NPU_HOST_LIB=${DDK_PATH}/runtime/lib64/stub export CPU_ARCH=`arch` export THIRDPART_PATH=/usr/local/Ascend/thirdpart/${CPU_ARCH} 
  • [问题求助] 在arm中,将数据写入device时,报错malloc device data buffer failed, aclRet is 107002
    报错代码如下:void* AtlasEngine::CopyDataToDevice(void* data, uint32_t dataSize, aclrtMemcpyKind policy) {    void* buffer = nullptr;    aclError aclRet = aclrtMalloc(&buffer, dataSize, ACL_MEM_MALLOC_HUGE_FIRST);    if (aclRet != ACL_SUCCESS) {        ERROR_LOG("malloc device data buffer failed, aclRet is %d", aclRet);        return nullptr;    }根据错误码,也检查了context,返回的是create context success,是创建成功的;aclrtSetDevice(deviceId_);也是成功的, ret = aclrtCreateContext(&context_, deviceId_);    if (ret != ACL_SUCCESS) {        ERROR_LOG("acl create context failed, deviceId = %d, errorCode = %d",            deviceId_, static_cast<int32_t>(ret));        return FAILED;    }    INFO_LOG("create context success");
  • [技术干货] 64位MFC调用32位DLL
    当64位MFC应用程序调用32位DLL时,你可以通过创建一个中间层Wrapper DLL来实现。下面是一个简单的示例,演示如何从64位MFC应用程序调用32位DLL的函数:假设你有一个32位DLL,其中包含一个名为MyFunction的函数,它接受一个整数参数并返回一个整数。你想从64位MFC应用程序中调用这个函数。首先,创建一个新的64位DLL项目(Wrapper DLL),用于与32位DLL进行交互。在这个64位DLL项目中,编写一个导出函数,该函数将调用32位DLL的函数。下面是一个简单的例子:// WrapperDLL.h #pragma once #ifdef WRAPPERDLL_EXPORTS #define WRAPPERDLL_API __declspec(dllexport) #else #define WRAPPERDLL_API __declspec(dllimport) #endif extern "C" WRAPPERDLL_API int CallMyFunction(int value);// WrapperDLL.cpp #include "WrapperDLL.h" #include "windows.h" typedef int(*MYFUNCTION)(int); int CallMyFunction(int value) { HINSTANCE hDLL = LoadLibrary(L"path_to_32bit_dll.dll"); if (hDLL != NULL) { MYFUNCTION myFunction = (MYFUNCTION)GetProcAddress(hDLL, "MyFunction"); if (myFunction != NULL) { int result = myFunction(value); FreeLibrary(hDLL); return result; } FreeLibrary(hDLL); } return -1; }在这个示例中,我们创建了一个名为CallMyFunction的导出函数。该函数加载32位DLL,并使用GetProcAddress函数获取MyFunction函数的地址。然后,我们将参数传递给32位DLL的函数,并返回结果。接下来,编译这个Wrapper DLL项目,并生成一个64位的DLL文件。然后,在你的64位MFC应用程序中,你可以通过调用CallMyFunction函数来间接调用32位DLL的函数。例如:// MFCAppDlg.cpp (64位MFC应用程序的对话框类文件) #include "WrapperDLL.h" // ... void CMFCAppDlg::OnBnClickedButton1() { int result = CallMyFunction(42); // 处理结果... }这里,我们在MFC应用程序中的按钮单击事件处理程序中调用了CallMyFunction函数,将参数值 42 传递给32位DLL的函数。你可以根据需要使用返回的结果。需要确保在编译64位MFC应用程序和Wrapper DLL时,使用相应的64位编译器选项。此外,还需要将32位DLL的路径替换为你自己的实际路径。这只是一个简单的示例,具体的实现可能因实际情况而有所不同。你可能需要根据32位DLL的特定函数和参数来进行更多的调整和适配。
  • [常见FAQ] C++如何Debug
    文档里说的调试器太简单了   能细说吗?解锁新知识
  • [问题求助] 按照样例操作,执行bash sample_build.sh的时候,编译出错,新人求指导
    正在学习Atlas 200 DK,用了分设环境,CANN是6.0.RC1,固件与驱动版本是1.0.13.alpha,目前卡在开发环境,试了两个C++的检测样例,都是成功模型转换,但在运行提供的bash sample_build.sh编译的时候,都报同样的错,想请教一下有经验的大佬
  • [开发资源] Restful 接口API开发文档
    使用restful接口进行对接和开发时,可以参考附件文档中的说明进行开发20221019:更新最新版本(10-10号发布)
  • [问题求助] 请求文档链接
    请问谁有《IPC V200R003C00 智能元数据结构设计说明书》?谢谢!
  • [问题求助] 捉虫,输入0D/1DTensor,1D张量时shape为1,获取不到(或不正确)获取那唯一元素的值,后来分int64,int32尝试获取了也不行
    固定值的Tensor输入可行,这两种用例随机范围0-10输入,不行原因设备日志显示,在于超时​UT增加用例input_int64_data_type_float,input_int64_data_type_default会有出现过超时bad_alloc,或段错误(调试时是获取不正确,n过大如下):@莫晓忧,有空麻烦上仓帮忙看一下实现和用例两个文件。感谢涛哥和各位版主了!尝试了memcpy_s,5个输入int64ut用例失败。但改上面两个随机Tensor用例为Int32输入,这两个随机x输入用例st设备本地测试也不通过,所以应该只能是cann仓的问题
  • [API使用] 请问想在Qt项目中使用mindspore lite进行推理有没有示例可以参考?
    如题,想在自己的Qt项目中加入mindspore lite的API进行推理,有没有什么示例可以参考?
  • [技术干货] 基于CC2530(ZigBee)设计的景观照明控制系统+配套手机APP
    一、环境介绍编译集成开发环境: IARMCU: CC2530(ZigBee)编程语言: C语言手机APP: 采用QT设计,程序支持跨平台编译运行(Android、IOS、Windows、Linux都可以编译运行,对应平台上QT的环境搭建,之前博客已经发了文章讲解)硬件包含: 3套CC2530开发板(1个协调器、2个节点)、1个ESP8266串口WIFI、1个DHT11温湿度传感器、1个RGB多彩灯、1个BH1750光强度检测传感器.资料包里包含了: CC2530协调器源码、2个节点源码、手机APP源码、Windows上位机源码、手机APP可执行文件、IAR下载器驱动、IAR资料等等。二、功能介绍这是基于CC2530设计的景观照明控制系统,一共包含了3个CC2530节点(就是3块CC2530开发板)。下面将这个3个CC2530开发板称为A、B、C节点。A节点: 当做协调器、可以接收BC节点上传的数据;A模块配了一个ESP8266 WIFI模块,可以连接手机APP,将BC节点上传温湿度数据再上传给手机APP显示。如果A节点在一定时间内没有收到B、C节点的数据,就会通知手机APP,告诉用户,B、C节点已经掉线。B节点: 作为RGB多彩灯+温湿度检测节点,会根据当前温湿度调整当前RGB灯的颜色,用于告诉景区的游客,当前景区的温湿度情况,采集的温湿度也会通过CC2530传递给A节点。C节点: 光照强度检测+LED灯节点。 这里的LED灯就是模拟景区的路灯,手机APP可以控制LED灯的开关,如果是白天的时候,LED灯会自动关掉,天气变暗,自动打开。也可以设计时间,定时关灯。三、相关的硬件介绍3.1 DTH11 温湿度传感器DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,使其成为该类应用中,在苛刻应用场合的最佳选择。产品为4针单排引脚封装,连接方便。3.2 ESP8266 WIFIESP8266系列无线模块是高性价比WIFI SOC模组,该系列模块支持标准的IEEE802.11b/g/n协议,内置完整的TCP/IP协议栈。用户可以使用该系列模块为现有的设备添加联网功能,也可以构建独立的网络控制器。能卓越ESP8266EX 芯片内置超低功耗 Tensilica L106 32 位 RISC 处理器,CPU 时钟速度最⾼可达 160 MHz,⽀持实时操作系统 (RTOS) 和 Wi-Fi 协议栈,可将⾼达 80% 的处理能⼒应用于编程和开发。高度集成ESP8266 芯片高度集成天线开关、射频巴伦、功率放大器、低噪声接收放大器、滤波器等射频模块。模组尺寸小巧,尤其适用于空间受限的产品设计。认证齐全RF 认证:SRRC、FCC、CE-RED、KCC、TELEC/MIC、IC 和 NCC 认证;环保认证:RoHS、REACH;可靠性认证:HTOL、HTSL、μHAST、TCT、ESD。丰富的产品应用ESP8266 模组既可以通过 ESP-AT 指令固件,为外部主机 MCU 提供 Wi-Fi 连接功能;也可以作为独立 Wi-Fi MCU 运行,用户通过基于 RTOS 的 SDK 开发带 Wi-Fi 连接功能的产品。用户可以轻松实现开箱即用的云连接、低功耗运行模式,以及包括 WPA3 在内的 Wi-Fi 安全支持等功能。3.3 CC2530CC2530 是用于2.4-GHz IEEE 802.15.4、ZigBee 和RF4CE 应用的一个真正的片上系统(SoC)解决方案。它能够以非常低的总的材料成本建立强大的网络节点。CC2530 结合了领先的RF 收发器的优良性能,业界标准的增强型8051 CPU,系统内可编程闪存,8-KB RAM 和许多其它强大的功能。CC2530 有四种不同的闪存版本:CC2530F32/64/128/256,分别具有32/64/128/256KB 的闪存。CC2530 具有不同的运行模式,使得它尤其适应超低功耗要求的系统。运行模式之间的转换时间短进一步确保了低能源消耗。CC2530F256 结合了德州仪器的业界领先的黄金单元ZigBee 协议栈(Z-Stack™),提供了一个强大和完整的ZigBee 解决方案。CC2530F64 结合了德州仪器的黄金单元RemoTI,更好地提供了一个强大和完整的ZigBee RF4CE 远程控制解决方案。3.4 RGB多彩灯颜色:全彩 红绿蓝三基色亮度:高亮电压:5V输入:数字电平三基色原理显示多重颜色通过PWM端口控制实现全彩显示3.5 BH1750** bh1750 是16位数字输出型,环境光强度传感器。**四、节点硬件+手机APP介绍4.1 C节点: 光敏传感器+LED灯控制4.2 B节点: 多彩灯+温湿度4.3 A节点: WIFI + APP4.4 手机APP界面效果五、手机APP上位机源码六、CC2530节点源码节点源码较多,下面就贴一些关键代码。6.1 uart.c#include "uart.h" /* 函数功能:串口0初始化 */ void Init_Uart0(void) { PERCFG&=~(1<<0); //串口0的引脚映射到位置1,即P0_2和P0_3 P0SEL|=0x3<<2; //将P0_2和P0_3端口设置成外设功能 U0BAUD = 216; //32MHz的系统时钟产生115200BPS的波特率 U0GCR&=~(0x1F<<0);//清空波特率指数 U0GCR|=11<<0; //32MHz的系统时钟产生115200BPS的波特率 U0UCR |= 0x80; //禁止流控,8位数据,清除缓冲器 U0CSR |= 0x3<<6; //选择UART模式,使能接收器 } /* 函数功能:UART0发送字符串函数 */ void UR0SendString(u8 *str) { while(*str!='') { U0DBUF = *str; //将要发送的1字节数据写入U0DBUF while(UTX0IF == 0);//等待数据发送完成 UTX0IF = 0; //清除发送完成标志,准备下一次发送 str++; } } /* 函数功能: 模仿printf风格的格式化打印功能 */ char USART0_PRINT_BUFF[200]; //格式化数据缓存数据 void USART0_Printf(const char *format,...) { char *str=NULL; /*1. 格式化转换*/ va_list ap; // va_list---->char * va_start(ap,format); //初始化参数列表 vsprintf(USART0_PRINT_BUFF, format, ap); //格式化打印 va_end(ap); //结束参数获取 /*2. 串口打印*/ str=USART0_PRINT_BUFF;//指针赋值 while(*str!='') { U0DBUF=*str; //发送一个字节的数据 str++; //指针自增,指向下一个数据 while(UTX0IF == 0);//等待数据发送完成 UTX0IF = 0; //清除发送完成标志,准备下一次发送 } }6.2 DHT11.c#include "dht11.h" #include "delay.h" #define DATA_PIN P0_7 //温湿度定义 uchar ucharFLAG,uchartemp; uchar shidu_shi,shidu_ge,wendu_shi,wendu_ge=4; uchar ucharT_data_H,ucharT_data_L,ucharRH_data_H,ucharRH_data_L,ucharcheckdata; uchar ucharT_data_H_temp,ucharT_data_L_temp,ucharRH_data_H_temp,ucharRH_data_L_temp,ucharcheckdata_temp; uchar ucharcomdata; //延时函数 void Delay_us() //1 us延时 { asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); } void Delay_10us() //10 us延时 { #if 0 Delay_us(); Delay_us(); Delay_us(); Delay_us(); Delay_us(); Delay_us(); Delay_us(); Delay_us(); Delay_us(); Delay_us(); #else int i = 10; while(i--); #endif } void Delay_ms(unsigned int Time)//n ms延时 { unsigned char i; while(Time--) { for(i=0;i<100;i++) Delay_10us(); } } //温湿度传感 void COM(void) // 温湿写入 { uchar i; for(i=0;i<8;i++) { ucharFLAG=2; while((!DATA_PIN)&&ucharFLAG++); Delay_10us(); Delay_10us(); Delay_10us(); uchartemp=0; if(DATA_PIN)uchartemp=1; ucharFLAG=2; while((DATA_PIN)&&ucharFLAG++); if(ucharFLAG==1)break; ucharcomdata<<=1; ucharcomdata|=uchartemp; } } void DHT11(void) //温湿传感启动 { DATA_PIN=0; Delay_ms(19); //>18MS DATA_PIN=1; P0DIR &= ~0x80; //重新配置IO口方向 Delay_10us(); Delay_10us(); Delay_10us(); Delay_10us(); if(!DATA_PIN) { ucharFLAG=2; while((!DATA_PIN)&&ucharFLAG++); ucharFLAG=2; while((DATA_PIN)&&ucharFLAG++); COM(); ucharRH_data_H_temp=ucharcomdata; COM(); ucharRH_data_L_temp=ucharcomdata; COM(); ucharT_data_H_temp=ucharcomdata; COM(); ucharT_data_L_temp=ucharcomdata; COM(); ucharcheckdata_temp=ucharcomdata; DATA_PIN=1; uchartemp=(ucharT_data_H_temp+ucharT_data_L_temp+ucharRH_data_H_temp+ucharRH_data_L_temp); if(uchartemp==ucharcheckdata_temp) { ucharRH_data_H=ucharRH_data_H_temp; ucharRH_data_L=ucharRH_data_L_temp; ucharT_data_H=ucharT_data_H_temp; ucharT_data_L=ucharT_data_L_temp; ucharcheckdata=ucharcheckdata_temp; } wendu_shi=ucharT_data_H/10; wendu_ge=ucharT_data_H; shidu_shi=ucharRH_data_H/10; shidu_ge=ucharRH_data_H; } else //没用成功读取,返回0 { wendu_shi=0; wendu_ge=0; shidu_shi=0; shidu_ge=0; } P0DIR |= 0x80; //IO口需要重新配置 }6.3 BH1750.c#include "bh1750.h" u8 Read_BH1750_Data() { unsigned char t0; unsigned char t1; unsigned char t; u8 r_s=0; IIC_Start(); //发送起始信号 IIC_WriteOneByteData(0x46); r_s=IIC_GetACK();//获取应答 if(r_s)USART0_Printf("error:1 "); IIC_WriteOneByteData(0x01); r_s=IIC_GetACK();//获取应答 if(r_s)USART0_Printf("error:2 "); IIC_Stop(); //停止信号 IIC_Start(); //发送起始信号 IIC_WriteOneByteData(0x46); r_s=IIC_GetACK();//获取应答 if(r_s)USART0_Printf("error:3 "); IIC_WriteOneByteData(0x01); r_s=IIC_GetACK();//获取应答 if(r_s)USART0_Printf("error:4 "); IIC_Stop(); //停止信号 IIC_Start(); //发送起始信号 IIC_WriteOneByteData(0x46); r_s=IIC_GetACK();//获取应答 if(r_s)USART0_Printf("error:5 "); IIC_WriteOneByteData(0x10); r_s=IIC_GetACK();//获取应答 if(r_s)USART0_Printf("error:6 "); IIC_Stop(); //停止信号 DelayMs(300); //等待 IIC_Start(); //发送起始信号 IIC_WriteOneByteData(0x47); r_s=IIC_GetACK();//获取应答 if(r_s)USART0_Printf("error:7 "); t0=IIC_ReadOneByteData(); //接收数据 IIC_SendACK(0); //发送应答信号 t1=IIC_ReadOneByteData(); //接收数据 IIC_SendACK(1); //发送非应答信号 IIC_Stop(); //停止信号 t=(((t0<<8)|t1)/1.2); return t; }
  • [技术干货] 【c++百日刷题计划】 ———— DAY9,奋战百天,带你熟练掌握基本算法-转载
    第一题 集合求和题目描述给定一个集合 s ss(集合元素数量 ≤ 30 \le 30≤30),求出此集合所有子集元素之和。输入格式集合中的元素(元素 ≤ 1000 \le 1000≤1000)输出格式s ss 所有子集元素之和。样例 #1样例输入 #12 31样例输出 #1101提示【样例解释】子集为:∅ , { 2 } , { 3 } , { 2 , 3 } \varnothing, \{ 2 \}, \{ 3 \}, \{ 2, 3 \}∅,{2},{3},{2,3},和为 2 + 3 + 2 + 3 = 10 2 + 3 + 2 + 3 = 102+3+2+3=10。【数据范围】对于 100 % 100 \%100% 的数据,1 ≤ ∣ s ∣ ≤ 30 1 \le \lvert s \rvert \le 301≤∣s∣≤30,1 ≤ s i ≤ 1000 1 \le s_i \le 10001≤s i​ ≤1000,s ss 所有子集元素之和 ≤ 10 18 \le {10}^{18}≤10 18 。解题思路1)数学推理题目。2)找规律发现,每个元素在 a 的每一个子集中出现的个数为2 n − 1 {2}^{n-1}2 n−1 。参考代码#include<bits/stdc++.h>using namespace std;int a[31];long long s=0;int main(){    int n=0;     {        s+=a[i];    }    s*=pow(2,n-2);    cout<<s;    return 0;}123456789101112131415第二题 [NOIP2004 普及组] 火星人题目描述人类终于登上了火星的土地并且见到了神秘的火星人。人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法。这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类科学家,科学家破解这个数字的含义后,再把一个很小的数字加到这个大数上面,把结果告诉火星人,作为人类的回答。火星人用一种非常简单的方式来表示数字――掰手指。火星人只有一只手,但这只手上有成千上万的手指,这些手指排成一列,分别编号为 1 , 2 , 3 , ⋯ 1,2,3,\cdots1,2,3,⋯。火星人的任意两根手指都能随意交换位置,他们就是通过这方法计数的。一个火星人用一个人类的手演示了如何用手指计数。如果把五根手指――拇指、食指、中指、无名指和小指分别编号为 1 , 2 , 3 , 4 1,2,3,41,2,3,4 和 5 55,当它们按正常顺序排列时,形成了 5 55 位数 12345 1234512345,当你交换无名指和小指的位置时,会形成 5 55 位数 12354 1235412354,当你把五个手指的顺序完全颠倒时,会形成 54321 5432154321,在所有能够形成的 120 120120 个 5 55 位数中,12345 1234512345 最小,它表示 1 11;12354 1235412354 第二小,它表示 2 22;54321 5432154321 最大,它表示 120 120120。下表展示了只有 3 33 根手指时能够形成的 6 66 个 3 33 位数和它们代表的数字:三进制数    代表的数字123 123123    1 11132 132132    2 22213 213213    3 33231 231231    4 44312 312312    5 55321 321321    6 66现在你有幸成为了第一个和火星人交流的地球人。一个火星人会让你看他的手指,科学家会告诉你要加上去的很小的数。你的任务是,把火星人用手指表示的数与科学家告诉你的数相加,并根据相加的结果改变火星人手指的排列顺序。输入数据保证这个结果不会超出火星人手指能表示的范围。输入格式共三行。第一行一个正整数 N NN,表示火星人手指的数目(1 ≤ N ≤ 10000 1 \le N \le 100001≤N≤10000)。第二行是一个正整数 M MM,表示要加上去的小整数(1 ≤ M ≤ 100 1 \le M \le 1001≤M≤100)。下一行是 1 11 到 N NN 这 N NN 个整数的一个排列,用空格隔开,表示火星人手指的排列顺序。输出格式N NN 个整数,表示改变后的火星人手指的排列顺序。每两个相邻的数中间用一个空格分开,不能有多余的空格。样例 #1样例输入 #1531 2 3 4 5123样例输出 #11 2 4 5 31提示对于 30 % 30\%30% 的数据,N ≤ 15 N \le 15N≤15。对于 60 % 60\%60% 的数据,N ≤ 50 N \le 50N≤50。对于 100 % 100\%100% 的数据,N ≤ 10000 N \le 10000N≤10000。解题思路1)模拟深度优先搜索的全排列问题参考代码#include<bits/stdc++.h>using namespace std;int a[10005];bool used[10005]={0};int m,n;int main(){    cin>>n>>m;    for(int i=1;i<=n;i++)    {        cin>>a[i];        int x=a[i];        for(int j=1;j<=a[i];j++)            x-=used[j];        used[a[i]]=1;        a[i]=x-1;    }    a[n]+=m;    for(int i=n;i>0;i--)    {        a[i-1]+=a[i]/(n-i+1);        a[i]%=n-i+1;    }    memset(used,0,sizeof(used));    for(int i=1;i<=n;i++)    {        for(int j=0;j<=a[i];j++)            if(used[j])                a[i]++;        cout<<a[i]+1<<" ";        used[a[i]]=1;    }    return 0;}12345678910111213141516171819202122232425262728293031323334第三题 [NOIP2004 普及组] 最大约数和题目描述选取和不超过S的若干个不同的正整数,使得所有数的约数(不含它本身)之和最大。输入格式输入一个正整数S。输出格式输出最大的约数之和。样例 #1样例输入 #1111样例输出 #191提示样例说明取数字4和6,可以得到最大值(1+2)+(1+2+3)=9。数据规模S<=10001解题思路1)对数据进行预处理,求出每个数的约数和。2)简单的01背包问题。参考代码#include<bits/stdc++.h>using namespace std;int i,j,n,a[1001],dp[1001];int main(){    cin>>n;    for(i=1;i<=n/2;i++)        for(j=2;i*j<=n;j++)            a[i*j]+=i;    for(i=1;i<=n;i++)        for(j=i;j<=n;j++)            dp[j]=max(dp[j],dp[j-i]+a[i]);    cout<<dp[n];      return 0;}123456789101112131415第四题 [NOIP2004 普及组] 通天之分组背包题目背景直达通天路·小 A 历险记第二篇题目描述自 01 0101 背包问世之后,小 A 对此深感兴趣。一天,小 A 去远游,却发现他的背包不同于 01 0101 背包,他的物品大致可分为 k kk 组,每组中的物品相互冲突,现在,他想知道最大的利用价值是多少。输入格式两个数 m , n m,nm,n,表示一共有 n nn 件物品,总重量为 m mm。接下来 n nn 行,每行 3 33 个数 a i , b i , c i a_i,b_i,c_ia i​ ,b i​ ,c i​ ,表示物品的重量,利用价值,所属组数。输出格式一个数,最大的利用价值。样例 #1样例输入 #145 310 10 110 5 150 400 21234样例输出 #1101提示1 ≤ m , n ≤ 1000 1 \leq m, n \leq 10001≤m,n≤1000。解题思路1)分组背包问题。2)直接枚举每个组,再在每个组里进行01背包。参考代码#include<bits/stdc++.h>using namespace std;long long dp[1050];int a[1050],b[1050],c,C[1050];int g[205][205];int main(){    int m,n;    cin>>m>>n;    int zu=0;    for(int i=1;i<=n;i++)    {                cin>>a[i]>>b[i]>>c;        zu=max(zu,c);        C[c]++;        g[c][C[c]]=i;    }        for(int i=1;i<=zu;i++)    {        for(int j=m;j>=0;j--)        {            for(int k=1;k<=C[i];k++)            {                if(j>=a[g[i][k]])                {                    dp[j]=max(dp[j],dp[j-a[g[i][k]]]+b[g[i][k]]);                }            }        }    }    cout<<dp[m];    return 0;}————————————————版权声明:本文为CSDN博主「锡兰_CC」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/Ceylan__/article/details/126246543
  • [技术干货] C/C++后端实习经验大礼包-转载
    C/C++后端实习经验大礼包文章目录C/C++后端实习经验大礼包一、前言二、实习面试宝典1.自我介绍2.深挖个人项目(多个问题不同角度)3.有用过STL吗?常用哪些STL?4.介绍一下你对STL的理解5.深挖STL底层6.Qt有接触过吗?Qt下Tcp通信的整个流程是怎么样的?7.设计模式的问题8.编译原理的简单问题9.讲一下dijkstra算法10.谈一下你对STL的理解11.STL的使用场景12.C++11语法熟悉吗13.工程里面的回溯是什么?14.Widget::Widget(QWidget *parent) :QWidget(parent)什么意思15.算法题:跳台阶(找规律可以发现是个斐波那契数列)16.算法题: 餐厅(区间贪心)17.反问面试官环节三、实习工作分享1.实习专有名词及分析篇1.1SDK:软件开发工具包(Software Development Kit)1.2API:应用程序接口(Application Programming Interface)举例:windows串口通信函数API1.3上位机1.4下位机1.5上位机与下位机区别四、总结一、前言这篇文章是C/C++后端实习经验大礼包的第一弹,后面会持续更新,谢谢大家支持~~撒花,前面说过博主目前在一家互联网公司实习,今天给大家带来第一弹C/C++后端实习经验大礼包,希望大家喜欢。123二、实习面试宝典流程:投简历->简历筛选->笔试->技术电话面->技术视频面->hr面(有些公司可能在中间环节比较多,比如两次技术电话面,两次技术视频面等,视频面多为主管之类的,ps:主管面会参考之前的部门对你面试的评价)1.自我介绍2.深挖个人项目(多个问题不同角度)3.有用过STL吗?常用哪些STL?回答:用过,平时用的比较多,常用vector,map,unordered_map,stack,queue,deque,set,multiset,unordered_set,priority_queue,bitset,list之类的4.介绍一下你对STL的理解回答:STL就是标准模板库,可以提高程序的开发效率和复用性。5.深挖STL底层vector:底层存储是一个可变大小的数组,支持O(1)的随机访问,在尾部之外的位置插入和删除操作时间复杂度是 O(n);deque:双端队列,支持O(1)随机访问在头部和尾部之外的位置插入和删除的时间复杂度是O(n);list: 双向链表,不支持随机访问,只支持顺序访问,在任意位置的插入和删除速度很快;forward_list:单向链表;array是固定大小的数组(vector是可变大小的数组);string:与vector类似,可以理解为特殊的vector,专门用来存储字符,支持随机访问,在尾部之外的位置插入的时间复杂度是O(n);6.Qt有接触过吗?Qt下Tcp通信的整个流程是怎么样的?有的,主要从服务器端和客户端两方面介绍:1.服务器端创建用于监听的套接字(Socket)Socket可以看成在两个程序进行通讯连接中的一个端点,一个程序将一段信息写入Socket中,该Socket将这段信息发送给另外一个Socket中,使这段信息能传送到其他程序中。给套接字设置监听如果有连接到来, 监听的套接字会发出信号newConnected接收连接, 通过nextPendingConnection()函数, 返回一个QTcpSocket类型的套接字对象(用于通信)使用用于通信的套接字对象通信1 发送数据: write2. 接收数据: readAll/read客户端方面:创建用于通信的套接字连接服务器: connectToHost连接成功与服务器通信1 发送数据: write2.接收数据: readAll/read7.设计模式的问题后面我会专门写文章来讲8.编译原理的简单问题后面我会专门写文章来讲9.讲一下dijkstra算法回答:。dijkstra算法是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。时间复杂度:朴素版写法O(V方) 进阶写法:基于优先队列的写法(适用于稀疏图)总复杂度为 O(V log E)Edge:边 Vertex:顶点10.谈一下你对STL的理解C++ STL 做为C++的一个标准类库,包含了复用性最高的数据结构(容器)与算法(模板函数)。STL的容器可以分为以下几个大类:一:序列容器,有vector, list, deque,string.二:关联容器可以分为 set(集合)和 map(映射表)两大类,及其衍生体 multiset 和 multimap。这些容器的底层机制均以 RB-tree(红黑树)实现。RB-tree 也是一个独立容器,但并不开放使用。SGI STL 还提供一个不在标准规格的关联式容器 hash_table(散列表),以及以 hash_table 为底层机制而完成的 hash_set散列集合、hash_map散列映射表、hash_multiset散列多键集合、hash_multimap散列多键映射表。关联容器,类似关联式数据库,每个元素都有一个键值key和一个实值value。关联式容器的内部结构是一个平衡二叉树,包括 AVL-tree、RB-tree、AA-tree,STl 中运用的是 RB-tree红黑树。11.STL的使用场景vector(可变长的动态数组)适用场景:需要快速查找,不需要频繁插入/删除的场景string:string 类型支持长度可变的字符串,实际上就是vector,便于程序员操作字符串的类库。也可以认为string是一个类:string封装了char* ,管理这个字符串,是一个char* 型的容器;array:数组 使用场景:类似vector,比数组更安全(不担心越界),但是内容在栈上,且属于定长容器。deque:(double-ended queue,双端队列)是一种具有队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。使用场景:头尾增删元素很快,随机访问比vector慢一点,因为内部处理堆跳转。中间插入和删除效率交较高。但因为他是list和vector的结合体,出场次数不多。forward_list:使用场景:需要list的优势,但只要向前迭代list:需要频繁插入/删除,不需要快速查找queue:FIFO(先进先出)~( First Input First Output)。底层容器可以是list或deque。set/multiset:需要元素有序,查找/删除/插入性能一样。红黑树效率都是O(logN)。即使是几个亿的内容,最多也查几十次。map/multimap 映射/多重映射:需要key有序将值关联到key,O(logN)查找/删除/插入性能一样12.C++11语法熟悉吗回答:还行,之后问了std::function,我回答是std::function是一个函数包装模板,可以包装下列这几种可调用元素类型:函数、函数指针、类成员函数指针或任意类型的函数对象(例如定义了operator()操作并拥有函数闭包)。std::function对象可被拷贝和转移,并且可以使用指定的调用特征来直接调用目标元素。当std::function对象未包裹任何实际的可调用元素,调用该std::function对象将抛出std::bad_function_call异常。13.工程里面的回溯是什么?回答:用git一直备份版本有需要就回退一下14.Widget::Widget(QWidget *parent) :QWidget(parent)什么意思由于构造函数是指在创建一个新对象的时候,自动执行,因此通常用来实现一些默认操作。此处“Widget::Widget(QWidget *parent) ”定义派生类的构造函数;:QWidget(parent)基类的有参构造函数最终达到:调用基类的有参构造函数,实现对象树上基类的功能15.算法题:跳台阶(找规律可以发现是个斐波那契数列)一个楼梯共有 n 级台阶,每次可以走一级或者两级,问从第 0 级台阶走到第 n 级台阶一共有多少种方案。输入格式共一行,包含一个整数 n。输出格式共一行,包含一个整数,表示方案数。数据范围1≤n≤15输入样例:5输出样例:8#include<bits/stdc++.h>using namespace std;int a=1,b=2,c;int main(){    int n;    cin>>n;    int w=n-2;    if(n==1) cout<<1;    else if(n==2) cout<<2;    else    {        while(w--)        {            c=a+b;            a=b,b=c;        }        cout<<b;    }}123456789101112131415161718192016.算法题: 餐厅(区间贪心)一家餐厅收到了 n 个客人的预约订单。每个订单都有开始时间和结束时间。对于每个订单,餐厅有权利接单,也有权利拒单。接受的订单,两两之间不得有任何时间交集,甚至不得有时刻交集,即如果一个订单的开始时间和另一个订单的结束时间相同,则两订单也不得同时接受。为了赚更多钱,餐厅需要尽可能多的接单。请问,餐厅最多可以接多少单?输入格式第一行包含一个整数 n。接下来 n 行,每行包含两个整数 l,r,表示一个订单的开始时间和结束时间。输出格式输出可以接受的最大订单数量。数据范围1≤n≤5×105,1≤l≤r≤109输入样例1:27 114 7输出样例1:1输入样例2:51 22 33 44 55 6输出样例2:3输入样例3:64 81 54 72 51 36 8输出样例3:2#include<bits/stdc++.h>using namespace std;struct node{    int l,r;};int n;bool cmp(node x,node y){    return x.r<y.r;}int main(){    cin>>n;    node a[n+1];    int i;    for(i=0;i<n;i++)    {        cin>>a[i].l>>a[i].r;    }    sort(a,a+n,cmp);    int temp=a[0].r;    int tot=1;    for(i=1;i<n;i++)    {        if(a[i].l>temp)        {            temp=a[i].r;            tot++;        }    }    cout<<tot;}123456789101112131415161718192021222324252627282930313217.反问面试官环节自由发挥即可,可以提前准备一些大众问题和自己关心的问题。三、实习工作分享1.实习专有名词及分析篇实习中你肯定会接触到很多自己没不熟悉的名词,在这里算法小学徒给大家分享一些cpp后端专有名词的解释:1.1SDK:软件开发工具包(Software Development Kit)软件开发工具包一般都是一些软件工程师为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件时的开发工具的集合。SDK相当于是一个开发者集成的环境,作为APP供应链中重要的一环,在提升App兼容性和灵活性、节约开发成本方面表现卓著。一个产品想实现某些特定功能如消息推送,便可以找到相关的第三方SDK,工程师直接接入SDK,不用再重新开发。这样,工程师可以将更多的时间和精力投入到其他产品业务相关功能的开发上。1.2API:应用程序接口(Application Programming Interface)API又称为应用编程接口,就是软件系统不同组成部分衔接的约定。由于近年来软件的规模日益庞大,常常需要把复杂的系统划分成小的组成部分,编程接口的设计十分重要。程序设计的实践中,编程接口的设计首先要使软件系统的职责得到合理划分。良好的接口设计可以降低系统各部分的相互依赖,提高组成单元的内聚性,降低组成单元间的耦合程度,从而提高系统的维护性和扩展性。简单地说:API就是接口,就是通道,负责一个程序和其他软件的沟通,本质是预先定义的函数。举例:windows串口通信函数API1.CreateFile - 打开串口;2.SetupComm-初始化一个指定的通信设备的通信参数3.ReadFile - 读数据;4.WriteFile - 写数据;5.CloseHandle - 关闭串口;6.GetCommState - 取得串口当前状态;7.SetCommState - 设置串口状态;8.PurgeComm - 清除串口缓冲区 ;9.ClearCommError - 清除串口错误或者读取串口现在的状态;10.SetCommMask - 设置串口通信事件;1.3上位机上位机是指可以直接发出操控命令的计算机。1.4下位机下位机是直接控制设备获取设备状况的计算机。1.5上位机与下位机区别1.上位机一般是集中管理监控机,下位机是指现场直接控制器或控制机。上位机面向管理级用户,下位机面向底层设备控制。2.上位机:上位监视系统,一般为计算机系统(监控软件;下位机:控制系统的现场执行系统,一般为PLC等设备。3上位机是指工业控制中位于较高层次的计算机,一般是指电脑;而下位机是直接控制设备获取设备状况的的计算机,一般是指PLC/单片机之类的。4.经验:通常工控机,工作站,触摸屏作为上位机;而通信控制PLC,单片机等作为下位机,从而控制相关设备元件和驱动装置。四、总结后面博主会继续为大家带来 C/C++后端实习经验大礼包的其他内容,希望大家喜欢,撒花~~,另外根据博主的亲身实习经验,自学能力不管是面试还是实习过程中都非常受青睐, 程序员行业是一个需要终身学习的行业,大部分时间别人教你的东西只能作为一个参考,而且自学这种能力可以让人感觉到了无限的可能和创造性,跨越认识边界,不受限制的感觉真的很奇妙每日一句:不是因为有希望才去努力,而是努力了,才能看到希望。成功重在努力与坚持,抓住时机,就趁现在!与大家共勉!!!————————————————版权声明:本文为CSDN博主「算法小学徒」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/wyhplus/article/details/125771094
  • [技术干货] C/C++ 指针小笔记-转载
    如果想要更详细的了解指针原理、用途,请自行阅读《The C Programming Language》第 5 章。指针是什么指针其实就是一个包含一个变量的地址的变量。如何定义指针定义指针的方式很简单:类型 *指针名称;即可。比如来声明一个变量名为a,类型为int的指针:int *a;1也就是比平时声明变量多了一个型号*。但是这里需要注意的是,声明时候的*a表示的是指针a包含的内存地址指向的内容,而a包含的则是地址。 这个地址开始的一部分连续的空间将会划分给指针,以供存储地址,划出的大小由类型int决定,一般int为 2 个字节(这里的一个字节在有些英文文档中被称为“cell”)。如何获取一个变量的地址刚才说到指针其实就是一个包含一个变量的地址的变量。那么如何获取一个变量的地址呢?这样才可以给指针赋值。方法很简单,使用&符号,如下(a就是上文声明的指针):a=&b;1通过以上表达式,就将变量b的地址赋值给指针a,如果这时候使用*a输出,就会发现输出的是b的值。而且修改b,输出*a的值也会发生改变。如果a并不是指针,那么变量a将会以十六进制存储变量b的地址(一般是十六进制,有些环境、设备可能会有不同)。下面展示输出一个变量地址的方法:#include <stdio.h>int main(){    int a=10;        printf("%x\n",&a);        return 0;}12345678910输出结果如下:bfeff2c8Program ended with exit code: 012可以看到,第一行的bfeff2c8就是变量a的地址。赋值给一个指针指针只负责存储地址,具体的值还是由变量存储。所以赋值给指针,就是将一个变量的地址赋值给它。如下:#include <stdio.h>int main(){    int a=10;    int *b;        b=&a;        printf("%d\n",*b);        return 0;}12345678910111213输出:10Program ended with exit code: 012指针的用途听了上述描述,可能你会觉得指针的作用好像就是新建了一个软连接(symbolic link)或者创建了一个别名(alias)。但是指针最大的作用其实是搭配数组使用。通过指针来使用数组因为一个数组的地址其实是数组第一个元素的地址,而数组在地址上是连续存放的,所以可以对地址加 1 来实现控制数组。如下(实际运行的时候可能会提醒,但是这里出于研究目的忽略提醒):#include <stdio.h>int main(){    int a[5]={1,2,3,4,5};    int *b;        b=&a;        printf("数组地址:%x\n",&a);    printf("数组第一个元素:%d\n",*b);    b=b+1;    printf("是不是数组第二个元素:%d\n",*b);        return 0;}12345678910111213141516输出:数组地址:bfeff2b0数组第一个元素:1是不是数组第二个元素:2Program ended with exit code: 01234这里说明一下,如果在开发过程中,指针指向数组的话,请使用b=&a[0];,这样不会出现提醒。字符串和指针字符串也是数组的一部分,所以也可以使用指针来实现一些功能,例如对比字符串(这个虽然不用指针也能写,但是使用指针的话,代码会变得更简洁)。下面来演示一下指针访问字符串的例子(记得把指针类型换一下,换成char,不然int存放的会是 ASCII编码,而不是字符串的内存地址):#include <stdio.h>int main(){    char a[20]="Hello! World!";    char *b;        b=&a[0];        printf("字符串的地址:%x\n",&a);    printf("字符串的第一个字符:%c\n",*b);    b=b+5;    printf("字符串的第六个字符:%c\n",*b);        return 0;}12345678910111213141516输出:字符串的地址:bfeff2b0字符串的第一个字符:H字符串的第二个字符:!Program ended with exit code: 01234其他用途还有一些其他的用途,但是有上述的知识也不用过多解释了,讲一下思路即可。更多维度的数组C 语言支持二维数组,但是有时候需要更多维度,那么就需要使用指针来嵌套数组,这样可以实现更多维度的数组。一般就是将指向多个数组的多个指针存放在一个数组中,然后通过上述方法来使用。处理命令选项这个一般使用不多,因为现在也没多少人使用命令行,都用图形化了,但是我还是要说一下。先看一下我的另一篇博客《C语言中函数main的参数argc和argv是什么》。argv是一个指向一个字符串数组的指针,数组包含了参数,每个字符串就是一个参数,最后一个元素为0。不过一般习惯使用多级指针来操作字符串。这里介绍一下,一般的命令行程序,使用起来的命令如下:程序名 -短选项 --长选项 内容1短选项为-加一个字母,长选项一般为--加一个单词。现在有些程序的短选项会省略-。短选项一般可以写到一起,举个例子:ls -a -f也可以写成ls -af。而这一功能的实现就需要使用指针(首先这是个存放了指向字符串指针的数组,其次指针真的更方便)。————————————————版权声明:本文为CSDN博主「zhonguncle」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_33919450/article/details/126129081
  • [技术干货] 、Python 比 C++ 慢 8 倍、29 倍?-转载
    整理 | 苏宓出品 | CSDN(ID:CSDNnews)近日,来自多伦多大学和 YScope 公司(为软件系统提供创新的日志管理和故障排除工具。由一群计算机工程教授和博士创立)的 David Lion、多伦多大学 Adrian Chiu 和 Michael Stumm、多伦多大学和 YScope 公司 Ding Yuan 共同发布了一份《调查托管语言的运行时性能:为什么 JavaScript 和 Python 比 C++ 慢了 8 倍和 29 倍,而 Java 和 Go 却能更快》(https://www.usenix.org/system/files/atc22-lion.pdf)的论文分析报告,深度剖析了不同编程语言运行时在代码开发中真实的性能情况,由此方便开发者可以精确地测量执行任何字节码指令所花费的时间等。性能是系统软件不得不面对的挑战在报告中,研究人员指出,自 2015 年以来,具有集成运行时环境的编程语言越来越受欢迎,其中,全球知名的代码托管平台 GitHub 上最受欢迎的三种语言分别是 JavaScript、Java 和 Python。作为开发利器,编程语言帮助开发者快速构建各种应用程序和服务,也极大地提高了生产力。同时,这些语言自身也提供了各种功能,如动态类型检查、带有垃圾收集的内存管理,以及动态内存安全检查等等。为此,研究人员用「托管语言」(managed languages)专业术语来指代这些类型的编程语言。现实来看,托管语言越来越多地被用于实现性能至关重要的系统软件上,如Hadoop 和 Spark 都在 Java 虚拟机(JVM)上运行,因为它们分别用 Java 和 Scala 实现;Kubernetes、etcd(分布式键值存储)和 M3(由 Uber 建立的分布式时间序列数据库和查询引擎)都是用 Go 实现的。当前,甚至连操作系统(OS)的内核 Biscuit 也是用 Go 实现的 。Openstack、Paypal、Instagram 和 Dropbox 都大量使用 Python,其中,Python 是 Dropbox "在后台服务和桌面客户端应用中使用最广泛的语言",在一个存储库中就有近 400 万行 Python 代码;JavaScript 也被用于 Facebook 的 Bladerunner pub/sub 系统的性能关键路径中。在开发过程中,编程语言的性能在一开始很少会被考虑到项目中,部分原因是不少开发者认为性能问题可以在以后慢慢去解决,也许可以通过简单地增加硬件来进行横向扩展。不过,随着代码产品或服务使用规模的扩大,服务变得越来越慢或者硬件成本变高,性能成为一个不容忽视的问题。这也是为什么 Stream 要放弃了 Python 而改用 Go、 Discord 从 Go 切换到 Rust、Twitter 从 Ruby on Rails 切换到 Scala 和 Java 的主要原因。不少开发者往往为了提升性能,想破脑袋,但现实只有两条路,一条是从现有的代码中想尽办法尽可能地做优化,另一条是思考使用的编程语言是否已经达到了性能极限,看看有没有必要将旧的代码移植到一个新的性能更高的语言上。为了彻底解开系统软件中不同编程语言导致的性能问题,研究人员决定以 C++ 为极限,对 Java、Go、JavaScript 和 Python 四种编程,还有应用最广泛的运行时系统 CPython、OpenJDK。Node.js 与 JavaScript 的 V8 引擎进行深入的定量性能分析。同时,研究人员还从头开始建立了 6 个应用程序,并创建了一个名为 LangBench 基准(https://github.com/topics/langbench)。这些应用程序涵盖了各种不同的计算强度、内存使用、网络和磁盘 I/O 强度以及可用的并发性的应用场景等复杂性。对此,研究人员全面分析了它们的完成时间、资源使用和可扩展性。测试方法值得一提的是,研究人员指出,这份论文没有也不可能全面地回答与语言运行时的性能有关的每一个问题。本文只是评估了四种语言的运行时,而且对于每种语言,只评估了最广泛使用的实现。此外,研究人员只在一个单一的操作系统/硬件堆栈上运行了工作负载。其研究结果与使用的基准有关,这些基准模拟了现实生活中的应用,但可能不代表广泛的应用。在测试方法上,研究人员在两台内部服务器上进行了实验,每台服务器有 2 个Xeon E5-2630V3、16 个虚拟核心、2.4GHz CPU、256GB DDR4 内存和两个 7200 RPM 硬盘。它们运行的系统是 Linux 4.15.0,并通过 10Gbps 的互联网络连接。对于 C++ 程序,研究人员使用的是 GCC 9.3.0 根据 C++17 标准用 -O3 进行编译。对于 OpenJDK 13、CPython 3.8.1 和Go 1.14.1 ,其使用了各自语言的参考实现。同时,使用 Node.js 13.12.0 和 V8 7.9.317.25 版本。研究人员对每个基准进行了 5 次测试,取平均值。其中,在运行键-值存储、日志分析器和文件服务器的基准时,client 和 worker 线程的数量从 1 到 1024 不等。对于 OpenJDK 和 V8 来说,最小的内存量是通过确定不会导致崩溃的第一个堆配置来设置的;对于 Go 来说,GOGC 被设置为5%。然后研究人员不断增加堆的设置,直到性能不再提高。其使用第一个设置的结果(即最小的堆大小)得出最佳性能。对于日志解析器和文件服务器基准,所用的日志文件被存储在一个复制系数为 2 的分布式文件系统上。 在运行每个基准之前,研究人员都清除了 Linux 的页面缓存,以保证测试准确性。其中,优化的 GCC 平均速度最快,Go 和 OpenJDK 紧随其后,比 GCC 慢了  1.30 倍和 1.43 倍。令人印象深刻的是,在 12 项基准测试中,Go 和 OpenJDK 有 3 项超过了优化的 GCC。总体而言,研究人员发现 V8 / Node.js 和 CPython 表现最差,执行应用程序的平均速度分别比 C++ 应用程序慢 8.01 倍和 29.50 倍,这意味着运行时下,JavaScript、Python 要比 C++ 慢这么多。更糟糕的是,这两个运行时上的应用程序扩展性很差,因为它们无法有效地利用多个内核。在极端情况下,CPython 比 GCC 慢了 129.66 倍(在排序基准中)。V8/Node.js 和 CPython 只有在工作负载受到磁盘 I/O 的瓶颈时,即在文件服务器基准中,才与 GCC 有竞争力。相比之下,OpenJDK 和 Go 应用程序即 Java 和 Go 语言比 C++ 更具有性能竞争力,运行速度仅慢了 1.43 倍和 1.30 倍,并且可以轻松扩展到多个内核。在一些应用中,OpenJDK 和 Go 的性能超过了 C++ 的同类产品。更多完整报告内容详见:https://www.usenix.org/system/files/atc22-lion.pdf