实现邮箱管理之gmail邮箱、office365(Azure)邮箱之披荆斩棘问题一览

要进行Office365邮箱的授权对接,你需要先申请一个应用,并获取授权访问令牌。

以下是一个简单的步骤:

  1. 登录 Azure 门户:https://portal.azure.com/
  2. 创建一个新的应用程序,或者使用现有的应用程序。要创建新的应用程序,请选择“Azure Active Directory”仪表板中的“应用注册”。
  3. 在应用程序设置中,配置重定向 URI 或网页回调以获取授权代码。
  4. 授权应用程序向 Office 365 发送电子邮件并访问电子邮件内容。这可以通过 Azure 中的“API 权限”设置或“管理访问”设置轻松完成。
  5. 通过 OAuth2 流程获取授权代码,使用代码获取令牌并调用 Office 365 API。

在你获取了授权令牌后,你可以使用相应的库或SDK来与 Office 365 邮箱进行交互。例如,使用Microsoft Graph API 来发送和接收邮件,或者使用 Office 365 REST API 来集成邮件和日历等其他功能。

要进行Gmail邮箱的授权对接,你需要先拥有一个gmail邮箱,设置凭据及OAuth同意屏幕相关配置,并获取授权访问令牌。你可以按照以下步骤进行操作:

在这里插入图片描述

创建Google Cloud Platform (GCP) 项目:
  • 前往Google Cloud Console(https://console.cloud.google.com/)并登录。
  • 创建一个新的项目并为其命名。
启用Gmail API:
  • 在GCP控制台的导航菜单中,找到API和服务并点击进入。
  • 点击“+启用API和服务”按钮。
  • 在搜索栏中输入“Gmail”并选择“Gmail API”。
  • 点击“启用”按钮以启用Gmail API。
创建OAuth 2.0凭据:
  • 在API和服务页面,点击“凭据”选项卡,然后点击“+创建凭据”按钮。
  • 选择“OAuth客户端ID”选项。
  • 选择应用类型,如网页应用程序或桌面应用程序。
  • 填写必要的信息,例如名称和重定向URL。
  • 完成后,将生成客户端ID和客户端密钥。
配置OAuth 2.0访问权限:
  • 在GCP控制台的导航菜单中,找到API和服务并点击进入。
  • 点击“OAuth同意屏幕”选项卡,并选择应用程序类型。
  • 填写必要的信息,如应用名称和开发者联系信息。
  • 在“范围”部分,添加对Gmail API的访问权限,例如https://www.googleapis.com/auth/gmail.readonly
  • 点击“保存”按钮。
进行授权访问:

在浏览器中打开以下授权URL,并将其中的参数替换为你的实际值:
https://accounts.google.com/o/oauth2/auth?client_id=[YOUR_CLIENT_ID]&redirect_uri=[YOUR_REDIRECT_URI]&response_type=code&scope=https://www.googleapis.com/auth/gmail.readonly&access_type=offline
用户将被要求授予访问权限,并返回一个授权代码。

交换授权码以获取访问令牌:
  • 使用前面步骤中的授权代码,向以下URL发送POST请求,以获取访问令牌:
    POST https://accounts.google.com/o/oauth2/token
  • 在请求中包含以下参数:
    code:前面步骤中获得的授权代码。
    client_id:你的应用程序的客户端ID。
    client_secret:你的应用程序的客户端密钥。
    redirect_uri:你的重定向URI。
    grant_type:设置为authorization_code
使用访问令牌访问Gmail API:
  • 使用获得的访问令牌,发送HTTP请求以通过Gmail API访问用户的邮件数据。

以上是进行Gmail邮箱的授权对接的基本步骤。你可以根据你的具体需求和开发环境进一步调整和配置。

邮箱项目实施中所遇到的问题:

1、选中一个邮箱的收件箱,之前选中的邮箱的收件箱还被选中bug
2、未读数未显示bug
3、No refreshToken in msal-node when providing scope "offline-access"

1、控制抖动频率,防止用户过快刷新导致崩溃,骨架屏时,用户切换其他邮箱的文件夹,又可以刷新列表,现在要做一个限制用户在骨架屏没加载完毕前,点击刷新不做处理。
2、第一次安装完electron客户端包后,收件人输入一个错误地址,然后弹出了那个编辑收件人的引导语,引导语消失以后,这个错误的收件人前面有个空白区域。 只有把vv-debug 这个文件夹删除掉,才能复现。
3、刷新令牌过期后,365刷新逻辑有问题。可能是初始化机制问题。
4、针对错序问题,需要给获取邮箱文件夹和文件夹列表的sdk提供时间戳,必要的话前端通过id处理判断是否是同一个邮箱发起的请求。
5、删除邮箱成功的图标是错误时的打叉图标,并且删除在还没弹框确认时就删成功了!

1、点击第二个邮箱的收件箱,选中后会刷新邮件列表,此时选中状态会被撤销掉【bug】。
2、过期时,google会有警告图标,但是刷新后code=0页还是出现了该图标,退出邮箱重进才恢复正常。【bug】。
3、草稿收件人 输入4 韦毅(下拉搜索选人组件) 会发现无法选中,可能是该数据是脏数据。
4、选择一个邮箱,点击一个邮件,再点击切换其他邮件,居然会变成拖拽多选?(变成了默认展示的数据了,默认是开启的允许多选拖拽,属于错误的状态)

1、写一个google的demo,同步scopes和其他配置,用来对照google auth2认证是否稳定。
2、UI如果有提供再进行还原。
3、365过期无法通过刷新令牌验证成功。
4、调用update接口后的回调里,进行valifyPassword验证发现该函数所有参数都没有数据!
5、当超时后,会进行update更新令牌数据,但是列表没有获取到,这时需要同步更新验证verifyPd,但是看起来好像不是这个问题导致的,像是因为新令牌验证不通过

google阶段问题总结
  • gmail 的2个测试邮箱在令牌有效期内,都可以接收邮件。

  • gmail 的2个测试邮箱在令牌有效期内,都可以发送邮件。

  • gmail在token有效期内可以发送成功邮件。并且发现添加有时候可以通过,有时候通不过。

  • gmail只剩下超时情况还没有进行复盘!

  • 发现bug,点击已发送,收件箱未读数量变29,点回收件箱数量变30。

  • gmail测试账户1用刷新令牌获取访问令牌验证失败了,猜测是帐户本身出了问题导致无法访问。

  • gmail测试账户2用刷新令牌获取访问令牌验证成功了,但是首次刷新的时候,文件夹打开没有内容,说明没有在更新时进行文件夹列表的获取!!!

  • 并且gmail测试账户1更新访问令牌后可以获取到新邮件,也可以发送邮件。

其他bug

【bug】从126发邮件到gmail和office365邮箱,gmail邮箱在不退出邮箱Tab重新打开的情况下,点击中间区域的刷新图标,发现收件箱没有刷新新的数据。退出邮箱Tab重新打开则可以刷出来!!!最后发现是因为每3分钟轮询了未读邮件和未读数,与点击刷新无关。但是可能出问题的那个时候轮询是未生效的。最后纠正,前面的现象是错误的,手动点击刷新也是会获取未读数和未读邮件的。结论:可能是刚好那个时候梯子网络不好或者gmail服务器繁忙。

【PS】:一开始进来邮箱tab页面的时候,可能获取到了邮箱和邮箱文件夹,但是中间的邮件区显示暂无数据,这边的做法是通过轮询定时去查数据,后面就有数据了!!!

1、删除gmail邮箱后不关闭tab重新添加3次,全部verifyPsd失败。关闭tab后重进,再添加gmail成功。成功后再删掉,再新增仍旧成功。那么引起首次失败的原因是什么?关闭tab,再次打开tab,删掉gmail,添加gmail,添加成功了。

2、超期的gmail邮箱以及365邮箱收不到新邮件,即便已经刷新了token,这个时候需要关闭邮箱TAB重新进才能收到,此时又再次获取了token以及update了一次。可能是缺少了初始化的数据导致的该BUG!并且,提示有问题,提示删除,其实不一定要删除。

阶段问题总结:
  • office365支持PC换机保存状态 google支持(但是不稳定)。

  • office365目前没有支持登录多个,因为只要登录一次,下次就不走登录逻辑了,改成内部弹窗形式。

  • google 路径重定向被篡改问题。

  • google支持跨PC设备、365暂不支持。跨设备文件夹都为空。

  • google令牌失效及文件夹为空、365令牌失效及文件夹为空。

  • 跨端暂不支持,数据不互通,因为接口没有统一成一个端进行调用。

  • google添加帐户有可能在verifyPassword环节验证失败。

PS: vv release命令执行后,会吃掉其他非release命令打印的控制台日志(仅供vv桌面端参考)

渲染进程IPC和主进程通信有2种方式:
1、IpcRenderer.invoke针对需要传递参数的同步或者异步操作

const res = await IpcRenderer.invoke('EMAIL_AUTH_LOGIN', params);

返回值会一直等待主进程返回消息才继续往下传递执行。
2、IpcRenderer.send;针对只需要事件触发的异步通信操作

IpcRenderer.send('EMAIL_AUTH_SIGN_OUT'); 

主进程IPC和渲染进程通信有2种方式:

// 登录
ipcMain.handle('EMAIL_AUTH_LOGIN', async (_, params) => {console.log('>>>>>>> EMAIL_AUTH_LOGIN ipcMain.on', params);const respInfo = await authProvider?.login();// ipcMainconsole.log('>>>>>>> EMAIL_AUTH_LOGIN respInfo', respInfo);return respInfo;
});
// 退出
ipcMain.on('EMAIL_AUTH_SIGN_OUT', () => {authProvider?.logout();
});

1、主进程只处理非交互的事情,比如调用auth2的授权接口返回数据给渲染进程,再由渲染进程进行UI交互处理,例如打开一个Tab窗口。
2、桌面端主进程console可以打印在TERMINAL窗口,但渲染进程(渲染主进程、渲染辅助进程)不能,它需要用Log打印才能在vscode的TERMINAL窗口打印,否则它会在浏览器的console里打印。

1、快速删除google邮箱2个时,有一个弹窗列表已删除,但是上面的列表上还存在,数据可能没更新
2、优化进入邮箱调用了两次list接口(第二次是token令牌过期后去刷新的列表)
3、google收件箱的未读数没有显示,后来出现了,可能是拉取google接口数据太慢导致的

【***】 google出现了无法添加成功的原因是因为经过了首次获取到了刷新令牌,后面的测试环节获取到的都是只有访问令牌,而且可能访问令牌失效了,两个原因叠加造成无法绑定。
但是,新获取到的访问令牌是有效的,以上可能只有刷新令牌缺少这一点论据成立。
google auth2有了刷新令牌后,添加成功了

【***】 office365出现token报错的原因,缺少了origin只是表象,实际是因为首次使用刷新令牌后,没有更新成功,而旧的刷新令牌365是会失效的,因此无法使用导致70000报错,PKCE授权码授权流方式只支持Spa。

【***】 office 365 的accessToken如果过期 会导致邮箱文件夹的内容获取不到,如果已加载过的文件夹是存在缓存的。

服务端提供2个接口:

一个上传token和refreshtoken,旧的会被新上传的覆盖。
另一个用来获取token和refreshtoken,在前端自己做一个轮询方案,每隔3秒判断是否过期,
如果过期了就再次调用365或google接口获取token和refreshtoken。

验证google令牌的有效性:

访问基础邮箱账户信息接口:
https://content-gmail.googleapis.com/gmail/v1/users/me/profile
Authorization值(等同于于token):
Bearer ya29.a0AWY7CkmOojfCwzRGf5iQhAaAL8uKWDEwe9tf8Lga1EDd-1ChS00IDwsjmd2DREbBzksAKLpk8KxowXBErYW3MlwlmACxMLqo9p4IfHAzGZQDik94mJoOOgukIdi30GJ9E0mdGYLJyTzymmqUJpjtWUoGZtkJaCgYKAVQSARMSFQG1tDrp13argMBe8kcNlqXOb4YCIw0163
PS:Bearer后面有个空格,请不要漏掉

验证office365令牌的有效性:

访问基础邮箱账户信息接口:
https://graph.microsoft.com/v1.0/me

Authorization值(等同于于token):
Bearer ya29.a0AWY7CkmOojfCwzRGf5iQhAaAL8uKWDEwe9tf8Lga1EDd-1ChS00IDwsjmd2DREbBzksAKLpk8KxowXBErYW3MlwlmACxMLqo9p4IfHAzGZQDik94mJoOOgukIdi30GJ9E0mdGYLJyTzymmqUJpjtWUoGZtkJaCgYKAVQSARMSFQG1tDrp13argMBe8kcNlqXOb4YCIw0163
PS:Bearer后面有个空格,请不要漏掉

office365的scopes:

“user.read openid profile offline_access https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All%20 https%3A%2F%2Foutlook.office365.com%2FSMTP.Send”

其他早期阻塞点备注:

-1、使用replace+正则表达式过滤邮箱内容提取摘要时,在多封邮件,且邮件内容好几万个字符时,发现邮箱列表(列表获取的摘要是从内容过滤出文本拿到的)明显卡顿。排查后发现是正则替换导致的。卡顿具体原因如下:

  • 当字符数量较多时,使用replace配合正则表达式可能会有性能问题的原因主要有两个:
    • 正则表达式的处理复杂度:正则表达式的匹配和替换操作通常比较复杂,特别是当需要处理大量字符时,正则表达式的处理复杂度会相应增加。正则表达式引擎在处理长字符串时可能需要进行多次匹配和回溯操作,这会导致性能下降。
    • replace 的执行次数:replace方法会在字符串中搜索并替换所有匹配的字符或模式。如果字符数量很多,那么替换操作也会频繁执行很多次,这会增加整体的执行时间。

0、office365的azure邮箱在测试过程中,由于频繁登进登出,会触发微软的安全机制,限制连接邮箱服务器,因此这会导致授权登录成功,但是实际上后台sdk连接不上微软的邮箱服务器,导致获取邮箱信息失败!!!【排查难度*****】
1、micro-app的沙箱问题,在沙箱开启后,无法调用google auth2接口,关闭沙箱后能正常使用
2、针对第三方请求,谨慎处理请求头的添加,避免第三方请求由于严格安全校验导致请求失败
3、桌面、子应用内的iframe缺少执行jsbridge的宿主环境,缺少全局属性及数据
4、子应用中打开窗体,仍旧无法将请求发送完全,react-google-login组件实现的谷歌认证按钮无法静默请求成功谷歌认证接口
5、采用邮箱内封装的request.post请求谷歌接口,请求发送不出去,但axios可以
6、采用electron打开一个窗体内嵌webview的方式打开授权页,在webview内部无法关闭webview授权页面本身(因为是窗体,但主应用本身没有关闭的api提供),并且无法通过协议的方式传递消息(没有开放window.open权限),使用postMessage传递消息在主应用也无法监听到。
7、独立的窗体承载webview实现auth2是不需要用到我们应用内的用户认证相关的逻辑的,又因为所有路由都会默认在BasicLayout布局组件里渲染,且在BasicLayout中有一些用户获取及窗体tab等相关操作,注意,这意味着里边的获取用户信息,获取窗体tab等等信息也会同时加载,但我们只是单纯的一个auth2认证页面,不需要这些,因此我们需要把auth2的路由单独提到最顶级,和/路径对应的BasicLayout布局组件并列,并且需要保证auth2的路由在/路由上方,这是为了防止/在上方时,默认把auth2组件的路由第一级给匹配到,这样会导致下面的与/路由同级的auth2路由不再被匹配。
PS:使用preload的方式在预加载时注入全局方法到webview里的window对象上
8、需要对electron打开的webview里的auth2页面修改Navigator.userAgent的值,目的是为了
过滤掉我们的判断逻辑(isElectronEnv,判断是否是electron的开发环境),它是通过判断userAgent判断是否存在electron字符串作为客户端的依据来给isElectronEnv赋值的。
如下所示:

<webviewsrc={webviewUrl}style={{ flex: 1 }}useragent={userAgent}preload={preloadJs}webpreferences="enableRemoteModule=true,nodeIntegration=true,nativeWindowOpen=yes,contextIsolation=false"
/>

Tokens issued for the 'Single-Page Application' client-type may only be redeemed via cross-origin requests
为单页应用程序客户端类型颁发的令牌只能通过跨来源请求兑换。
解决:给请求添加“Origin”标头

headers: {'Origin': 'http://localhost'
}

谷歌登录发布生产所需材料(office365 Azure不区分环境,不需要提交材料到微软审核):

1、应用名称
2、用户支持电子邮件地址
3、应用icon 100px*100px
4、应用域-----
应用主页地址(为用户提供指向您主页的链接)
应用程序隐私政策链接
申请服务条款链接(为用户提供指向您的公共服务条款的链接)非必须
5、授权域-----
授权登录所要访问我们的域名(vv.cn、vvtechnology.cn)
6、开发商联系方式(电子邮件地址)
7、一段 YouTube 视频,展示了您计划如何使用从范围获取的 Google 用户数据
8、一份书面解释,告诉 Google 为什么您需要访问敏感和/或受限用户数据

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从0到1开发go-tcp框架【3-读写协程分离、引入消息队列、进入连接管理器、引入连接属性】【基础篇完结】

从0到1开发go-tcp框架【3-读写协程分离、引入消息队列、进入连接管理器、引入连接属性】 1 读写协程分离[v0.7] 添加一个Reader和Writer之间通信的channel添加一个Writer goroutineReader由之前直接发送给客户端改为发送给通信channel启动Reader和Writer一起工作 zinx/znet/co…

【Golang 接口自动化05】使用yml管理自动化用例

目录 YAML 基本语法 对象&#xff1a;键值对的集合(key:value) 数组&#xff1a;一组按顺序排列的值 字面量&#xff1a;单个的、不可再分的值&#xff08;数字、字符串、布尔值&#xff09; yml 格式的测试用例 定义yml文件 创建结构体 读取yml文件中的用例数据 调试…

【1.3】Java微服务:Spring Cloud版本说明

✅作者简介&#xff1a;大家好&#xff0c;我是 Meteors., 向往着更加简洁高效的代码写法与编程方式&#xff0c;持续分享Java技术内容。 &#x1f34e;个人主页&#xff1a;Meteors.的博客 &#x1f49e;当前专栏&#xff1a; 微服务 ✨特色专栏&#xff1a; 知识分享 &#x…

【后端面经】微服务构架 (1-6) | 隔离:如何确保心悦会员体验无忧?唱响隔离的鸣奏曲!

文章目录 一、前置知识1、什么是隔离?2、为什么要隔离?3、怎么进行隔离?A) 机房隔离B) 实例隔离C) 分组隔离D) 连接池隔离 与 线程池隔离E) 信号量隔离F) 第三方依赖隔离二、面试环节1、面试准备2、基本思路3、亮点方案A) 慢任务隔离B) 制作库与线上库分离三、章节总结 …

深度学习各层负责什么内容?

1、深度学习——神经网络简介 深度学习(Deep Learning)(也称为深度结构学习【Deep Structured Learning】、层次学习【Hierarchical Learning】或者是深度机器学习【Deep Machine Learning】)是一类算法集合&#xff0c;是机器学习的一个分支。 深度学习方法近年来&#xff0c…

元宇宙虚拟展厅的特点是什么呢?优势有哪些?

元宇宙是一个很广阔的虚拟世界&#xff0c;它可以创造出更为丰富、沉浸式的体验&#xff0c;这种全新的体验为展览和艺术领域带来了更多的可能性&#xff0c;元宇宙虚拟展厅以其多样化、互动性、沉浸式展示的特点&#xff0c;带领大家进入一个虚拟现实的全新世界。 元宇宙虚拟展…

MACOM EDI 需求分析

MACOM 是一家全球性半导体公司&#xff0c;专注于设计和制造高性能射频、微波和光电元件&#xff0c;其产品被广泛应用于通信、航空航天、国防、工业和医疗等领域。随着 MACOM 的不断发展&#xff0c;传统数据传输方式效率较低&#xff0c;无法满足 MACOM 的需求。为了提高企业…

使用自适应去噪在线顺序极限学习机预测飞机发动机剩余使用寿命(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

代理模式--静态代理和动态代理

1.代理模式 定义&#xff1a;代理模式就是代替对象具备真实对象的功能&#xff0c;并代替真实对象完成相应的操作并且在不改变真实对象源代码的情况下扩展其功能&#xff0c;在某些情况下&#xff0c;⼀个对象不适合或者不能直接引⽤另⼀个对象&#xff0c;⽽代理对象可以在客户…

【前端知识】React 基础巩固(三十六)——RTK中的异步操作

React 基础巩固(三十六)——RTK中的异步操作 一、RTK中使用异步操作 引入RTK中的createAsyncThunk&#xff0c;在extraReducers中监听执行状态 import { createSlice, createAsyncThunk } from "reduxjs/toolkit"; import axios from "axios";export cons…

Spring事务传播机制、实现方式、失效场景即原理

贴一篇源码分析的好文章&#xff1a;https://blog.csdn.net/qq_30905661/article/details/114400417 本质&#xff1a; 一个事务对应一个数据库连接。 通过 this 来调用某个带有 Transactional 注解的方法时&#xff0c;这个注解是失效的&#xff0c;可以看做这个方法&#x…

安防视频汇聚平台EasyCVR视频广场面包屑侧边栏支持拖拽操作

智能视频监控平台EasyCVR能在复杂的网络环境中&#xff0c;将海量设备实现集中统一接入与汇聚管理&#xff0c;实现视频的处理与分发、录像与存储、按需调阅、平台级联等。 TSINGSEE青犀视频汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协…

2023年中职组“网络安全”赛项吉安市竞赛任务书

2023年中职组“网络安全”赛项 吉安市竞赛任务书 一、竞赛时间 总计&#xff1a;360分钟 竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 A模块 A-1 登录安全加固 180分钟 200分 A-2 本地安全策略配置 A-3 流量完整性保护 A-4 事件监控 A-5 服务加固…

MYSQL进阶-事务

什么是数据库事务&#xff1f; 事务是一个不可分割的数据库操作序列&#xff0c;也是数据库并发控制的基本单位&#xff0c;其执 行的结果必须使数据库从一种一致性状态变到另一种一致性状态。事务是逻辑上 的一组操作&#xff0c;要么都执行&#xff0c;要么都不执行。 事务最…

使用express搭建后端服务

目录 1 创建工程目录2 初始化3 安装express依赖4 启动服务5 访问服务总结 上一篇我们利用TDesign搭建了前端服务&#xff0c;现在的开发讲究一个前后端分离&#xff0c;后端的话需要单独搭建服务。后端服务的技术栈还挺多&#xff0c;有java、php、python、nodejs等。在众多的技…

2023-08-03 LeetCode每日一题(删除注释)

2023-08-03每日一题 一、题目编号 722. 删除注释二、题目链接 点击跳转到题目位置 三、题目描述 给一个 C 程序&#xff0c;删除程序中的注释。这个程序source是一个数组&#xff0c;其中source[i]表示第 i 行源码。 这表示每行源码由 ‘\n’ 分隔。 在 C 中有两种注释风…

【图论】强连通分量

一.定义 强连通分量&#xff08;Strongly Connected Components&#xff0c;简称SCC&#xff09;是图论中的一个概念&#xff0c;用于描述有向图中的一组顶点&#xff0c;其中任意两个顶点之间都存在一条有向路径。换句话说&#xff0c;对于图中的任意两个顶点u和v&#xff0c;…

数学学习——最优化问题引入、凸集、凸函数、凸优化、梯度、Jacobi矩阵、Hessian矩阵

文章目录 最优化问题引入凸集凸函数凸优化梯度Jacobi矩阵Hessian矩阵 最优化问题引入 例如&#xff1a;有一根绳子&#xff0c;长度一定的情况下&#xff0c;需要如何围成一个面积最大的图像&#xff1f;这就是一个最优化的问题。就是我们高中数学中最常见的最值问题。 最优化…

《Java-SE-第二十七章》之常见的锁策略

前言 在你立足处深挖下去,就会有泉水涌出!别管蒙昧者们叫嚷:“下边永远是地狱!” 博客主页&#xff1a;KC老衲爱尼姑的博客主页 博主的github&#xff0c;平常所写代码皆在于此 共勉&#xff1a;talk is cheap, show me the code 作者是爪哇岛的新手&#xff0c;水平很有限&…