【无标题】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日止的中期业绩,财报显示…...

硅谷的魔法:如何塑造了全球技术的未来
硅谷的创新文化简介 硅谷,位于美国加利福尼亚州的圣克拉拉谷,已经从一个半导体产业的中心发展成为全球技术创新的代名词。这里集结了全球最顶尖的技术公司、创业者和投资者,共同创造了一个技术创新的奇迹。 起源与发展 硅谷的起源与斯坦福大…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...
鸿蒙HarmonyOS 5军旗小游戏实现指南
1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发,采用DevEco Studio实现,包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...
WEB3全栈开发——面试专业技能点P4数据库
一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库,基于 mysql 库改进而来,具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点: 支持 Promise / async-await…...