搭建算法日志自检小系统

🥒 前言

目前演示的是一个工具,但如此,未来完成有潜力可以演变为一整套系统。

👑现场人员自检失败表计点位教程V2.0

NOTE: 如果没有logfiles-meter-tool“目录请联系我们进行提供

👇

进入<dist>目录

👇

【关键步骤一】、将我们需要分析的日志文件放到该目录中

👇

【关键步骤二】、配置<日志名称><任务ID>

config.ini配置文件内容和详细解析如下图:

@pararm:[logfile_path]是存放日志的路径,但由于与<应用程序>处于同目录下,所以相当于日志名,该日志包含您刚跑完测试的日志内容。
@pararm:[work_id] 是您任务的序号,如下图,Ftp图片路径下包含”task“/"Task"的字符串,也就是灰色框框住的那一串正式您此次任务的序号。

👇

【关键步骤三】、运行<应用程序>

👇

【异常如果出现下面的红框信息,是因为任务ID输入错了,没有匹配结果,根据提示操作。【如果有匹配结果,列出来的任务id后面会打√的。】

正常】正常运行终端结果

👇

自动生成自检报表meterLog_checking-<任务ID>.txt,位于<分析报告生成处>目录下

👇

里面部分关键内容如下:

👇

接下来大家请对照这张表,找到【需要现场人员自检】【错误】进行搜索排查,有多个,可以从上往下慢慢来。

👇

以【通用类】<序号7>"该点位没有录入"作为例子,打开自检文本meterlog_checking.txt,搜索指定错误。

👇

NOTE:如果出现无需现场人员自检的错误,需要提供一下日志文件,可能后续还需提供图片我们这边进行优化。

NOTE:如果点位出现多次,只会取最后一次也就是最新一次的结果。

🍉一些使用样例图: 

👑Code

# -*- coding: utf-8 -*-
'''
参考diamagnetic:
# 兰江
python3 meterPoint_Self-Checking_sys.py -p meterlog -t 30M00000036658634_task1703485183168_20231225141946
# 金鼎
python3 meterPoint_Self-Checking_sys.py -p meterlog -t 30M00000036658634_task1703485183168_20231225141947
'''
import os
import re
import json
import configparser

def get_settings():   
    config = configparser.ConfigParser()
    config.read('./config.ini')

    log_file = config.get('settings', 'logfile_path')
    work_id = config.get('settings', 'work_id')
    return log_file, work_id

def extract_debug_segments(log_file):
    debug_segments = []
    with open(log_file, 'r', encoding='utf-8') as file:
        lines = file.readlines()
        start_line = None
        end_line = None
        segment = []

        for i, line in enumerate(lines):
            if 'Debug' in line or '收到请求' in line or '数据库信息' in line:
                if start_line is None:
                    start_line = i
                segment.append(line.strip())   

            elif '结果放入队列待发送' in line:
                if start_line is not None:
                    end_line = i
                    segment.append(line)
                    debug_segments.append([segment, start_line, end_line])
                    segment = []
                    start_line = None
                    end_line = None

    return debug_segments
def process_request(request_str):
    target_index = request_str.index("{")
    # 按照":"分割字符串
    split_str = request_str[target_index:]
    # 获取分割后数组中最后一个索引所保存的信息
    json_str = split_str.strip().replace("—", "-").replace("'", "\"")

    objectList_request_str = json.loads(json_str)['objectList'][0]
    # for k in objectList_request_str:
    #     print(k)
    return objectList_request_str

def get_pointList_length(json_str):
    
    pattern = r"'Position': '(\[.*?\])'"
    matches = re.search(pattern, json_str)
    if matches is None:
        return 0
    position_list = json.loads(matches.group(1))
    # print("position_list:", position_list)
    return len(position_list)

def process_sql(json_str):

    json_str = json_str[json_str.index("MinValue"):]
    json_str = "{'" + json_str
    json_str = json_str.replace("'", "\"")
    sql_dict = json.loads(json_str)
    return sql_dict

def process_result(json_str):

    json_str = json_str[json_str.index("code"):-5]
    json_str = "{'" + json_str
    # print(json_str)
    json_str = json_str.replace("'", "\"")
    json_str = json_str.replace("None", "null")
    sql_dict = json.loads(json_str)
    return sql_dict

def contains_digit(string):
    pattern = r'\d'  # 正则表达式模式,匹配任意数字
    if re.search(pattern, string):
        return True
    else:
        return False

def get_path_separator(path):
    if '/' in path:
        return '/'
    elif '\\' in path:
        return '\\'
    elif '\\' * 2 in path:
        return '\\\\'
    else:
        return None

def extract_work_path_tool(goal_str):
    split_str = get_path_separator(goal_str)
    pathIdx = -1
    splitPaths = goal_str.split(split_str)
    for idx, ss in enumerate(splitPaths):
        if ss == 'CCD':
            pathIdx = idx
    if pathIdx == -1:
        raise Exception("您的任务路径中没有CCD路径")
    work_path = splitPaths[pathIdx-1]
    return work_path

if __name__ == "__main__":
    print("---------------------------------------------------------------------")
    # 摄像机偏移严重+模糊
    Error_withoutDetctor = []
    # 未识别出指针
    Error_withoutPointer = []
    # 读取ftp图失败
    Error_loadftp = []
    # minIO无图
    Error_withoutMinioImage = []
    # minIO错图
    Error_minioErrorImage = []
    # 点位未录入
    Error_withoutId = []
    # 表计类型录入错误
    Error_clsType = []
    # 最大最小值设置错误
    Error_minMaxSet = []
    # 最大最小值未设置
    Error_withoutMinMax = []
    # 未打刻度点位
    Error_withoutPointList = []
    # 刻度打点错误
    Error_PointList = []
    # 未识别到任何油面表!
    Error_ymb = []
    # 画框与推理出来的油面表无匹配
    Error_withoutYmbMatch = []
    # OCR没有检测出数字
    Error_ocrRec = []
    # OCR没有检测出表盘
    Error_ocrDet = []
    # ===========================核
    # 获取命令行参数
    log_file, work_id =  get_settings()
    debug_segments = extract_debug_segments(log_file)
    error_num = 0
    # not_reading_num = 0
    # type_num = 0
    ymb_num, sxb_num, bj_num = 0, 0, 0
    ymb_errorNum, sxb_errorNum, bj_errorNum = 0, 0, 0
    # 过滤一遍只剩下最新的
    filter_schem = {}
    piNums_schem = {}
    not_del_ids = []
    # 任务计算
    workNUms_schem = {}
    for idx, segment in enumerate(debug_segments):
        strat_line = segment[1]
        end_line = segment[2]
        for line in segment[0]:
            if "收到请求" in line:
                # print('【请求信息】: ',end='')
                objectList_request_str = process_request(line)
                # 任务ID
                work_path = extract_work_path_tool(objectList_request_str['imageUrlList'][0])
                if not work_path in workNUms_schem:
                    workNUms_schem[work_path] = 1
                else:
                    workNUms_schem[work_path] += 1
                if work_path != work_id:
                    break
                #点位ID
                extract_objectId = objectList_request_str['objectId']
                if not extract_objectId in filter_schem.keys():
                    # 新增
                    filter_schem[extract_objectId] = idx
                    piNums_schem[extract_objectId] = 1
                else:
                    # 更新
                    filter_schem[extract_objectId] = idx
                    piNums_schem[extract_objectId] += 1
                    not_del_ids.append(idx)
                break

    print('|任务id                                                        |数量')
    print("---------------------------------------------------------------------")
    for wnn in workNUms_schem:
        if work_id == wnn:
            print(wnn, '     |',workNUms_schem[wnn],end='   ✔\n')
        else:
            print(wnn, '     |',workNUms_schem[wnn])
    
    print('*********************************************************************')
    if not work_id in workNUms_schem:
        print("[告警]任务ID有误,本日志中无匹配任务。上方已列出所有任务ID以及他们的数量!请根据上面列出的任务ID,输入正确的任务ID。")
        print('*********************************************************************')
        work_id = input('[Input]:')
        print("[提示]此次任务ID已经修改为:<{}>".format(work_id))
        # 重置
        filter_schem = {}
        piNums_schem = {}
        not_del_ids = []
        for idx, segment in enumerate(debug_segments):
            strat_line = segment[1]
            end_line = segment[2]
            for line in segment[0]:
                if "收到请求" in line:
                    objectList_request_str = process_request(line)
                    # 任务ID
                    work_path = extract_work_path_tool(objectList_request_str['imageUrlList'][0])
                    if work_path != work_id:
                        break
                    # 点位ID
                    extract_objectId = objectList_request_str['objectId']
                    if not extract_objectId in filter_schem.keys():
                        # 新增
                        filter_schem[extract_objectId] = idx
                        piNums_schem[extract_objectId] = 1
                    else:
                        # 更新
                        filter_schem[extract_objectId] = idx
                        piNums_schem[extract_objectId] += 1
                        not_del_ids.append(idx)
                    break
        print('*********************************************************************')

    # print(piNums_schem)
    # 找到第一次出现重复点位的位置
    print("此次任务ID:<{}>中".format(work_id))
    idsNums_result1 = len({key: value for key, value in piNums_schem.items() if value == 1})
    print("点位 [=1] 的数量:",idsNums_result1) 
    idsNums_result2 = len({key: value for key, value in piNums_schem.items() if value > 1})
    print("点位 [>1] 的数量:",idsNums_result2)  
    print('*********************************************************************')
    # print(filter_schem, len(filter_schem)) 
    # ------------------过滤结束
    sumWorkNum, filter_workId_num, filter_objectId_num = 0, 0, 0
    for idx, segment in enumerate(debug_segments):
        # print(segment[0],'\n',len(segment[0]))
        error_flag = False
        ftpLoad_flag = False
        # print('Start Line:', segment[1])
        # print('End Line:', segment[2])
        for line in segment[0]:
            if "收到请求" in line:
                # print('【请求信息】: ',end='')
                objectList_request_str = process_request(line)
                extract_objectId = objectList_request_str['objectId']
                # print(extract_objectId)
                # print(objectList_request_str['imageUrlList'][0], work_id)
                # 过滤掉【不同任务】
                if not work_id == extract_work_path_tool(objectList_request_str['imageUrlList'][0]):
                    filter_workId_num += 1
                    break
                # 过滤掉【同任务相同点位取最新】
                if ( piNums_schem[extract_objectId] > 1 ) and ( idx != filter_schem[extract_objectId] ):
                    # print(idx, filter_schem[extract_objectId])
                    filter_objectId_num += 1
                    break

                # 这里才是没被break的真正点位数量
                sumWorkNum += 1
            
            elif '数据库信息' in line:
                # print(line)
                if line.split("【数据库信息】")[-1] == '{}':
                    # 数据库信息为空
                    # print('*pointList_length:0')
                    # print('{}')
                    Error_withoutId.append(extract_objectId)
                    error_num += 1
                    break
                else:
                    # 数据库有信息
                    pointList_length = get_pointList_length(line)
                    sql_schem = process_sql(line)
                    MinValue = sql_schem['MinValue']
                    MaxValue = sql_schem['MaxValue']
                    meter_type = sql_schem['AlgorithmType']
                    ImagePath = sql_schem['ImagePath']

                    if meter_type == 'meter_v5':
                        bj_num += 1
                    if meter_type == 'meter_ywj':
                        ymb_num += 1
                    if meter_type == 'paddleocr':
                        sxb_num += 1

                    if meter_type == 'meter_v5':
                        if len(MinValue)== 0 or len(MaxValue) == 0:
                            Error_withoutMinMax.append(extract_objectId)
                            MinValue = float(0)
                            MaxValue = float(100)
                            error_flag = True
                        else:
                            MinValue = float(MinValue)
                            MaxValue = float(MaxValue)

                    # 表计类型录入错误(如果打点了,但表计类型不是meter_v5)
                    if meter_type != 'meter_v5' and pointList_length != 0:
                        Error_clsType.append(extract_objectId)
                        error_flag = True
                    # 未打刻度点位
                    if meter_type == 'meter_v5' and pointList_length == 0:
                        Error_withoutPointList.append(extract_objectId)
                        error_flag = True

                    # print(sql_schem, end=',')
                    # print("*pointList_length:", pointList_length)
            
            elif '结果放入队列待发送' in line:
                result_schem = process_result(line)
                # print('【结果队列信息】:',end='')
                # print(result_schem)
                if result_schem['code'] == '2001':
                    Error_loadftp.append(extract_objectId)
                    ftpLoad_flag = True
                    error_flag = True
                    break

                if result_schem['desc'] == '未识别到任何油面表!':
                    error_flag = True
                    Error_ymb.append(extract_objectId)

            else:
                splitContent = line.split("【Debug】")[-1]
                if "成功检测到表盘!表盘信息是" in splitContent:
                    det_clsType = splitContent.split(":")[-1].strip().strip("").strip("[]").strip()
                    if splitContent.split(":")[-1].strip().strip("") == "[]":
                        Error_withoutDetctor.append(extract_objectId)
                        error_flag = True

                    if not 'sxb' in det_clsType and meter_type == 'paddleocr':
                        Error_ocrDet.append(extract_objectId) 
                        error_flag = True

                    if 'ywb' in det_clsType:
                        ywb_minMax = [
                            [-20, 140],
                            [0, 160]
                        ]
                        iter_minMax = [MinValue, MaxValue]
                        if not iter_minMax in ywb_minMax:
                            Error_minMaxSet.append(extract_objectId)
                            error_flag = True
                            
                    elif 'xldlb' in det_clsType:
                        xldlb_minMax = [
                            [0, 3.0],
                            [0, 10],
                            [0, 9],
                            [0, 1]
                        ]
                        iter_minMax = [MinValue, MaxValue]
                        if not iter_minMax in xldlb_minMax:
                            Error_minMaxSet.append(extract_objectId)
                            error_flag = True
                # if '动作次数' in splitContent:
                #     print(splitContent)
                # if '泄漏电流值' in splitContent:
                #     print(splitContent)
                if 'OCR没有检测出数字' in splitContent:
                    Error_ocrRec.append(extract_objectId)
                    error_flag = True

                if "没识别出指针" in splitContent:
                    Error_withoutPointer.append(extract_objectId)
                    error_flag = True
                
                 # 画框与推理出来的油面表无匹配
                if '画框与推理出来的油面表无匹配' in splitContent:
                    Error_withoutYmbMatch.append(extract_objectId)
                    error_flag = True

                if len(ImagePath) == 0 or "MinIo中缺失该点位基准图" in splitContent:
                    Error_withoutMinioImage.append(extract_objectId)
                    error_flag = True

                # 用于验证
                if '读数结果' in splitContent and not contains_digit(splitContent):
                    # not_reading_num +=1
                    # 验证后 无读数个数和错误个数基本一致->代表验证成功
                    # print(not_reading_num)
                    continue
        if error_flag and not ftpLoad_flag: 
            if meter_type == 'meter_v5':
                bj_errorNum += 1
            if meter_type == 'meter_ywj':
                ymb_errorNum += 1
            if meter_type == 'paddleocr':
                sxb_errorNum += 1
            error_num += 1

        elif error_flag and ftpLoad_flag:
            error_num += 1
            meter_type = ''
            
    print("错误总数比:【{}/{}】-> 即正确率:{}%".format(error_num,sumWorkNum,round((1-error_num/sumWorkNum)*100, 2)))
    # ===========================核
    # 写入
    # with open('meterLog_checking.txt', 'w') as output_file:
    saveLogFile_path = './分析报告生成处'
    if not os.path.exists(saveLogFile_path):
        os.makedirs(saveLogFile_path)
    with open(os.path.join(saveLogFile_path,'meterLog_checking-{}.txt'.format(work_id)), 'w', encoding='utf-8') as output_file:
        
        output_file.write('您这次序号为[{}]的任务:\n---------------------------------\n一共测试表计数量:[{}]个, 错误点位为:[{}]个, 未打点个数为:[{}]。\n<在此之中>\n,指针类表计成功占[{}/{}]个\n,油面表成功占[{}/{}]个\n,数显表成功占[{}/{}]个。'.format(work_id,sumWorkNum,error_num,len(Error_withoutId),bj_num - bj_errorNum, bj_num,ymb_num - ymb_errorNum, ymb_num, sxb_num - sxb_errorNum, sxb_num))

        # output_file.write("-> 即正确率:{}%".format(error_num,sumWorkNum,round((1-error_num/sumWorkNum)*100, 2)))

        output_file.write('\n')
        output_file.write('---------------------------------\n')
        output_file.write('NOTE:接下来,请您根据所需要查询的错误名称,使用<ctrl+F>的方式进行查询。\n')
        output_file.write('---------------------------------\n')

        output_file.write("【错误】可能存在摄像机偏移严重/模糊<数量:{}>:".format(str(len(set(Error_withoutDetctor)))) + "\n")
        output_file.write("\n".join(set(Error_withoutDetctor)))
        output_file.write('\n')

        output_file.write("【错误】未识别出指针<数量:{}>:".format(str(len(set(Error_withoutPointer)))) + "\n") 
        output_file.write("\n".join(set(Error_withoutPointer)))
        output_file.write('\n')

        output_file.write("【错误】读取ftp图失败<数量:{}>:".format(str(len(set(Error_loadftp)))) + "\n")
        output_file.write("\n".join(set(Error_loadftp)))
        output_file.write('\n')

        output_file.write("【错误】minIO无图<数量:{}>:".format(str(len(set(Error_withoutMinioImage)))) + "\n")
        output_file.write("\n".join(set(Error_withoutMinioImage)))
        output_file.write('\n')

        output_file.write("【错误】该点位没有录入<数量:{}>:".format(str(len(set(Error_withoutId)))) + "\n")
        output_file.write("\n".join(set(Error_withoutId)))
        output_file.write('\n')

        output_file.write("【错误】表计类型录入错误<数量:{}>:".format(str(len(set(Error_clsType)))) + "\n")
        output_file.write("\n".join(set(Error_clsType)))
        output_file.write('\n')

        output_file.write("【错误】最大最小值未设置<数量:{}>:".format(str(len(set(Error_withoutMinMax)))) + "\n")
        output_file.write("\n".join(set(Error_withoutMinMax)))
        output_file.write('\n')

        output_file.write("【错误】未打刻度点位<数量:{}>:".format(str(len(set(Error_withoutPointList)))) + "\n")
        output_file.write("\n".join(set(Error_withoutPointList)))
        output_file.write('\n')

        output_file.write("【错误】最大最小值设置错误<数量:{}>:".format(str(len(set(Error_minMaxSet)))) + "\n")
        output_file.write("\n".join(set(Error_minMaxSet)))
        output_file.write('\n')

        output_file.write("【错误】存在刻度打点错误(暂未启用)<数量:{}>:".format(str(len(set(Error_PointList)))) + "\n")
        output_file.write("\n".join(set(Error_PointList)))
        output_file.write('\n')

        for ey in Error_ymb:
            if ey in Error_withoutYmbMatch:
                Error_ymb.remove(ey)
        output_file.write("【错误】未识别到任何油面<数量:{}>:".format(str(len(set(Error_ymb)))) + "\n")
        output_file.write("\n".join(set(Error_ymb)))
        output_file.write('\n')

        output_file.write("【错误】画框与推理结果无匹配<数量:{}>:".format(str(len(set(Error_withoutYmbMatch)))) + "\n")
        output_file.write("\n".join(set(Error_withoutYmbMatch)))
        output_file.write('\n')

        output_file.write("【错误】OCR没有检测出数字<数量:{}>:".format(str(len(set(Error_ocrRec)))) + "\n")
        output_file.write("\n".join(set(Error_ocrRec)))
        output_file.write('\n')

        output_file.write("【错误】OCR没有检测出表盘<数量:{}>:".format(str(len(set(Error_ocrDet)))) + "\n")
        output_file.write("\n".join(set(Error_ocrDet)))
        output_file.write('\n')

    print('<*总共统计数量:{}>\n<*过滤掉的非此次任务ID数量:{}>\n<*过滤掉的重复的点位ID数量:{}>'.format(len(debug_segments),filter_workId_num, filter_objectId_num))
    print('*********************************************************************')
    input("Press any key to exit...")

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用AutoDL云计算平台训练并测试Pytorch版本NeRF代码

文章目录 前言一、数据集及代码获取二、租用并设置服务器三、Pycharm远程开发四、训练并测试代码 前言 因为第一次在云服务器上跑代码&#xff0c;所以在这里记录一下。 一、数据集及代码获取 nerf-pytorch项目是 NeRF 的忠实 PyTorch 实现&#xff0c;它在运行速度提高 1.3 倍…

docker 利用特权模式逃逸并拿下主机

docker 利用特权模式逃逸并拿下主机 在溯源反制过程中&#xff0c;会经常遇到一些有趣的玩法&#xff0c;这里给大家分享一种docker在特权模式下逃逸&#xff0c;并拿下主机权限的玩法。 前言 在一次溯源反制过程中&#xff0c;发现了一个主机&#xff0c;经过资产收集之后&…

SSL证书与HTTPS的关系

SSL证书是一种数字证书&#xff0c;由权威的证书颁发机构颁发。它包含了一个公钥和有关证书所有者的一些信息&#xff0c;如名称、组织、邮箱等。SSL证书的主要作用是实现数据加密和身份验证&#xff0c;确保数据在传输过程中的安全性和完整性。 HTTPS是一种基于HTTP协议的安全…

Web开发:SQLsugar的安装和使用

一、安装 第一步&#xff0c;在你的项目中找到解决方案&#xff0c;右键-管理解决方案的Nuget 第二步&#xff0c;下载对应的包&#xff0c;注意你的框架是哪个就下载哪个的包&#xff0c;一个项目安装一次包即可 点击应用和确定 安装好后会显示sqlsugar的包 二、使用&#xf…

UOS Python+Qt5实现声卡回路测试

1.回路治具设计&#xff1a; 2.Ui界面&#xff1a; 3.源代码&#xff1a; # -*- coding: utf-8 -*-# Form implementation generated from reading ui file SoundTestWinFrm.ui # # Created by: PyQt5 UI code generator 5.15.2 # # WARNING: Any manual changes made to this…

3d云渲染用什么显卡比较好?3d云渲染显卡推荐

3D云渲染能加快渲染速度&#xff0c;是众多公司的首选方案&#xff0c;作为公司负责人&#xff0c;选择哪个平台值得思考&#xff0c;今天我就说下我的选择吧。 首先我们要了解云渲染的渲染方式&#xff0c;云渲染的渲染方式分两种&#xff0c;一种是CPU渲染&#xff0c;一种是…

C++程序员必备的面试技巧

“程序员必备的面试技巧&#xff0c;就像是编写一段完美的代码一样重要。在面试战场上&#xff0c;我们需要像忍者一样灵活&#xff0c;像侦探一样聪明&#xff0c;还要像无敌铁金刚一样坚定。只有掌握了这些技巧&#xff0c;我们才能在面试的舞台上闪耀光芒&#xff0c;成为那…

Windows 远程控制之 PsExec

1、介绍&#xff1a; PsExec 是一种轻量级 telnet 替代品&#xff0c;可让你在其他系统上执行进程&#xff0c;并为控制台应用程序提供完整交互性&#xff0c;而无需手动安装客户端软件。 PsExec 最强大的用途包括在远程系统上启动交互式命令提示符&#xff0c;以及 IpConfig …

【LeetCode】2619. 数组原型对象的最后一个元素

数组原型对象的最后一个元素 题目题解 题目 请你编写一段代码实现一个数组方法&#xff0c;使任何数组都可以调用 array.last() 方法&#xff0c;这个方法将返回数组最后一个元素。如果数组中没有元素&#xff0c;则返回 -1。 你可以假设数组是 JSON.parse 的输出结果。 示例 …

Postgres 中文周报:Postgres Weekly 537 期

本周报由 Cloudberry Database 社区编译自英文版《Postgres Weekly》&#xff0c;译文较原文有所调整。 推荐博文 &#x1f3c6; PostgreSQL: The DBMS of the Year 2023 PostgreSQL 荣获 DB-Engines 网站 2023 年度 DBMS 冠军。DB-Engines 收集了 480 款数据库系统信息并跟踪…

JAVA循环结构

目录 if语句 1、if语句第一种格式 2、if的第二种格式 3、if的第三种格式 switch语句 1、switch格式 2、switch练习 3、switch规则 循环 1、格式 2、练习 if语句 1、if语句第一种格式 package 分支结构;import java.util.Scanner;public class ifjiegou {public sta…

C Primer Plus 第6版 编程练习 chapter 13

文章目录 1. 第1题1.1 题目描述1.2 编程源码1.3 结果显示 2. 第2题2.1 题目描述2.2 编程源码2.3 结果显示 3. 第3题3.1 题目描述3.2 编程源码3.3 结果显示 4. 第4题4.1 题目描述4.2 编程源码4.3 结果显示 5. 第5题5.1 题目描述5.2 编程源码5.3 结果显示 6. 第6题6.1 题目描述6.…

​水经微图Web1.5.0版即将上线

让每一个人都有自己的地图&#xff01; 最近我们上线了水经微图&#xff08;简称“微图”&#xff09;Web1.4.0版&#xff0c;现在1.5.0版也即将上线&#xff0c;接下来的1.6.0版研发计划也已经确定好。 这里就来分享一下已上线的版本&#xff0c;即将上线的版本&#xff0c;…

virtualbox Ubuntu 网络连接

一、网络连接需求1—— 上网&#xff1a; 虚拟机默认的NAT连接方式&#xff0c;几乎不需要怎么配置&#xff0c;即可实现上网。 enp0s17以太网必须要开启&#xff0c;才能上网&#xff1b; 但是主机ping不通虚拟机&#xff0c;貌似可以ping 127.0.0.1; 二、主机和虚拟机相互p…

8年经验之谈!一文看懂性能测试的流程!

每天做着点点点测试有没有危机感&#xff1f; 突然有一天&#xff0c;领导说&#xff1a;“小王&#xff0c;今天把996福报系统压一下&#xff0c;下班前把压测报告发我邮箱。” 啥&#xff1f;压测&#xff1f;今天&#xff1f;报告&#xff1f;怎么压&#xff1f;怎么写&am…

java多线程面试集合(1)

1.并行和并发的区别 操作系统角度&#xff0c;线程是最小的执行单位 并行同一时刻两个线程都在执行&#xff0c;这就要求要有两个cpu。并发就是 同一时刻&#xff0c;只有一个执行但是在一个时间段内&#xff0c;两个线程都执行了&#xff0c;并发依赖于CPU切换线程&#xff…

20240112-【UNITY 学习】实现第一人称移动教程

1、创建一个空物体&#xff0c;挂载Rigidbody组件&#xff0c;并设置相应参数 2、在上述空物体下创建一个胶囊体&#xff0c;两个空物体&#xff0c;一个用来控制朝向&#xff0c;另一个用来控制摄像机 3、给摄像机创建一个父物体&#xff0c;并挂载脚本MoveCamera_01.cs using…

YOLOv8改进 更换层次化视觉变换器的网络结构

一、SwinTransformer论文 论文地址:arxiv.org/pdf/2103.14030.pdf 二、 SwinTransformer网络结构 SwinTransformer是一种基于transformer的图像分类网络结构。SwinTransformer是由微软亚洲研究院提出的,其特点是具有高效的计算和参数效率。 SwinTransformer的网络结构主要…

java每日一题——打印100以内个位和十位相同,尾数为1,3,5,7的数字

前言&#xff1a; 打好基础&#xff0c;daydayup! 题目&#xff1a;打印100以内个位和十位相同&#xff0c;尾数为1,3,5,7的数字 思路&#xff1a;1&#xff0c;个位通过对10求余数可求出1&#xff0c;3&#xff0c;5&#xff0c;7&#xff1b; 2&#xff0c;十位可通过先除10…