Github开通第三方平台OAuth登录及Java对接步骤
调研起因:
准备搞AI Agent海外项目,有相当一部分用户群体是程序员,所以当然要接入Github这个全球最大的同性交友网站了,让用户使用Github账号一键完成注册或登录。
本教程基于Web H5界面进行对接,同时也提供了spring-boot版本的对接Demo在:
https://github.com/youbl/study/tree/master/study-codes/github-oauth-login-demo
废话不多说,直接开始步骤说明吧:
注意:要注册和对接,国内访问github不那么稳定,自己想办法保证稳定性吧。
1、Github OAuth功能申请
1.1、账号注册
首先肯定是要有一个有效的Github账号,去这里注册去吧:https://github.com/signup
这个过程比较简单,输入一个邮箱和密码,接收验证码邮件确认即可,过程中会进行机器人验证。
如果已经有账号了,可以忽略。
1.2、创建Github App
按Github要求,要在App内配置和使用OAuth身份验证能力,所以要先创建Github App。
注:Github支持2种App:
两种Apps的区别参考官方说明:https://docs.github.com/zh/apps/oauth-apps/building-oauth-apps/differences-between-github-apps-and-oauth-apps
我自己实际配置对比了一下:
- Github Apps:推荐,支持配置最多10个回调地址,支持细粒度的权限配置;
- OAuth Apps:Github也不推荐,只支持配置1个回调地址(不方便测试),不支持权限配置。
Github Apps创建说明参考:https://docs.github.com/zh/apps/creating-github-apps/registering-a-github-app/registering-a-github-app
- 先登录并进入Github首页:https://github.com/
点击右上角的头像,再点弹出菜单下面的“Settings”:
- 再点左边菜单列表最下面的“Developer settings”:
- 点击右侧的“New GitHub App”
- 在新建窗口,输入必要信息,必填项:
- GitHub App name:应用名,自己写,必须在GitHub唯一才行;
- Homepage URL:你的网站地址,没有可以使用Github项目地址,不过Github没有校验是否存在;
- Callback URL:Github登录成功的回调地址,最多可以配置10个,建议把开发、测试、预上、生产都配置进去;
- Webhook:取消勾选Active,不接收Github的活动事件;
- 最后点击最下方的“Create GitHub App”即可。
- 此时会进入创建成功的App页面,点击页面右边的“Generate a new client secret”, 生成一个OAuth使用的密钥,请务必把这个Client ID和Client secret复制并保存下来,后面程序要用:
- OK,到这里,GitHub App已经创建完成了,下面是代码对接过程。
注:一开始还以为要配置权限,添加“Email addresses”的只读权限,后面发现并不需要。
2、代码对接
上面的步骤操作完成后,有了客户端ID和Secret,把它复制下来,开始用于我们的代码对接。
2.1、技术方案和时序图
考虑前端灵活性,以及code无法单独生成access_token,不存在安全问题,下面演示的方案使用前端接收GitHub回调,再通过后端生成access_token及获取用户信息,时序图如下:
2.2、前端页面对接代码生成
可以参考官方的对接文档说明:https://docs.github.com/zh/apps/creating-github-apps/writing-code-for-a-github-app/building-a-login-with-github-button-with-a-github-app#add-code-to-generate-a-user-access-token
2.2.1、登录页面的按钮逻辑
这一步就是生成一个按钮,点击跳转去GitHub登录授权页,参考代码:
<input type="button" onclick="doLogin" value="Github登录">
<script type="text/javascript">const githubUrl = 'https://github.com/login/oauth/authorize?scope=user:email&client_id=';const githubClientId = '上面App里的 Client ID';const redirectUri = 'http://127.0.0.1:8999/demo/githubCallback.html';function doLogin() {location.href = githubUrl + encodeURIComponent(githubClientId)+ '&redirect_uri=' + encodeURIComponent(redirectUri);}
</script>
注:上面代码里的回调地址 http://127.0.0.1:8999/demo/githubCallback.html
要记得在GitHub Apps那边的Callback URL里配置,否则点登录时会报错:
2.2.2、上面提到的回调地址逻辑
http://127.0.0.1:8999/demo/githubCallback.html
这个回调页面,要从url里提取出授权码code,并转发给服务端,
回调页面代码参考:
<script>start();function start() {let code = getFromSearch('code');if (!code) {return alert('未找到code授权码:' + url);}// 后端获取github用户信息getUserInfoByServer(code);}/*** 从url的参数里获取变量值* @param name 变量名* @returns {string} 变量值*/function getFromSearch(name) {if (!name || !location.search || location.search.length <= 1) {return ''; // 没有search}let array = location.search.substring(1).split('&'); // 去除第一个 ?for (let i = 0, j = array.length; i < j; i++) {let item = array[i];let idx = item.indexOf('=');if (idx <= 0) continue;if (name === item.substring(0, idx))return item.substring(idx + 1);}return '';}function getUserInfoByServer(code) {let userInfoUrl = '../callback?code=' + encodeURIComponent(code);var xhr = new XMLHttpRequest();xhr.open('GET', userInfoUrl);xhr.onreadystatechange = function (e) {if (xhr.response) {const data = JSON.parse(xhr.response);document.getElementById('txtUserInfoServer').value = '后端返回得到的github用户信息:\r\n' +JSON.stringify(data, null, 4);}};xhr.send(null);}
</script>
2.3、后端根据code获取用户信息的逻辑
2.3.1、根据code生成access_token
要使用code + Client ID + Client secret,才能生成access_token,
对应的API文档:https://docs.github.com/zh/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-user-access-token-for-a-github-app#using-the-web-application-flow-to-generate-a-user-access-token
参考代码:
@FeignClient(name = "github-token", url = "https://github.com")
public interface GithubTokenFeign {/*** 根据登录成功回调的code,交换access_token* @param dto code信息* @return token信息*/@PostMapping(value = "login/oauth/access_token", headers = {"Accept=application/json", "Content-Type=application/json"})GithubTokenOutputDto getAccessToken(GithubTokenInputDto dto);/*
// 异常场景:
// 不加 Accept=application/json ,返回值如下:
// error=bad_verification_code&error_description=The+code+passed+is+incorrect+or+expired.&error_uri=https%3A%2F%2Fdocs.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-oauth-app-access-token-request-errors%2F%23bad-verification-code
// 加了返回值如下:
// {"error":"bad_verification_code","error_description":"The code passed is incorrect or expired.","error_uri":"https://docs.github.com/apps/managing-oauth-apps/troubleshooting-oauth-app-access-token-request-errors/#bad-verification-code"}
// 正常场景,返回的json如下:
// {access_token=aaa, expires_in=28800, refresh_token=bbb, refresh_token_expires_in=15811200, token_type=bearer, scope=}* */
}
2.3.2、根据access_token获取用户信息
对应的API文档:https://docs.github.com/zh/rest/users/users?apiVersion=2022-11-28#get-the-authenticated-user
参考代码:
@FeignClient(name = "github-api", url = "https://api.github.com")
public interface GithubApiFeign {/*** 获取用户信息* @param authorization access_token* @return 用户信息*/@GetMapping(value = "user", headers = {"Accept=application/json", "Content-Type=application/json"})GithubUserDto getUserInfo(@RequestHeader String authorization);/*成功响应参考:
cost time(ms): 916 status:200 from GET https://api.github.com/user
Headers:access-control-allow-origin: *access-control-expose-headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunsetcache-control: private, max-age=60, s-maxage=60content-length: 1250content-security-policy: default-src 'none'content-type: application/json; charset=utf-8date: Tue, 29 Apr 2025 10:00:16 GMTetag: "abc"github-authentication-token-expiration: 2025-04-29 18:00:09 UTClast-modified: Mon, 28 Apr 2025 09:48:55 GMTreferrer-policy: origin-when-cross-origin, strict-origin-when-cross-originserver: github.comstrict-transport-security: max-age=31536000; includeSubdomains; preloadvary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-Withx-accepted-github-permissions: allows_permissionless_access=truex-accepted-oauth-scopes:x-content-type-options: nosniffx-frame-options: denyx-github-api-version-selected: 2022-11-28x-github-media-type: github.v3x-github-request-id: abcx-oauth-client-id: abcx-oauth-scopes:x-ratelimit-limit: 5000x-ratelimit-remaining: 4999x-ratelimit-reset: 1745924416x-ratelimit-resource: corex-ratelimit-used: 1x-xss-protection: 0Body:
{"login":"youbl","id":1,"node_id":"abc","avatar_url":"https://avatars.githubusercontent.com/u/2508702?v=4","gravatar_id":"","url":"https://api.github.com/users/youbl","html_url":"https://github.com/youbl","followers_url":"https://api.github.com/users/youbl/followers","following_url":"https://api.github.com/users/youbl/following{/other_user}","gists_url":"https://api.github.com/users/youbl/gists{/gist_id}","starred_url":"https://api.github.com/users/youbl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/youbl/subscriptions","organizations_url":"https://api.github.com/users/youbl/orgs","repos_url":"https://api.github.com/users/youbl/repos","events_url":"https://api.github.com/users/youbl/events{/privacy}","received_events_url":"https://api.github.com/users/youbl/received_events","type":"User","user_view_type":"public","site_admin":false,"name":"水边","company":"@baidu","blog":"http://beinet.cn","location":"Fuzhou","email":"youbl@126.com","hireable":true,"bio":"https://youbl.blog.csdn.net/","twitter_username":null,"notification_email":"youbl@126.com","public_repos":17,"public_gists":0,"followers":12,"following":0,"created_at":"2012-10-08T03:37:21Z","updated_at":"2025-04-28T09:48:55Z"}*/
}
2.3.3、封装API给前端调用
参考代码:
@RestController
@RequiredArgsConstructor
public class GithubCallbackController {private final String githubClientId = "Iv23liwz6AxRv7VXcHvf";private final String githubClientSecret = "github app里的Client secret";private final GithubTokenFeign githubTokenFeign;private final GithubApiFeign githubApiFeign;// 会带code回调,如 http://localhost:8080/callback?code=abc@GetMapping("callback")public GithubUserDto callback(@RequestParam String code) {GithubTokenInputDto dto = new GithubTokenInputDto().setClient_id(githubClientId).setClient_secret(githubClientSecret).setCode(code);// 根据授权码,获取access_tokenGithubTokenOutputDto ret = githubTokenFeign.getAccessToken(dto);if (!ret.success()) {throw new RuntimeException("failed: " + ret.getError_description() + " " + ret.getError_uri());}String auth = ret.getToken_type() + " " + ret.getAccess_token();// 根据access_token, 获取用户信息return githubApiFeign.getUserInfo(auth);}
}
2.4、运行和测试
把项目跑起来,在浏览器里访问:http://127.0.0.1:8999/login.html
-
打开的登录测试页如下:
-
点击上面的登录按钮,会进入GitHub的授权页面:
注:每个用户只会显示一次,授权通过后,第二次再登录,就没有这个界面了,会直接进入回调页;
除非该用户去GitHub的设置页面,删除授权,删除授权的地址:https://github.com/settings/apps/authorizations
-
点击上面授权页的“Authorize xxx”后,就会调用后端去获取GitHub的用户信息了,测试页面的结果如下:
3、常见问题
3.1、不支持iframe嵌入
测试中发现,想在登录页面弹出一个浮层,使用iframe嵌入GitHub的授权页面是不支持的,必须是跳转过去完成授权,再通过Callback URL接收回调的方式。
因此,我项目里的其它登录,比如Google OAuth登录也要修改风格,从弹小窗变成跳转方式了。
相关文章:
Github开通第三方平台OAuth登录及Java对接步骤
调研起因: 准备搞AI Agent海外项目,有相当一部分用户群体是程序员,所以当然要接入Github这个全球最大的同性交友网站了,让用户使用Github账号一键完成注册或登录。 本教程基于Web H5界面进行对接,同时也提供了spring-…...
DeepSeek V1:初代模型的架构与性能
DeepSeek V1(又称DeepSeek-MoE)是DeepSeek系列的首代大规模语言模型,它采用Transformer结合稀疏混合专家(MoE)的创新架构,实现了在受控算力下的大容量模型。本文将深入解析DeepSeek V1的架构设计与技术细节,包括其关键机制、训练优化策略,以及在各类NLP任务上的表现。 …...
Java ResourceBundle 资源绑定详解
Java ResourceBundle 资源绑定详解 ResourceBundle 是 Java 提供的国际化(i18n)资源管理工具,位于 java.util 包。它专门用于加载本地化的 .properties 资源文件,支持多语言切换,是国际化和本地化开发的核心类。 1. 核心特性 (1)基本特点 基于 .properties 文件管理键…...
flutter 专题 六十一 支持上拉加载更多的自定义横向滑动表格
在股票软件中,经常会看到如下所示的效果(ps:由于公司数据敏感,所以使用另一个朋友的一个图)。 分析需要后,我先在网上找了下支持横向滑动的组件,最后找到了这个:flutter_horizontal…...
暗夜模式续
之前写过一篇笨拙的方式实现暗夜模式,但是当真正去适配的时候发现简直恶心至极;然后想通过一些方式可以把笨拙的方式变得优雅; 之前实现暗夜模式的快速通道,这篇文章在基于这个基础上优化而来 目录 背景 优化步骤 OK…...
[吾爱出品] 文件夹迁移工具(DirMapper)
文件夹迁移工具(DirMapper) 链接:https://pan.xunlei.com/s/VOP4Uf6vu3dalYLaZ1iZUhJ1A1?pwdfhzi# 文件夹迁移工具(DirMapper) 智能识别源文件夹分类 复制/移动两种迁移模式 冲突解决方案(覆盖/跳过/合…...
DeepSeek 4月30日发布新模型:DeepSeek-Prover-V2-671B 可进一步降低数学AI应用门槛,推动教育、科研领域的智能化升级
DeepSeek-Prover-V2-671B模型特点: 一、超大参数规模与数学推理能力 参数规模跃升 模型参数量高达6710亿,是前代数学推理模型Prover-V1.5(70亿参数)的近100倍,表明其具备更强的复杂问题处理能力。 前代Prover-V1.5在高…...
GitHub修炼法则:第一次提交代码教学(Liunx系统)
前言 github是广大程序员们必须要掌握的一个技能,万事开头难,如果成功提交了第一次代码,那么后来就会简单很多。网上的相关资料往往都不是从第一次开始,导致很多新手们会在过程中遇到很多权限认证相关的问题,进而被卡…...
百家号等新媒体私信入口是否可以聚合到企业微信的客服,如何实现
一、技术实现路径 1. 百家号 API 对接 接口权限申请: 登录百度开发者平台,创建应用并获取 API 密钥(app_id和app_token)。申请私信相关接口权限(如消息通知、粉丝查询),需满足百家号的审核要求…...
【来自AI】RS485,Rs232,Modbus的区别和联系是什么
RS485、RS232 和 Modbus 是常用于工业自动化和通信中的技术标准,它们有不同的特点和应用。下面是它们的区别和联系: RS232 (Recommended Standard 232) 定义:RS232 是一种串行通信标准,通常用于短距离(一般最多15米&…...
java实现序列化与反序列化
va 实现序列化与反序列化 序列化(Serialization) 是将 Java 对象转换为字节流(二进制数据),以便存储或网络传输。 反序列化(Deserialization) 则是将字节流恢复为 Java 对象。 Java 提供了 ja…...
harmonyOS 手机,双折叠,平板,PC端屏幕适配
由于HarmonyOS设备的屏幕尺寸和分辨率各不相同,开发者需要采取适当的措施来适配不同的屏幕。 1.EntryAbility.ets文件里:onWindowStageCreate方法里判断设备类型, 如果是pad,需全屏展示(按客户需求来,本次…...
Qt Creator环境编译的Release软件放在其他电脑上使用方法
本文解决的问题:将Qt Creator环境编译的exe可执行程序放到其他电脑上不可用情况 1、寻找windeployqt工具所在路径" D:\Qt5.12.10\5.12.10\msvc2015_64\bin" ,将此路径配置到环境变量; 2、用Qt Creator环境编译出Release版本可执行…...
electron+vite+vue3 快速入门教程
Electron、Vite 和 Vue 3 结合使用可以创建强大的跨平台桌面应用程序,下面是一个快速入门教程,帮助你搭建一个基于 Electron Vite Vue 3 的项目。 环境准备 Node.js: 首先确保你的机器上已经安装了 Node.js。你可以通过以下命令来检查是否已安装&…...
添加了addResourceHandlers 但没用
B站黑马的视频 public class WebMvcConfig extends WebMvcConfigurationSupport { /** * 设置静态资源映射 * param registry */ Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { log.info("开始进…...
uniapp如何获取安卓原生的Intent对象
通过第三方app唤起,并且获取第三方app唤起时携带的参数 因为应用a唤起应用b时,应用b第一时间就要拿到参数token,所以需要将获取参数的方法写在APP.vue中的onLaunch钩子里,如果其他地方要用可以选择vuex或者采用本地缓存。 uniapp中plus.run…...
国标GB28181视频平台EasyGBS在物业视频安防管理服务中的应用方案
一、方案背景 在现代物业服务中,高效的安全管理与便捷的服务运营至关重要。随着科技的不断发展,物业行业对智能化、集成化管理系统的需求日益增长。EasyGBS作为一款基于国标GB28181协议的视频监控平台,具备强大的视频管理与集成能力&#…...
Linux容器大师:K8s集群部署入门指南
引言 在云原生时代,Kubernetes就像一位"集群调度大师"🎮,轻松管理成千上万的容器化应用!本文将带你从零开始搭建生产级K8s集群,从基础概念到实战部署,从核心组件到安全运维。无论你是要搭建开发…...
Vue 3 中纯 template 标签
发现 Vue 3 中纯 template 标签不会被渲染。 可以加 v-if"1" 即可 https://andi.cn/page/622155.html...
极光PDF编辑器:高效编辑,轻松管理PDF文档
在日常工作和学习中,PDF文件的使用越来越普遍。无论是学术论文、工作报告还是电子书籍,PDF格式因其稳定性和兼容性而被广泛采用。然而,编辑PDF文件往往比编辑Word文档更加复杂。今天,我们要介绍的 极光PDF编辑器,就是这…...
《可信数据空间 技术架构》技术文件正式发布
可信数据空间 技术架构发布了 国家数据基础设施技术文件发布有几个月了,成为数据要素圈内必读的白皮书,接着今日国家数据局正式发布了《可信数据空间 技术架构》,笔者有幸见证了该文件出炉的过程,在这两个文件重,对数…...
OpenCV 图形API(74)图像与通道拼接函数-----合并三个单通道图像(GMat)为一个多通道图像的函数merge3()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 从3个单通道矩阵创建一个3通道矩阵。 此函数将多个矩阵合并以生成一个单一的多通道矩阵。即,输出矩阵的每个元素将是输入矩阵元素的…...
Redis应用场景实战:穿透/雪崩/击穿解决方案与分布式锁深度剖析
一、缓存异常场景全解与工业级解决方案 1.1 缓存穿透:穿透防御的三重门 典型场景 恶意爬虫持续扫描不存在的用户ID 参数注入攻击(如SQL注入式查询) 业务设计缺陷导致无效查询泛滥 解决方案进化论 第一层防护:布隆过滤器&am…...
负载均衡技术全景指南:架构、算法与发展趋势
负载均衡技术全景指南:架构、算法与发展趋势 一、负载均衡技术概述二、应用层负载均衡(一)HTTP 重定向(二)反向代理服务器 三、传输层负载均衡(一)DNS 域名解析负载均衡(二ÿ…...
DeepSeek-V3 解析第二篇:DeepSeekMoE
这篇文章是我们 DeepSeek-V3 系列的第二篇,聚焦于 DeepSeek 模型 [1, 2, 3] 的一个关键架构突破:DeepSeekMoE。 📚 本文也是我们【LLM 架构演化系列】的第二篇,聚焦 DeepSeek-V3 的 MoE 架构创新。如果你正研究大模型性能优化或架…...
【ArcGISPro学习笔记】布局输出时图例总是有省略号怎么办?
在用ArcGISPro制图时,发现布局输出时图例总是有省略号,例如下图: 调整半天都搞不定,必须把图例框拉很宽才没有省略号,非常影响布局体验 后来发现只需调整一个地方就把省略号弄没了,就是在图例排列这里&…...
驱散养生伪识阴霾,重铸科学养生晴空
在健康意识日益觉醒的当下,养生已然成为人们生活中备受瞩目的焦点。然而,各类养生伪知识如同阴霾,遮蔽了科学养生的光芒,误导着人们的养生实践。只有彻底驱散这些伪识阴霾,才能重铸科学养生的朗朗晴空,让健…...
【补题】Codeforces Round 664 (Div. 1) A. Boboniu Chats with Du
题意:给出n,d,m三个值,分别代表,有多少个值ai,使用超过m的ai,需要禁言d天,如果不足也能使用,m代表区分点,问能得到最大的值有多少。 思路: …...
大语言模型 06 - 从0开始训练GPT 0.25B参数量 - MiniMind 实机配置 GPT训练基本流程概念
写在前面 GPT(Generative Pre-trained Transformer)是目前最广泛应用的大语言模型架构之一,其强大的自然语言理解与生成能力背后,是一个庞大而精细的训练流程。本文将从宏观到微观,系统讲解GPT的训练过程,…...
Java进阶--设计模式
设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样࿰…...
同时启动俩个tomcat压缩版
下载解压tomcat压缩版 复制一份,换个名字 更改任意一个tomcat的配置文件用记事本打开 修改三个位置 1.<Server port"8005" shutdown"SHUTDOWN"> 2. <Connector port"8080" protocol"HTTP/1.1" …...
ZYNQ MPSOC之PL与PS数据交互DMA方式
ZYNQ MPSOC之PL与PS数据交互DMA方式 1 摘要 XILINX ZYNQ 以及 ZYNQ MPSOC主要优势在于异构 ARM+FPGA。其中非常关键的一点使用了 AXI 总线进行高速互联。而且这个 AXI 总线是开放给我们用户使用的。在前面的文章中我们详解了使用了AXI-HP方式PL到PS端进行数据交互。本文主要涉…...
Qwen3本地化部署,准备工作:SGLang
文章目录 SGLang安装deepseek运行Qwen3-30B-A3B官网:https://github.com/sgl-project/sglang SGLang SGLang 是一个面向大语言模型和视觉语言模型的高效服务框架。它通过协同设计后端运行时和前端编程语言,使模型交互更快速且具备更高可控性。核心特性包括: 1. 快速后端运…...
一种动态分配内存错误的解决办法
1、项目背景 一款2年前开发的无线网络通信软件在最近的使用过程中出现网络中传感器离线的问题,此软件之前已经使用的几年了,基本功能还算稳定。这次为什么出了问题。 先派工程师去现场调试一下,初步的结果是网络信号弱,并且有个别…...
golang接口和具体实现之间的类型转换
在 Go 语言中,如果你有一个接口类型的变量,并且你知道它的具体实现类型,你可以使用类型断言将其转换为具体类型。类型断言的语法是 value, ok : interfaceVar.(ConcreteType),其中 interfaceVar 是接口变量,ConcreteTy…...
独立站SaaS平台源码搭建全流程指南:从零到部署
一、什么是独立站SaaS? 独立站SaaS(Software as a Service)指通过自主搭建的云平台为用户提供软件服务,与第三方平台(如Shopify)相比,具有以下优势: 完全自主控制:可自…...
零基础学指针2
零基础学指针---大端和小端 零基础学指针---什么是指针 零基础学指针---取值运算符*和地址运算符& 零基础学指针---结构体大小 零基础学指针5---数据类型转换 零基础学指针6---指针数组和数组指针 零基础学指针7---指针函数和函数指针 零基础学指针8---函数指针数组…...
TM1668芯片学习心得二
一、该芯片包括的指令:显示模式设置命令、数据命令设置、地址命令设置、显示控制; 1、显示模式设置 2、数据命令设置 3、地址命令设置 4、显示控制...
[FPGA VIDEO IP] VCU
Xilinx H.264/H.265 Video Codec Unit IP (PG252) 详细介绍 概述 Xilinx LogiCORE™ IP H.264/H.265 Video Codec Unit(VCU,PG252)是一个专为 Zynq UltraScale MPSoC 设备设计的硬件加速视频编解码模块,支持 H.264(A…...
Git从入门到精通-第一章-基础概念
目录 为什么要版本控制? 版本控制系统 本地版本控制系统 集中化的版本控制系统 分布式版本控制系统 Git是什么? 直接记录快照 几乎所有操作都是本地执行 保证完整性 Git一般只添加数据 三种状态! Git的三种状态 Git的三个阶段…...
简单表管理
1.创建表(学生表,课程表,成绩表) --首先创建数据库 STUxxx CREATE DATABASE STU065; USE STU065; --创建学生表 CREATE TABLE SSS065(SNO CHAR(10) NOT NULL PRIMARY KEY, -- 学号SNAME VARCHAR(20) NOT NULL, -- 姓名DEPA VARCHAR(20), -- 系别AGE INT…...
C#静态类与单例模式深度解析(七):从原理到工业级应用实践
一、静态类:全局工具箱的设计艺术 1.1 静态类的本质特性 public static class MathUtils {// 静态字段(线程安全需自行处理)public static readonly double GoldenRatio = 1.618;// 静态方法public static double CircleArea(double radius){return Math.PI * radius * ra…...
2025年深圳杯-东三省联赛赛题浅析-助攻快速选题
深圳杯作为竞赛时长一个月,上半年度数模竞赛中难度最大的竞赛,会被各种省级竞赛、高校作为选拔赛进行选拔。本文为了能够帮助大家快速的上手该题目,将从涉及背景、解题所需模型、求解算法、实际求解中可能遇到的问题等详细进行描述࿰…...
springboot集成Lucene详细使用
以下是 Spring Boot 集成 Lucene 的详细步骤: 添加依赖 在 Spring Boot 项目的 pom.xml 文件中添加 Lucene 的依赖,常用的核心依赖和中文分词器依赖如下: <dependency><groupId>org.apache.lucene</groupId><artifac…...
【数据链路层】网络通信的“桥梁建设者”
目录 一、核心定位二、关键技术详解1. MAC地址体系2. 帧结构剖析(以太网V2为例)3. 典型协议对比 三、关键设备原理1. 交换机工作原理2. ARP协议流程 四、高级应用场景1. VLAN虚拟局域网2. 生成树协议(STP) 五、典型故障排查1. MAC…...
《多端统一的终极答案:X5内核增强版的渲染优化全解析》
跨端应用的需求呈爆发式增长,无论是电商购物、社交互动,还是金融理财类应用,都期望能够在不同平台上为用户提供一致且流畅的体验。而在这一过程中,跨端渲染技术成为了关键瓶颈。腾讯X5内核增强版的出现,犹如一道曙光&a…...
【MySQL数据库】事务
目录 1,事务的详细介绍 2,事务的属性 3,事务常见的操作方式 1,事务的详细介绍 在MySQL数据库中,事务是指一组SQL语句作为一个指令去执行相应的操作,这些操作要么全部成功提交,对数据库产生影…...
《Python实战进阶》No45:性能分析工具 cProfile 与 line_profiler
Python实战进阶 No45:性能分析工具 cProfile 与 line_profiler 摘要 在AI模型开发中,代码性能直接影响训练效率和资源消耗。本节通过cProfile和line_profiler工具,实战演示如何定位Python代码中的性能瓶颈,并结合NumPy向量化操作…...
intellij idea最新版git开启Local Changes
习惯了在idea的git插件里,查看项目已修改的文件,但是新版idea默认不展示了,用起来很难受。 参考网上教程开启方法如下: 1. 确保安装Git Modal Commit Interface插件并开启该插件 2. 在Advanced Settings开启Use Modal Commit In…...
C++ RAII 编程范式详解
C RAII 编程范式详解 一、RAII 核心概念 RAII(Resource Acquisition Is Initialization,资源获取即初始化) 是 C 的核心编程范式,通过将资源生命周期与对象生命周期绑定实现安全、自动化的资源管理。 核心原则: 资源…...