地址 | 作用 |
---|---|
/oauth/authorize | 授权端点,申请授权码。 |
/oauth/token | 令牌端点 |
/oauth/confirm_access | 用户确认授权提交端点 |
/oauth/error | 授权服务错误信息端点 |
/oauth/check_token | 用于资源服务访问的令牌解析端点 |
/oauth/token_key | 提供共公有秘钥的端点,如果你使用JWT令牌的话,需要注意的是授权端点这个URL应该被SpringSecurity保护起来职工授权用户访问 |
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
@Override
// 配置客户端信息
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
String secret = "{bcrypt}" + new BCryptPasswordEncoder().encode("123456");//OAuth推荐的密码存储方式 {加密算法}加密后的密码
clients.inMemory() // 将客户端的信息存储在内存中
.withClient("client_1") // 客户端 id, 需唯一
.secret(secret)//客户端密码
.authorizedGrantTypes("client_credentials", "password", "authorization_code", "refresh_token") // 认证服务器支持的认证模式 支持刷新令牌
.scopes("ui") // 客户端域
.redirectUris("http://www.baidu.com"); //授权成功重定向的url
}
/**
* 客户端密码编码器
*/
@Bean
public PasswordEncoder passwordEncoder(){
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer// 开启/oauth/token_key验证端口无权限访问
.tokenKeyAccess("permitAll()")
// 开启/oauth/check_token验证端口认证权限访问
.checkTokenAccess("isAuthenticated()")
//允许表单认证 请求/oauth/token的,如果不配置这个/oauth/token访问就会显示没有认证
.allowFormAuthenticationForClients();
}
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//SpringSecurity5.x 如果不配置此编码器,并在下面设置编码器,会报错
public PasswordEncoder userPasswordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser(User.withUsername("lzj").password("123456").roles("admin")).passwordEncoder(userPasswordEncoder());
}
}
@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtAccessTokenConverter accessTokenConverter;
@Autowired
private TokenStore tokenStore;
@Autowired
private TokenEnhancerChain tokenEnhancerChain;
@Autowired
private UserService userService;
@Override
// 配置客户端信息
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
String secret = "{bcrypt}" + new BCryptPasswordEncoder().encode("123456");//OAuth推荐的密码存储方式 {加密算法}加密后的密码
clients.inMemory() // 将客户端的信息存储在内存中
.withClient("client_1") // 客户端 id, 需唯一
.secret(secret)//客户端密码
.authorizedGrantTypes("client_credentials", "password", "authorization_code", "refresh_token") // 认证服务器支持的认证模式 支持刷新令牌
.scopes("ui") // 客户端域
.redirectUris("http://www.baidu.com"); //授权成功重定向的url
}
/**
* 客户端密码编码器
*/
@Bean
public PasswordEncoder passwordEncoder(){
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// 设置token存储方式,这里提供redis和jwt
endpoints
.tokenStore(tokenStore)//临牌存储方式
.authenticationManager(authenticationManager)//password模式要配置的认证管理器
.accessTokenConverter(accessTokenConverter)//token转换器
.tokenEnhancer(tokenEnhancerChain)//token加强器
.userDetailsService(userService)//执行token刷新需要带上此参数
.allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST);//允许访问暴露端点的方法
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer// 开启/oauth/token_key验证端口无权限访问
.tokenKeyAccess("permitAll()")
// 开启/oauth/check_token验证端口认证权限访问
.checkTokenAccess("isAuthenticated()")
//允许表单认证 请求/oauth/token的,如果不配置这个/oauth/token访问就会显示没有认证
.allowFormAuthenticationForClients();
}
}
@Configuration
public class TokenStoreConfig {
private String SIGNING_KEY = "lzj";
//JWT令牌存储方案
@Bean
public TokenStore tokenStore(){
return new JwtTokenStore(accessTokenConverter());
}
//JWT token转换器
@Bean
public JwtAccessTokenConverter accessTokenConverter(){
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(SIGNING_KEY);
return converter;
}
//token加强器 用于存储自己想要的信息到jwt中
@Bean
public TokenEnhancer tokenEnhancer() {
return new JWTTokenEnhancer();
}
//token加强器链 把加强器和转换器加入链中
@Bean
public TokenEnhancerChain tokenEnhancerChain(){
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
List<TokenEnhancer> enhancers = new ArrayList<>();
enhancers.add(tokenEnhancer());
enhancers.add(accessTokenConverter());
enhancerChain.setTokenEnhancers(enhancers);
return enhancerChain;
}
}
public class JWTTokenEnhancer implements TokenEnhancer {
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication authentication) {
Map<String, Object> info = new HashMap<>();
info.put("message", "myself design message");
((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(info);
return oAuth2AccessToken;
}
}
@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtAccessTokenConverter accessTokenConverter;
@Autowired
private TokenStore tokenStore;
@Autowired
private TokenEnhancerChain tokenEnhancerChain;
@Autowired
private UserService userService;
@Override
// 配置客户端信息
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
String secret = "{bcrypt}" + new BCryptPasswordEncoder().encode("123456");//OAuth推荐的密码存储方式 {加密算法}加密后的密码
// String secret = new BCryptPasswordEncoder().encode("123456");
clients.inMemory() // 将客户端的信息存储在内存中
.withClient("client_1") // 客户端 id, 需唯一
.secret(secret)//客户端密码
.authorizedGrantTypes("client_credentials", "password", "authorization_code", "refresh_token") // 认证服务器支持的认证模式 支持刷新令牌
.scopes("ui") // 客户端域
.redirectUris("http://www.baidu.com")//授权成功重定向的url
.accessTokenValiditySeconds(60 * 60 * 2) //toekn 过期时间
.refreshTokenValiditySeconds(60 * 60 * 24 * 7); //refresh token 过期时间
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// 设置token存储方式,这里提供redis和jwt
endpoints
.tokenStore(tokenStore)//令牌存储方式
.authenticationManager(authenticationManager)//password模式要配置的认证管理器
.accessTokenConverter(accessTokenConverter)//token转换器
.tokenEnhancer(tokenEnhancerChain)//token加强器
.userDetailsService(userService)//执行token刷新需要带上此参数
.allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST);//允许访问暴露端点的方法
}
@Bean
PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer// 开启/oauth/token_key验证端口无权限访问
.tokenKeyAccess("permitAll()")
// 开启/oauth/check_token验证端口认证权限访问
.checkTokenAccess("isAuthenticated()")
//允许表单认证 请求/oauth/token的,如果不配置这个/oauth/token访问就会显示没有认证
.allowFormAuthenticationForClients();
}
}
@Configuration
public class TokenStoreConfig {
private String SIGNING_KEY = "lzj";
//JWT令牌存储方案
@Bean
public TokenStore tokenStore(){
return new JwtTokenStore(accessTokenConverter());
}
//JWT token转换器
@Bean
public JwtAccessTokenConverter accessTokenConverter(){
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(SIGNING_KEY);
return converter;
}
//token加强器 用于存储自己想要的信息到jwt中
@Bean
public TokenEnhancer tokenEnhancer() {
return new JWTTokenEnhancer();
}
//token加强器链 把加强器和转换器加入链中
@Bean
public TokenEnhancerChain tokenEnhancerChain(){
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
List<TokenEnhancer> enhancers = new ArrayList<>();
enhancers.add(tokenEnhancer());
enhancers.add(accessTokenConverter());
enhancerChain.setTokenEnhancers(enhancers);
return enhancerChain;
}
}
public class JWTTokenEnhancer implements TokenEnhancer {
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication authentication) {
Map<String, Object> info = new HashMap<>();
info.put("message", "myself design message");
((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(info);
return oAuth2AccessToken;
}
}
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers().anyRequest()
.and()
.authorizeRequests()
.anyRequest().permitAll()
.and().cors().and().csrf().disable();
}
/**
* 用户密码编码器
*/
public PasswordEncoder userPasswordEncoder(){
return MyPasswordEncoder.getInstance();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(userPasswordEncoder());
}
//password模式要的认证管理器
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
public class MyPasswordEncoder implements PasswordEncoder {
private String salt;
private static MyPasswordEncoder instance = new MyPasswordEncoder();
public static MyPasswordEncoder getInstance() {
return instance;
}
public void setSalt(String salt) {
this.salt = salt;
}
@Override
public String encode(CharSequence rawPassword) {
return Hashing.md5().newHasher().putString(rawPassword + salt, Charsets.UTF_8).hash().toString();
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return encodedPassword.equals(encode(rawPassword));
}
}
public class SecurityUser implements UserDetails, Serializable {
private String username;
private String password;
private List<Permission> permissions;
public SecurityUser() {
}
public SecurityUser(String username, String password, List<Permission> permissions) {
this.username = username;
this.password = password;
this.permissions = permissions;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.permissions;
}
@Override
public String getPassword() {
return this.password;
}
@Override
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
public class Permission implements GrantedAuthority {
private Integer id;
private String code;
private String description;
private String url;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public String getAuthority() {
return this.code;
}
}
@Service
public class UserService implements UserDetailsService {
@Autowired
private UserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("进入了UserService");
User user = userDao.getUserByUsername(username);
if(user != null){
MyPasswordEncoder encoder = MyPasswordEncoder.getInstance();
encoder.setSalt(user.getSalt());
return new SecurityUser(username,user.getPassword(),userDao.findPermissionsByUserId(user.getId()));
}
throw new UsernameNotFoundException("用户名或密码错误!");
}
}
重写方法 | 作用 |
---|---|
configure(ClientDetailsServiceConfigurer clients) | 用来配置客户端详情服务(ClientDetailService),客户端详情信息在这里进行初始化,你能够把客户端详情信息写死在这里或者通过数据库来存储调用详情信息 |
configure(AuthorizationServerEndpointsConfigurer endpoints) | 用来配置另配的访问端点和令牌服务 通过以下属性决定支持的授权类型(GrantTypes) |
configure(AuthorizationServerSecurityConfigurer security) | 用来配置令牌端点的安全约束,通俗讲就是那些人能访问你暴露的令牌访问端点 |
配置信息 | 作用 |
---|---|
inMemoory | 调用内存存储客户端信息(必要) |
clientId | 用来表示客户的id (必要) |
secret | 客户端安全码 (必要) |
scope | 客户端的的访问范围 (必要) |
authorizedGrantTypes | 此客户端可以使用的授权类型,OAauth2.0五中授权类型,默认为空 (authorization_code 授权码模式,password 密码模式,implicit 简单模式,client_secret客户端模式 ) (必要) |
authroities | 客户端的的权限范围 |
resoutceIds | 资源列表 |
autoApprove | false代表跳转到授权页面 |
redirectUrls | 验证的回调地址 |
autoapprove | true为跳过授权页面的弹出 |
配置信息 | 作用 |
---|---|
authenticationManager | 认证管理器,当你选择了 password 授权类型的时候要注入一个AutheenicationManager对象 |
userDetailService | 用户信息查询Service,执行token刷新需要带上此参数 |
tokenGranter | token生成器 |
tokenServices | token管理服务 |
tokenStore | token存储策略 |
tokenEnhancer | token加强器 |
allowedTokenEndpointRequestMethods | 允许访问token端点的请求方式 |
pathMapping | 修改原来的url,第一个参数 这个端点URL默认的路径 第二参数 你要进行代替的URL路径 |
配置信息 | 作用 |
---|---|
tokenKeyAccess | /oauth/token_key接口的设置 |
checkTokenAccess | /oauth/check_token接口的设置 |
allowFormAuthenticationForClients | 允许表单认证,不开启/oauth/token将无法访问会报无认证错误 |
passwordEncoder | 验证客户端密码使用的编码器 |
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
@Configuration
@EnableResourceServer
public class ResourceServer extends ResourceServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Value("${spring.application.name}")
public String RESOURCE_ID;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources
.tokenStore(tokenStore)//令牌存储验证服务,让资源服务自己验证token
.resourceId(RESOURCE_ID)//资源ID
.stateless(true);//会话机制stateless开启
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/**").authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
@Configuration
public class TokenStoreConfig {
private String SIGNING_KEY = "lzj";
//JWT令牌存储方案
@Bean
public TokenStore tokenStore(){
return new JwtTokenStore(accessTokenConverter());
}
//JWT token转换器
@Bean
public JwtAccessTokenConverter accessTokenConverter(){
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(SIGNING_KEY);
return converter;
}
//token加强器 用于存储自己想要的信息到jwt中
@Bean
public TokenEnhancer tokenEnhancer() {
return new JWTTokenEnhancer();
}
//token加强器链 把加强器和转换器加入链中
@Bean
public TokenEnhancerChain tokenEnhancerChain(){
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
List<TokenEnhancer> enhancers = new ArrayList<>();
enhancers.add(tokenEnhancer());
enhancers.add(accessTokenConverter());
enhancerChain.setTokenEnhancers(enhancers);
return enhancerChain;
}
}
#客户端信息表
DROP TABLE IF EXISTS `oauth_client_details`;
CREATE TABLE `oauth_client_details` (
`client_id` varchar(48) NOT NULL,
`resource_ids` varchar(256) DEFAULT NULL,
`client_secret` varchar(256) DEFAULT NULL,
`scope` varchar(256) DEFAULT NULL,
`authorized_grant_types` varchar(256) DEFAULT NULL,
`web_server_redirect_uri` varchar(256) DEFAULT NULL,
`authorities` varchar(256) DEFAULT NULL,
`access_token_validity` int(11) DEFAULT NULL,
`refresh_token_validity` int(11) DEFAULT NULL,
`additional_information` varchar(4096) DEFAULT NULL,
`autoapprove` varchar(256) DEFAULT NULL,
PRIMARY KEY (`client_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#授权码表
Drop table if exists oauth_code;
create table oauth_code (
create_time timestamp default now(),
code VARCHAR(255),
authentication BLOB
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
//添加内容 注入对象
@Autowired
private DataSource dataSource;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
// 配置客户端信息
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//用数据库存储客户端信息
clients.withClientDetails(clientDetails());
}
.......
//以下是添加内容
//客户端信息服务
@Bean
public ClientDetailsService clientDetails() {
ClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
((JdbcClientDetailsService) clientDetailsService).setPasswordEncoder(passwordEncoder);
return clientDetailsService;
}
//授权码模式 存入jdbc中
@Bean
public AuthorizationCodeServices authorizationCodeServices(){
return new JdbcAuthorizationCodeServices(dataSource);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// 设置token存储方式,这里提供redis和jwt
endpoints
.tokenStore(tokenStore)//令牌存储方式
.authenticationManager(authenticationManager)//password模式要配置的认证管理器
.accessTokenConverter(accessTokenConverter)//token转换器
.tokenEnhancer(tokenEnhancerChain)//token加强器
.allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST)//允许访问暴露端点的方法
.authorizationCodeServices(authorizationCodeServices());//授权码服务配置
}
spring:
application:
name: oauth-server
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/springstudy?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
文章浏览阅读117次。神经网络初探——读《深度学习的数学》总结 学习是一个系统通过某种过程或者方式提升自身的某个或某些性能的过程,它本身包含的是一种自动化和可控化的含义。那么如何能让不具备智能的机器去学习呢?在模拟大脑神经元的工作原理后,看来我们已经找到了通往机器学习的一种方法,它叫做神经网络。神经网络是一种看似不可理解的复杂学习方法,这里包含着许多数学的知识。在阅读《深度学习的数学》一书之后,我想,我对神经网..._神经网络初探
文章浏览阅读3.5k次,点赞5次,收藏13次。音频分离Spleeter的安装1.环境依赖及建立(需要已安装anaconda)1.0 项目源地址(github地址)1.1 创建虚拟环境1.2 激活虚拟环境1.3 conda 安装spleeter1.4 下载一个示例音乐1.5 将该音乐分离为两部分1.5.1 报错:No module named numba.decorators1.5.2 解决方案:1.6 下载分类模型1.6.1报错ValueError:Can't load save_path when it is None.1.6.2 解决方案:1.6._2stems.tar.gz
文章浏览阅读64次。朋友曾经给我推荐了一个有关代码优化的pdf文档《让你的软件飞起来》,看完之后,感受颇深。为了推广其,同时也为了自己加深印象,故将其总结为word文档。下面就是其的详细内容总结,希望能于己于人都有所帮助。速度取决于算法同样的事情,方法不一样,效果也不一样。比如,汽车引擎,可以让你的速度超越马车,却无法超越音速;涡轮引擎,可以轻松超越音障,却无法飞出地球;如果有火箭发动机,就可以到达火..._bao.yuv
文章浏览阅读2.5k次,点赞3次,收藏33次。文章目录前言一、载具设置二、电机接线三、PWM输出设置四、航点设置前言一个人可以走的更快,一群人才能走的更远,交流学习加qq:2096723956更多保姆级PX4+ROS学习视频:https://b23.tv/ZeUDKqy分享知识,传递正能量,如有疏漏或不当之处,恳请指出.PX4固件版本:1.10.0硬件:淘宝竞速船或者打窝船实验录屏https://www.bilibili.com/video/BV1wA411c7p3?spm_id_from=333.999.0.0一、载具设置单电机_在px4固体中如何设置差速船
文章浏览阅读370次。每天都有大量的快递单号需要查询,如果一个个手动查询,不仅费时费力,还容易出错。为了解决这个问题,我们教您如何批量查询快递单号,并将快递物流信息进行备份并共享,实现高效管理。弹出一个对话框,文件名和保存类型不变,直接点“保存”,会提示备份成功,那么这个数据库就备份在电脑上了,也可以用第三方工具发送到其他电脑上。第四步,查询速度很快,我们就可以在主页面看到该批单号的运件信息了,比如:发出时间,状态,最后更新的物流时间,等等。第二步,在弹出来的文件框里,将需要查询的德邦快递单号都一一导入,并点击保存。_批量快递查询
文章浏览阅读7.7k次,点赞6次,收藏61次。敏捷开发(scrum)是一种软件开发的流程,强调快速反应、快速迭代、价值驱动。Scrum的英文意思是橄榄球运动的一个专业术语,表示“争球”的动作;运用该流程,你就能看到你团队高效的工作。一、四大价值观(特点)敏捷开发的特点就是下面4句话:「个体与交互」胜过「过程与工具」「可以工作的软件」胜过「面面俱到的文挡」「客户协作」胜过「合同谈判」「响应变化」胜过「遵循计划」说明:(1)敏捷开发(scrum)适用于竞争激烈,快速变化的市场。 敏捷的客户协作观念,快速迭代能帮助团队以最小成本,最快速_敏捷开发
文章浏览阅读2.2k次,点赞3次,收藏13次。802.11 Wi-Fi_wifi dfs
文章浏览阅读249次。pcie接口sata接口pcie总线pcie总线pcie控制器sata控制器nvme设备sata设备nvme协议ahci协议m-key接口b-key接口_rk3568 sata
文章浏览阅读1.3k次。循环队列可以很好的解决假溢出问题,不同于普通队列,在循环队列中,需将rear与front初始值都设置为0,rear指针指向队列中最后一个元素的下一个位置,也正因如此,数组是否存满的判定条件也应做出改变,在普通队列中,front==maxSize-1,即可认为数组已满,但是在循环队列中,由于在存放完数组最后一个有效位置后可以继续像数组中的0号位置进行存储,所以判断满的条件也会发生改变,—(rear+1)%maxSize = front.可以举个例子方便理解,假设一maxSize=5的数组,那么其有0 1_但是要利用循环队列的时候,处理假溢出,要使q.front=0的时候,为什么q.rear要加
文章浏览阅读4.8k次。linux CentOS 7下载步骤_centos7下载
文章浏览阅读464次。布局管理器提供相关的类对界面组件进行布局管理能够自动排布窗口中的界面组件窗口变化后自动更新界面组件的大小QLayoutQLayout 是Qt 中布局管理器的抽象基类通过继承QLayout实现了功能各异且互补的布局管理器Qt中可以根据需要自定义布局管理器布局管理器不是界面部件,而是界面部件的定位策略QBoxLayout 布局管理器以水平或者垂直的方式管理界面组件水平:QHBoxLayout 水平布局管理器垂直:QVBoxLayout 垂直布局管理器sizePolicy:QSize_qt layout可以嵌套layout吗
文章浏览阅读2.6k次。error MSB6006 rc exe 已退出,代码为 5_vs2010报警 error msb6006: “rc.exe”已退出,代码为 5。