【无标题】jenkins消息模板(飞书)
这里写目录标题
- Jenkins 安装的插件
- 发送消息到飞书
- 预览 1 (单Job)
- 预览 2 (多Job,概览)
Jenkins 安装的插件
插件名称 | 作用 |
---|---|
Rebuilder | |
-
Rebuilder。
官方地址:https://plugins.jenkins.io/rebuild
安装方式:在Jenkins插件当中直接搜索即可安装。
功能说明:此插件可以直接重复上次构建,也可以用于查看一些参数比较复杂的构建时,上次构建所选的参数是什么。非常nice的一个插件。 -
AnsiColor。
官方地址:https://plugins.jenkins.io/ansicolor
安装方式:在Jenkins插件当中直接搜索即可安装。
功能说明:扩展支持我们在shell当中定义的echo -e指令,从而给一定的输出上颜色。
使用方式:点此跳转到使用介绍。(opens new window) -
Maven Release Plug-in。
maven风格插件。
安装方式:在Jenkins插件当中直接搜索即可安装。 -
user build vars。
官方地址:https://wiki.jenkins.io/display/JENKINS/Build+User+Vars+Plugin
安装方式:在Jenkins插件当中直接搜索即可安装。
功能说明:通过此插件,让整个Jenkins系统中的用户参数成为一个可调用的变量。
使用方式:在构建环境中选中Set Jenkins user build variables。 -
Post build task
功能说明:此功能允许您关联 shell 或批处理脚本,这些脚本根据构建日志输出在 Hudson
上执行某些任务。如果日志文本与构建日志文件中的某处匹配,脚本将执行。例如:如果在日志文本中指定了“IOException”,并且构建日志文件包含字符串“IOException”,则脚本将执行。
允许使用 Java 正则表达式,并且可以将组用作脚本参数。如果文本是“Last Build : #(\d+)”并且脚本是“script.sh”,那么如果日志包含一行“Last
Build : #4”,脚本“script.sh 4”将被调用. -
MultiJob Phase
功能说明:上下游执行
发送消息到飞书
预览 1 (单Job)
- 对应shell
#!/usr/bin/env bash
url1="https://open.feishu.cn/open-apis/bot/v2/hook/"
url2="https://open.feishu.cn/open-apis/bot/v2/hook/" # 1. 消息 接收地址
webhook_list=($url1 $url2)# ========================
# 2. 消息 参数预处理
if [ ! "$GIT_BRANCH" ]; thenecho "----------------- GIT_BRANCH 为空"GIT_BRANCH="''"
fi
echo -e "GIT_BRANCH -> ${GIT_BRANCH}"
# ========================
# 3. 消息 执行发送
run_send_msg() {echo -e "\n 复制发送消息脚本 $HOME -> ${WORKSPACE}" && cp "$HOME"/send_msg_to_feishu.py "${WORKSPACE}"for ((i = 0; i < ${#webhook_list[@]}; i++)); dowebhook=${webhook_list[$i]}echo -e "发送中 --> $webhook"python3 send_msg_to_feishu.py "${webhook}" -job_name "${JOB_NAME}" -job_url "${JOB_URL}" -build_name "${BUILD_ID}" -branch "${GIT_BRANCH}"doneecho -e "发送完成 \n\n"
}run_send_msg
- 对应python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import json
import timeimport requestsparser = argparse.ArgumentParser(description='Jenkins 发送消息到飞书',epilog="执行示例>>> python ${webhook} -job_name ${JOB_NAME} -job_url ${JOB_URL} -branch ${GIT_BRANCH} -build_name ${BUILD_NUMBER} ")
parser.add_argument('webhook', help='机器人webhookURL') # 必填
parser.add_argument('-job_name', '--JOB_NAME', help='作业Name', ) # 选填
parser.add_argument('-job_url', '--JOB_URL', help='作业URL', required=True, ) # 必填
parser.add_argument('-branch', '--GIT_BRANCH', help='git分支', default='') # 选填
parser.add_argument('-build_name', '--BUILD_DISPLAY_NAME', help='编译Name') # 选填
# parser.add_argument('-build_url', '--BUILD_URL', help='编译URL', required=True, ) # 必填webhook = parser.parse_args().webhook
JOB_NAME = parser.parse_args().JOB_NAME
JOB_URL = parser.parse_args().JOB_URL
GIT_BRANCH = parser.parse_args().GIT_BRANCH
BUILD_DISPLAY_NAME = parser.parse_args().BUILD_DISPLAY_NAME
# BUILD_URL = parser.parse_args().BUILD_URLBUILD_URL = JOB_URL + '/lastBuild'def set_msg():# ============ 数据获取 ============result = requests.get(f'{BUILD_URL}/api/json', auth=jenkins_auth).json()# print(BUILD_STATUS.request.url)try:shortDescription = result['actions'][0]['causes'][0]['shortDescription'] # 启动者except KeyError: # 安装 `Multijob plugin` 后位置变更shortDescription = result['actions'][1]['causes'][0]['shortDescription'] # 启动者print(result['timestamp'])timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(result['timestamp'] / 1000)) # 编译开始时间print(timestamp)BUILD_STATUS = result['result'] # 编译状态print('build_status --> ', BUILD_STATUS)duration = result['duration'] # 编译持续时间build_duration = int(duration) // 1000 # 毫秒到秒minutes, seconds = divmod(build_duration, 60)hours, minutes = divmod(minutes, 60)print(f'build duration --> {hours}H:{minutes}M:{seconds}S')# ============ 设置样式 ============if "SUCCESS" in BUILD_STATUS: # 成功template_color = "green"elif "FAILURE" in BUILD_STATUS: # 失败template_color = "red"elif "ABORTED" in BUILD_STATUS: # 终止template_color = "yellow"else:template_color = "grey"# ============ 卡片模板 ============card = json.dumps({"config": {"wide_screen_mode": True},"elements": [{"tag": "markdown","content": f"触发时间:{timestamp}\n"f"分支名称:{GIT_BRANCH}\n"f"构建编号:{BUILD_DISPLAY_NAME}\n"f"构建状态:<font color={template_color}>{BUILD_STATUS}</font>\n"},{"tag": "note","elements": [{"tag": "img","img_key": f"{img_icon}","alt": {"tag": "plain_text","content": f"{JOB_URL}"}},{"tag": "plain_text","content": f"{shortDescription}"}]},{"tag": "hr"},{"tag": "action","actions": [{"tag": "button","text": {"tag": "plain_text","content": "报告链接"},"type": "primary","multi_url": {"url": f"{BUILD_URL}/allure","pc_url": "","android_url": "","ios_url": ""}}],"layout": "bisected"}],"header": {"template": f"{template_color}","title": {"content": f"作业名称: {JOB_NAME}","tag": "plain_text"}}})body = json.dumps({"msg_type": "interactive", "card": card})headers = {"Content-Type": "application/json"}res = requests.post(url=webhook, data=body, headers=headers)print(res.text)if __name__ == '__main__':img_icon = 'img_v2_098e80ae-e583-4148-b822-xxxxxx' # img_key_id jenkinsIconjenkins_auth = ('report', 'report') # jenkins User:Pwdset_msg()
预览 2 (多Job,概览)
Jenkins 需安装
Multijob
插件
Multijob https://plugins.jenkins.io/jenkins-multijob-plugin/
- 对应shell
#!/usr/bin/env bashecho -e "\n\n 消息处理"
# ========================
# 消息发送
# ========================# 1. 消息 接收地址
# -----------------------
group='https://open.feishu.cn/open-apis/bot/v2/hook/'webhook_list=($group)
py_send='SendMsgFeishu.py'# ========================
# 2. 文件处理
# -----------------------
echo -e "\n 复制发送消息脚本 $HOME -> ${WORKSPACE}" && cp "$HOME"/$py_send "${WORKSPACE}"# ========================
# 3. 消息 执行发送
# -----------------------
run_send_msg() {for ((i = 0; i < ${#webhook_list[@]}; i++)); dowebhook=${webhook_list[$i]}echo -e "发送中 --> $webhook"python3 $py_send "${webhook}" -job_url "${JOB_URL}"doneecho -e "发送完成 \n\n"
}run_send_msg
- 对应python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import datetime
import json
import subprocess
import time
from json import JSONDecodeErrorimport requestsparser = argparse.ArgumentParser(description='Jenkins 发送消息到飞书',epilog="执行示例>>> python ${webhook} -job_url ${JOB_URL}")
parser.add_argument('webhook', help='机器人webhookURL') # 必填
parser.add_argument('-job_url', '--JOB_URL', help='作业URL', required=True, ) # 必填webhook = parser.parse_args().webhook
JOB_URL = parser.parse_args().JOB_URL
BUILD_URL = JOB_URL + '/lastBuild'job_name = [] # 运行名称
job_duration = [] # 运行时长
job_status = [] # 运行状态
job_url = [] # 运行结果
pass_rate = [] # 百分比显示print('修改时间:2023-07-04 10:02:43')def get_base_info():device_id = subprocess.getoutput('cat /etc/ding_issue')version_os = subprocess.getoutput('cat /etc/issue')version_browser = subprocess.getoutput('dingdao-dingtao-stable -version')device_sn = subprocess.getoutput('hostname').split('-')[-1]# print(deviceid,os_version,browser_version, sn)return device_id, version_os, version_browser, device_sndef sending_alarms(text=None):local_network_info = subprocess.getoutput("networkctl status")if text is None:text = f"网络异常: 无法访问\n{BUILD_URL}\n{local_network_info}"payload_message = {"msg_type": "text", "content": {"text": text}}headers = {"Content-Type": "application/json"}res = requests.post(url=webhook, data=json.dumps(payload_message), headers=headers)print(f"告警信息发送状态:{res.text}")def set_msg():get_result = requests.get(f'{BUILD_URL}/api/json', auth=jenkins_auth)# ------------------# ------ 数据获取 ------# ------------------JENKINS_URL = BUILD_URL.split('job')[0] # JENKINS_URL# ------ begin 登陆异常 ------try:print(f"查询地址:{get_result.url}")result = get_result.json()# except JSONDecodeError: # json解析失败 未登陆# text = "Error 401 Unauthorized"# sending_alarms(text)# quit(text)# except RecursionError: # BUG: https://github.com/jenkinsci/tikal-multijob-plugin/issues/255# quit('递归错误:从 unicode 字符串解码 JSON 对象时超出最大递归深度')except OSError: # 异常列表: 网络text = "No route to host"sending_alarms()quit(text)except Exception as e: # 通用异常处理text = f"发生异常: {type(e).__name__} --> {str(e)}\n检查:{get_result.url}"sending_alarms(text)quit(text)# res = requests.get(f'{BUILD_URL}/api/json', auth=jenkins_auth)# if res.status_code == 401:# quit('Error 401 Unauthorized')# else:# result = res.json()# # ------ end 登陆异常 ------shortDescription = result['actions'][0]['causes'][0]['shortDescription'] # 启动者timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(result['timestamp'] / 1000)) # 编译开始时间# ------ begin 获取持续时间 ------if result['duration'] != 0: # 获取字段duration = int(result['duration']) // 1000 # 编译持续时间minutes, seconds = divmod(duration, 60)hours, minutes = divmod(minutes, 60)build_duration = f'{hours}h {minutes}m {seconds}s'print(f"--> 通过响应值换算{build_duration}\n")else: # 通过当前时间计算build_duration = datetime.datetime.now() - datetime.datetime.fromtimestamp(result['timestamp'] / 1000)build_duration = str(build_duration).split('.')[0]print(f"--> 通过当前时间计算耗时{build_duration}\n")# ------ end 获取持续时间 ------total_count = len(result['subBuilds']) # 数量总计print(f'======= 项目概览 ======= \n'f'shortDescription:{shortDescription}\nbuild duration:{build_duration}\ntotal_count:{total_count}\ntimestamp:{timestamp}\n')print('提示: 没有allure就报错 无法运行 JSONDecodeError')for index in result['subBuilds']: # 提取数据# print(index)# print(index['result'])# 数据预处理allure_summary = requests.get(f"{JENKINS_URL}{index['url']}/allure/widgets/summary.json").json()['statistic']allure_history_trend = requests.get(f"{JENKINS_URL}{index['url']}/allure/widgets/history-trend.json")# print(allure_history_trend.request.url)try: # 获取历史数据allure_history_trend = allure_history_trend.json()[1]except IndexError:print('没有历史数据')allure_history_trend = allure_history_trend.json()[0]# 计算百分比if allure_summary['total'] != 0: # 除数不能为0allure_pass_rate = allure_summary['passed'] / allure_summary['total']else:allure_pass_rate = 0 # 除数不能为0if allure_history_trend['data']['total'] != 0:allure_history = allure_history_trend['data']['passed'] / allure_history_trend['data']['total']else:allure_history = 0# ------------------# ------ 设置样式 ------# ------------------if "SUCCESS" == index['result']: # 成功color = "green"elif "FAILURE" == index['result']: # 失败color = "red"elif "ABORTED" == index['result']: # 中止color = "yellow"else: # 其他color = "grey"# 通过率对比allure_change = allure_pass_rate - allure_historyprint(f"{index['jobName']} --> 本次比上次通过率 {allure_change}")if allure_pass_rate > allure_history:allure_pass_rate = f'<font color=green>↑{allure_pass_rate:.2%}</font>'elif allure_pass_rate < allure_history or allure_pass_rate == 0:allure_pass_rate = f'<font color=red>↓{allure_pass_rate:.2%}</font>'else:allure_pass_rate = f' {allure_pass_rate:.2%}'# ------------------# ------ 载入数据 ------# ------------------job_name.append({"tag": "markdown", "content": f"{index['jobName']}", "text_align": "center"})job_duration.append({"tag": "markdown", "content": f"{index['duration']}", "text_align": "center"})job_status.append({"tag": "markdown", "content": f"<font color={color}>{index['result']}</font>", "text_align": "center"})job_url.append({"tag": "markdown", "content": f"[查看]({JENKINS_URL}{index['url']}/allure)", "text_align": "center"})pass_rate.append({"tag": "markdown","content": f"{allure_summary['passed']}/{allure_summary['total']}{allure_pass_rate} ","text_align": "center"})print(f'======= 项目详情 ======= \n{job_name}\n{job_duration}\n{job_status}\n{pass_rate}\n{job_url}\n')def set_msg_a(total_count=None, build_duration=None, timestamp=None, shortDescription=None):"""# ------------------# ------ 卡片模板 ------# ------------------total_count: 总数量build_duration: 持续时间timestamp: 开始时间shortDescription: 启动者"""card = json.dumps({"elements": [{"tag": "markdown","content": "**项目总览**\n"},{"tag": "column_set","flex_mode": "bisect","background_style": "grey","horizontal_spacing": "default","columns": [{"tag": "column","width": "weighted","weight": 1,"elements": [{"tag": "markdown","text_align": "center","content": f"项目数量\n**{total_count}**\n"}]},{"tag": "column","width": "weighted","weight": 1,"elements": [{"tag": "markdown","text_align": "center","content": f"运行耗时\n**{build_duration}**"}]},{"tag": "column","width": "weighted","weight": 1,"elements": [{"tag": "markdown","text_align": "center","content": f"执行时间\n**{timestamp}**\n"}]}]},{"tag": "markdown","content": "**项目信息**"},{"tag": "column_set","flex_mode": "none","background_style": "grey","columns": [{"tag": "column","width": "weighted","weight": 2,"vertical_align": "top","elements": [{"tag": "markdown","content": "**项目名**","text_align": "center"}]},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "top","elements": [{"tag": "markdown","content": "**运行时长**","text_align": "center"}]},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "top","elements": [{"tag": "markdown","content": "**运行状态**","text_align": "center"}]},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "top","elements": [{"tag": "markdown","content": "**passed/total/通过率**","text_align": "center"}]},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "top","elements": [{"tag": "markdown","content": "**Report**","text_align": "center"}]}]},{"tag": "column_set","flex_mode": "none","background_style": "default","columns": [{"tag": "column","width": "weighted","weight": 2,"vertical_align": "top","elements": job_name},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "center","elements": job_duration},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "top","elements": job_status},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "top","elements": pass_rate},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "top","elements": job_url}]},{"tag": "hr"},{"tag": "note","elements": [{"tag": "img","img_key": f"{img_icon}","alt": {"tag": "plain_text","content": ""}},{"tag": "plain_text","content": f"{shortDescription}\n颜色代表对比上次执行,绿色上升,红色下降"}]}]})card_id = json.dumps({"type": "template","data": {"template_id": "ctp_AA6DZMfkJekh", # 卡片id,参数必填。可在搭建工具中通过“复制卡片ID”获取"template_variable": # 卡片中绑定的变量的取值。如没有绑定变量,可不填此字段。{"total_count": "29","group_table": [{"jobName": "test001","duration": "小于1小时","build_url": "baidu.com","build_status": "SUCCESS","tmp_color": "green"},{"jobName": "test002","duration": "2小时","build_url": "baidu.com","build_status": "FAILURE","tmp_color": "red"},{"jobName": "test003","duration": "3小时","build_url": "baidu.com","build_status": "ABORTED","tmp_color": "yellow"},{"jobName": "test004","duration": "3小时","build_url": "baidu.com","build_status": "UNSTABLE","tmp_color": "grey"}],"duration": "15080","shortDescription": "Started by user admin","timestamp": "1686645721264","jobName": "","tmp_color": ""}}})body = json.dumps({"msg_type": "interactive", "card": card}) # 使用 当前模板# body = json.dumps({"msg_type": "interactive", "card": card_id}) # 使用 预置模板headers = {"Content-Type": "application/json"}res = requests.post(url=webhook, data=body, headers=headers)print(f'消息发送响应 -->\n\t {res.text}')if __name__ == '__main__':img_icon = 'img_v2_098e80ae-e583-4148-b822-f42a05298d3g' # img_key_id jenkinsIconjenkins_auth = ('result', 'result') # jenkins User:Pwd# get_base_info()set_msg()deviceid, os_version, browser_version, sn = get_base_info()print(deviceid, os_version, browser_version, sn)
相关文章:
【无标题】jenkins消息模板(飞书)
这里写目录标题 Jenkins 安装的插件 发送消息到飞书预览 1 (单Job)预览 2 (多Job,概览) Jenkins 安装的插件 插件名称作用Rebuilder Rebuilder。 官方地址:https://plugins.jenkins.io/rebuild 安装方式&a…...
2023年国赛 高教社杯数学建模思路 - 案例:随机森林
文章目录 1 什么是随机森林?2 随机深林构造流程3 随机森林的优缺点3.1 优点3.2 缺点 4 随机深林算法实现 建模资料 ## 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 什么是随机森林ÿ…...
element Collapse 折叠面板 绑定事件
1. 点击面板触发事件 change <el-collapse accordion v-model"activeNames" change"handleChange"><el-collapse-item title"一致性 Consistency"><div>与现实生活一致:与现实生活的流程、逻辑保持一致,…...
CSS :mix-blend-mode、aspect-ratio
mix-blend-mode 元素的内容应该与元素的直系父元素的内容和元素的背景如何混合。 mix-blend-mode: normal; // 正常mix-blend-mode: multiply; // 正片叠底mix-blend-mode: screen; // 滤色mix-blend-mode: overlay; // 叠加mix-blend-mode: darken; // 变暗mix-blend-mode: …...
Module not found: Error: Can‘t resolve ‘less-loader‘解决办法
前言: 主要是在自我提升方面,感觉自己做后端还是需要继续努力,争取炮筒前后端,作为一个全栈软阿金开发人员,所以还是需要努力下,找个方面,目前是计划学会Vue,这样后端有java和pytho…...
量化QAT QLoRA GPTQ
模型量化的思路可以分为PTQ(Post-Training Quantization,训练后量化)和QAT(Quantization Aware Training,在量化过程中进行梯度反传更新权重,例如QLoRA),GPTQ是一种PTQ的思路。 QAT…...
CentOS下查看 ssd 寿命
SSD写入量达到设计极限,颗粒擦写寿命耗尽后会导致磁盘写入速度非常缓慢,读取正常。 使用smartctl及raid卡管理软件查看硬盘smart信息可以发现Media_Wearout_Indicator值降为1,表明寿命完全耗尽。 涉及范围 所有SSD处理方案 查看SSD smart信…...
Node基础--npm相关内容
下面,我们一起来看看Node中的至关重要的一个知识点-----npm 1.npm概述 npm(Node Package Manager),CommonJS包规范是理论,npm是其中一种实践。 对于Node而言,NPM帮助其完成了第三方模块的发布、安装和依赖等。借助npm,Node与第三方模块之间形成了很好的一个 生态系统。(类…...
Python图片爬虫工具
不废话了,直接上代码: import re import os import requests import tqdmheader{User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36}def getImg(url,idx,path):imgre…...
制造执行系统(MES)在汽车行业中的应用
汽车行业在不断发展中仍然面临一些挑战和痛点。以下是一些当前汽车行业可能面临的问题: 1.电动化和可持续性转型:汽车行业正逐渐向电动化和可持续性转型,但这需要投入大量资金和资源,包括电池技术、充电基础设施等,同时…...
Spring与Mybatis集成且Aop整合
目录 一、集成 1.1 集成的概述 1.2 集成的优点 1.3 代码示例 二、整合 2.1 整合概述 2.2 整合进行分页 一、集成 1.1 集成的概述 集成是指将不同的组件、部分或系统组合在一起,以形成一个整体功能完整的解决方案。它是通过连接、交互和协调组件之间的关系来实…...
【nonebot-plugin-mystool】快速安装使用nonebot-plugin-mystool
快速安装使用nonebot-plugin-mystool,以qq为主 前期准备:注册一个QQ号,python3.9以上的版本安装,go-cqhttp下载 用管理员模式打开powershell,并输入以下命令 #先排查是否有安装过的nonebot,若有则删除 pip uninstal…...
js实现数据关联查找更新。数据求和验证
为了实现这个功能我们和后端定义了数据结构 data:{id:‘’,formInfo:,formInfo2:,formInfo3:,formInfo4:, ......deailData:[ // 明细数据 // saleData 查询带出的对应明细序列号数据{ id:, ocopyId:, copyId:, odoId:, ......, saleData:[ { id:, oc…...
区块链上地址与银行账户有什么区别?
在区块链世界中,除了交易还有另一个基础要素:地址。在日前推出的Onchain AML合规技术方案,也有一个与区块链地址密切相关的概念:KYA(Know Your Address,了解你的地址)。 那问题来了,区块链地址究竟有什么用…...
CF 148 D Bag of mice(概率dp求概率)
CF 148 D. Bag of mice(概率dp求概率) Problem - 148D - Codeforces 大意:袋子里有 w 只白鼠和 b 只黑鼠 ,A和B轮流从袋子里抓,谁先抓到白色谁就赢。A每次随机抓一只,B每次随机抓完一只之后会有另一只随机老鼠跑出来。如果两个人…...
引入本地 jar 包教程
将本地 jar 包,放到 resource 目录下,在 pom.xml 文件中加入如下依赖: <dependency><groupId>com.hk</groupId><artifactId>examples</artifactId><version>1.0</version><scope>system<…...
优维产品最佳实践第5期:什么是持续集成?
谈到到DevOps,持续交付流水线是绕不开的一个话题,相对于其他实践,通过流水线来实现快速高质量的交付价值是相对能快速见效的,特别对于开发测试人员,能够获得实实在在的收益。 本期EasyOps产品使用最佳实践,…...
空时自适应处理用于机载雷达——元素空间空时自适应处理(Matla代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
聚观早报 | 青瓷游戏上半年营收3.34亿元;如祺出行冲击IPO
【聚观365】8月26日消息 青瓷游戏上半年营收3.34亿元 如祺出行冲击IPO 索尼互动娱乐将收购Audeze 昆仑万维上半年净利润3.6亿元 T-Mobile计划在未来五周内裁员5000人 青瓷游戏上半年营收3.34亿元 青瓷游戏发布截至2023年6月30日止的中期业绩,财报显示…...
硅谷的魔法:如何塑造了全球技术的未来
硅谷的创新文化简介 硅谷,位于美国加利福尼亚州的圣克拉拉谷,已经从一个半导体产业的中心发展成为全球技术创新的代名词。这里集结了全球最顶尖的技术公司、创业者和投资者,共同创造了一个技术创新的奇迹。 起源与发展 硅谷的起源与斯坦福大…...
(三)行为模式:4、迭代器模式(Iterator Pattern)(C++示例)
目录 1、迭代器模式(Iterator Pattern)含义 2、迭代器模式的UML图学习 3、迭代器模式的应用场景 4、迭代器模式的优缺点 (1)优点 (2)缺点 5、C实现迭代器模式的实例 1、迭代器模式(Itera…...
React Antd form.getFieldsValue() 和 form.getFieldsValue(true) 有区别吗?
背景 突然发现 antd 的 getFieldsValue()是可以传一个 true 参数的,如题,React Antd form.getFieldsValue() 和 form.getFieldsValue(true) 有区别吗? 验证 确实不一样 结论 getFieldsValue 提供了多种重载方法: getFieldsValue(name…...
浅谈Java中的观察者模式
观察者模式是软件开发中常用的一种设计模式,它通过定义一对多的依赖关系,使得一个对象(主题)的状态变化可以通知多个其他对象(观察者)。 这种模式的优点是解耦和增加扩展性,用于实现对象之间的…...
C++:命名空间,缺省参数,函数重载,引用,内联函数
个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》《C》 文章目录 前言一、命名空间命名空间的定义命名空间的使用 二、缺省参数缺省参数概念缺省参数分类 三、函数重载函数重载的概念 四、引用引用的概念引用特性引用的使用场景引用与指针的区别 …...
2.Vue报错Cannot read properties of undefined (reading ‘then‘)
1.出现报错 Cannot read properties of undefined (reading ‘then’), 代码为 uploadFile(e.target.files[0]).then((res) > {alert(JSON.stringify(res));});2.原因 是因为uploadFile方法没有返回值,于是我又检查了一遍代码,发现我的r…...
【LeetCode 】数组简介
集合列表和数组 本文中介绍的概念为适用于所有编程语言的抽象理论,具体实现会由编程语言的不同而稍有差别。 具体介绍数组之前,我们先来了解一下集合、列表和数组的概念之间的差别。 集合 集合一般被定义为:由一个或多个确定的元素所构成的…...
一文解析block io生命历程
作为存储业务的一个重要组成部分,block IO是非易失存储的唯一路径,它的生命历程每个阶段都直接关乎我们手机的性能、功耗、甚至寿命。本文试图通过block IO的产生、调度、下发、返回的4个阶段,阐述一个block IO的生命历程。 一、什么是块设备…...
Python爬虫学习之旅:从入门到精通,要学多久?
导语: 随着信息时代的发展,大量的数据和信息储存在互联网上,这为我们提供了获取和利用这些数据的机会。而Python爬虫作为一种强大的工具,可以帮助我们从网页中提取数据,并进行进一步的分析和挖掘。然而,对…...
HarmonyOS/OpenHarmony(Stage模型)卡片开发应用上下文Context使用场景一
1.获取应用文件路径 基类Context提供了获取应用文件路径的能力,ApplicationContext、AbilityStageContext、UIAbilityContext和ExtensionContext均继承该能力。应用文件路径属于应用沙箱路径。上述各类Context获取的应用文件路径有所不同。 通过ApplicationContext…...
MAE 论文精读 | 在CV领域自监督的Bert思想
1. 背景 之前我们了解了VIT和transformer MAE 是基于VIT的,不过像BERT探索了自监督学习在NLP领域的transformer架构的应用,MAE探索了自监督学习在CV的transformer的应用 论文标题中的Auto就是说标号来自于图片本身,暗示了这种无监督的学习 …...
C++中内存的分配
一个由C/C编译的程序占用的内存分为以下几个部分 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。 2、堆区(heap) — 一般由程序员分配释放, 若程序…...
Qt中的垂直布局QVBoxLayout和水平布局QHBoxLayout
文章目录 QVBoxLayoutQHBoxLayout QVBoxLayout Qt中的垂直布局(Vertical Layout)是用来将控件按垂直方向进行排列的布局管理器。下面是一些常用的Qt Vertical Layout的函数及其用法示例: QVBoxLayout类的构造函数: QVBoxLayout…...
【C#学习笔记】委托和事件
文章目录 委托委托的定义委托实例化委托的调用多播委托 为什么使用委托?官方委托泛型方法和泛型委托 事件为什么要有事件?事件和委托的区别: 题外话——委托与观察者模式 委托 在 .NET 中委托提供后期绑定机制。 后期绑定意味着调用方在你所…...
堆排序简介
概念: 堆排序是一种基于二叉堆数据结构的排序算法。它的概念是通过将待排序的元素构建成一个二叉堆,然后通过不断地取出堆顶元素并重新调整堆的结构来实现排序。 算法步骤: 构建最大堆(或最小堆):将待排…...
React Diff算法
文章目录 React Diff算法一、它的作用是什么?二、React的Diff算法1.了解一下什么是调和?2.react的diff算法3.React Diff的三大策略4.tree diff:1、如果DOM节点出现了跨层级操作,Diff会怎么办? 5. component diff:6. e…...
07 mysql5.6.x docker 启动, 无 config 目录导致客户端连接认证需要 10s
前言 呵呵 最近再一次 环境部署的过程中碰到了这样的一个问题 我基于 docker 启动了一个 mysql 服务, 然后 挂载出了 数据目录 和 配置目录, 没有手动复制配置目录出来, 所以配置目录是空的 然后 我基于 docker 启动了一个 nacos, 配置数据库设置为上面的这个 mysql 然后 启…...
GO GC
GO GC 垃圾回收(Garbage Collection,简称GC)是编程语言中提供的自动的内存管理机制,自动释放不需要的对象,让出存储器资源,无需程序员手动执行。 Golang中的垃圾回收主要应用三色标记法,GC过程和其他用户goroutine可…...
ECharts配合Node.js爬虫实现数据可视化
数据可视化简介 可视化技术是将数据和信息以图形化的方式展示出来,以便更好地理解和分析。可视化技术通常使用各种图表、图形、动画和交互式效果来呈现数据。可视化技术有以下几个基本概念: 数据:可视化技术的基础是数据。数据可以是数字、文…...
[Linux] C获取键盘,鼠标数据
键盘检测指令:cat /dev/input/event1 | hexdump 鼠标检测指令:cat /dev/input/event2 | hexdump 当键盘/鼠标有输入时,会有对应的一堆16进制输出。它其实对应着input_event结构体【24字节】。 struct input_event {struct timeval time;_…...
户外跑步用什么耳机、户外运动耳机推荐
跑步是一项简单的运动,只需要交替迈左右腿就可以进行。然而,跑步有时可能变得单调乏味。即使是意志坚定、热爱跑步的人,在这个漫长的过程中也会感到乏味,更不用说像你我这样的普通跑者了。音乐能够让跑步变得更加有趣,…...
ubuntu设置系统代理
安装trojan等代理工具并配置启动,得到端口号 例如 10.10.1.10:8080系统代理设置 我们将在/etc/profile.d/proxy.sh下添加一个shell脚本文件,这将确保设置适用于所有已登录的用户: sudo vim /etc/profile.d/proxy.sh将以下内容写到文档中&…...
java定时任务如何取消
java定时任务如何取消,并比如,我之前想每周二晚上6点自动生成一条devops流水线,现在我想停掉 答案: 在Java中,可以使用ScheduledExecutorService类来创建定时任务。要取消定时任务,可以调用ScheduledFutur…...
gitlab 9.05 版本获取合并请求的API接口报错404是为什么
gitlab 9.05 版本获取合并请求的API接口报错404是为什么 答案: 出现404错误表示请求的资源未找到。在这种情况下,可能有以下几个原因导致API接口报错404: 版本不匹配:请确保你使用的是GitLab 9.05版本的API接口,如果使…...
微服务(多级缓存)
目录 多级缓存 1.什么是多级缓存 2.JVM进程缓存 2.2.初识Caffeine 2.3.实现JVM进程缓存 2.3.1.需求 2.3.2.实现 3.Lua语法入门 3.1.初识Lua 3.1.HelloWorld 3.2.变量和循环 3.2.1.Lua的数据类型 3.2.2.声明变量 3.2.3.循环 3.3.条件控制、函数 3.3.1.函数 3.3.…...
阿里云配置MySQL-server 8.0远程登录
Ubuntu 22.04 LTS 安装MySQL-Server 8.0 # apt search mysql-server # apt install mysql-server重建服务 # service mysql stop # vi /etc/mysql/mysql.conf.d/mysqld.cnf ... bind-address 0.0.0.0 ... # service mysql start # lsof -i:3306 COMMAND PID USER FD …...
清洁能源使用的社会发展意义
应用清洁能源是转变经济增加途径的有效手段,能够在减少污染物、降低企业经营成本的同时,提高企业经济效益和社会经济效益。 应用清洁能源是保护环境的最佳方式和必然选择,改变末端治理的现状,采取以预防为主的环境保护与发展理…...
针对论坛系统进行功能测试和性能测试
项目链接:飞鸽论坛 目录 一. 项目背景 二. 项目功能 三. 功能测试 注册: 登录: 更改用户信息: 发布帖子: 更新帖子信息: 点赞: 评论: 发送私信: 测试报告 四. 性能测试 Virtual User Generator Controller Analysis 测试报告: 一. 项目背景 该论坛系统采用前…...
Android App的设计规范
Android App 设计规范是为开发者和设计师提供的一系列准则和建议,以确保应用在 Android 设备上的外观、交互和用户体验保持一致。以下是一些常见的 Android App 设计规范要点,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开…...
paddleclas ImportError: cannot import name ‘Identity‘ from ‘paddle.nn‘
使用paddlepaddle的 paddleclas 官方demos时 ,报错如图 ImportError: cannot import name ‘Identity’ from ‘paddle.nn’ 解决方案很简单: 找到调用 Identity 的位置: 注释掉就解决啦 !!! 搞定!!!…...
Debezium系列之:深入理解Debezium Server Operator和实际应用Debezium Server Operator案例详解
Debezium系列之:深入理解Debezium Server Operator和实际应用Debezium Server Operator案例详解 一、认识Debezium Server Operator二、深入理解Debezium Server和Debezium Server实际应用案例详解三、Debezium Server Operator安装步骤四、Debezium Operator使用案例五、post…...