内部类复习笔记
- 成员内部类:成员内部类相当于一个类一个属性。
成员内部类能访问外部类的私有属性,外部类同理也能访问。
如何访问
在外部类中创建内部类的对象,通过在外部类的内部类对象访问内部类的私有属性,
内部类能直接访问外部类的私有属性和方法。
外部类创建内部类对象:
ObjectTest.Inner innerTest = new ObjectTest().new Inner();
外部类创建内部对象:
Inner inner = new Inner();
当外部类和内部类具有相同属性时用this.属性名。代表外部类的属性
注意内部类依赖于外部类对象,所以在使用内部类时一定要先创建外部类对象。
成员内部类与成员方法一样,不能拥有静态代码块以及静态属性
import jdk.nashorn.internal.ir.CallNode;
public class ObjectTest {
private String outer = "我是外部类";
int a = 20
class Inner{
private int a = 10;
String test = "我是内部类";
public void userInner() {
System.out.println(outer);
//使用的是外部类的a
System.out.println(this.a);
}
}
Inner inner = new Inner();
private void userOuter() {
System.out.println(outer);
Inner inner = new Inner();
System.out.println(inner.test);
}
}
public class MainTest {
public static void main(String[] args) {
ObjectTest.Inner innerTest = new ObjectTest().new Inner();
innerTest.userInner();
}
}
- 静态成员内部类:静态成员内部类只能访问外部类静态成员变量以及静态域,不能访问非静态变量和非静态域。
在外部类中创建内部类对象:
Inner inner = new Inner()
在其他类中创建静态内部类:
ObjectTest.Inner inner = new ObjectTest.Inner();
import jdk.nashorn.internal.ir.CallNode;
public class ObjectTest {
private static String outer = "我是外部类";
String a = "111";
static class Inner{
String test = "我是内部类";
public void userOuter() {
System.out.println(test);
System.out.println(outer);
//不能使用非静态变量
System.out.println(a);
}
}
//创建静态内部类对象
Inner inner = new Inner()
public static void inter(){
int a = 2;
System.out.println(2);
}
}
public class MainTest {
public static void main(String[] args) {
ObjectTest.Inner inner = new ObjectTest.Inner();
inner.userOuter();
};
}
- 方法内部类:
方法内部类定义在方法内,作用域也只在该方法内部。
- 方法内部类不能添加static访问符
- 方法内部类和上面的内部类一样可以访问外部类的属性和方法
- 方法内部类的对象只能在方法的作用域内创建
- 方法内部类可以直接访问方法中的属性
public class ObjectTest {
private static String outer = "我是外部类";
String a = "111";
public void function(){
String code = "我是方法属性";
class FunctionInnerClass{
int a = 10;
public void test(){
//访问外部类属性a
System.out.println(this.a);
//调用外部类的函数
sun();
//访问方法属性
System.out.println(code);
}
}
FunctionInnerClass functionInnerClass = new FunctionInnerClass();
System.out.println( a );
}
private void sun(){
System.out.println("我是外部函数");
}
}
- 匿名内部类:使用条件
- 必须继承一个抽象类或者实现一个接口
- 没有构造器
匿名内部类不能定义任何静态成员、方法、类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或继承一个类(抽象类)
public interface Sun {
void run();
}
public class MainTest {
public static void main(String[] args) {
//匿名内部类
new Sun(){
@Override
public void run() {
System.out.println("我是匿名内部类的方法");
}
};
};
}
匿名内部类可用于给方法传递实参,演示如下:
interface Dao {
void show();
}
public class AnonymousDemo {
//编写回调方法:callInner 参数类型为接口Dao
private static void callInner(Dao d) {
d.show();
}
public static void main(String[] args) {
callInner(new Dao() {//接口回调
//实现子类 但是没有名字 所以叫匿名内部类
@Override
public void show() {
System.out.println("匿名内部类用于给方法传递实参");
}
});
}
}
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
作者分享
很久没发贴文了,看了这么多优秀的同学在分享自己的经历,我也来说说吧。我是 2023 参加了 2024 年的研究生考试,有点遗憾没过。于是 2024 年继续二战。这次面试没过。被二刷了。于是今年跟着朋友的培训班,按照他们的方式进行简历包装,也成功混入了几家公司吧(五家)。我也不知道为什么我会换这么多,其实按理来说一年内两家都算多的,我发现我恐惧上班,对上班恐惧这需求我分析不了。恐惧需求延期,恐惧上线出现问题。这导致我今年过的很坎坷。
现在这家公司也是我一个关系好的老大,让我回来的(我实际入职的第一家,离职后又回来了),我自认为我面试来说没有任何压力,因为我有了一套自己的方式。但是对于工作。按我师傅的话来说。我就是差不多先生以及是奇思妙想先生还有就是胆小鬼。
差不多先生是说我在这几个月工作中的态度总是基于能用和能跑就行。
我师傅是大专学历但是做的大数据分析师。我老大让我跟着他学。这几个月我一直在跟他学怎么分析数据,怎么分析表与表的关系。
他对我说的最多的就是你去看表,看表里面有哪些字段,谁能关联谁。逐步去推上下游业务。这是我从他这里学到的。
至于他为什么叫我差不多先生,是因为。他在我工作中发现我在做数据同步任务的时候。写的 json 脚本能写出 6 种风格(依赖 ai)。能跑就行。第二处就是他让我建立的 Doris 表也有几种风格,他已经替我擦了几次屁股了。我似乎没听进去。后面行事还是如此(当然现在已经知道要改了)
奇思妙想先生,是说我在工作中总是有很多想法想去做这想去做那,永远也不会脚踏实地去做。他知道我想涨薪拿高工资。他便会骂我,又想法又不去行动(下班后我会去看看高并发的项目课,在他眼里这个些课没用,只有学技术才是王道),他让我去学的,我也都答应了但是没按他说的来。师傅抱歉。徒儿这次被裁后会回去好好学自己想从事的行业的技术。
胆小鬼是,我害怕交流(其实也有去问需求是怎么理解。如何用技术去实现),我有些不确定的,我会去问,但是不会带着思考去问,就算去问,我也说不清楚重点🤦♂️。很恼火。后面我找前辈让他们帮忙与客户对接,他们都说让我确定好后再找他们(其实我也有时候确定了没有)。我也很害怕自己的需求很难,害怕新技术突然要用到,害怕延期。我什么都怕,我不知道是不是自己不适合做这行?但是今天被通知裁员之前,我一直做的需求其实我做的还行,都做的没问题,我又觉得我行。但是写出来的代码自测没有很到位,写出来总会考虑的不周到。基本上还是老样子能跑通了,就丢给前端联调。
我相比于前面的同学,我真的很普通我也很焦虑。今年已经 25 岁了,明年 26 岁。我还是和学生一样没有长进。我也不知道怎么办。技术栈我也就常见的 spring 全家桶以及 vue3 MySQL redis 消息队列我也没做过,明年我该何去何从,我该转行吗。还是在家劳作
4
请各位大佬指正一下!!!orz orz
先简单说下我的情况,就是我有基础,项目也做过但是感觉只是敲了一遍,然后可能业务逻辑之前懂但是现在忘了(毕竟是听视频听懂了逻辑后再去敲了一遍)。然后那些专业技能我也只懂部分。
我的目标是春招
1一年半准备考研去了,现在没考上想先工作。但是我对于项目理解可能没有很深,项目上的一些技术我懂了一些。没有全部懂,没有懂得也在查资料尽可能的查漏补缺了。
2八股文也只是背了一小部分。
现在在学校每天的学习时间差不多有7个小时。
能请各位帮我看看简历,以及教教我怎么准备春招好吗跪求了 orz orz
我这样该怎么去春招啊各位大佬指点一下好吗
14
各位uu请问你们的八股文是怎么背的呀,能分享一下你们背八股文得方法吗[大哭][大哭]
12
好的,我在星球的第一分笔记来了。不画饼。这是我oj后一部分的笔记前面的没记。实属是我的错。跪下了磕了。
数据库数据存储:
存json的前提:
你不需要根据某个字段去倒查这条数据
你的字段含义相关,属于同一类的值
你的字段存储空间占用不能太大
以上可以考虑存json数组或json对象
何为sql语句的索引??索引的作用是啥??(加索引一般是根据具体业务来加的)
=========分割线。项目微服务改造=
跑通项目流程
1.合并questionSubmitController代码到questionController中
2.由于后端修改了接口地址,前端需要重修生成接口调用代码(与后端无关前端的事)
单体项目改造为微服务
什么是微服务?
服务:提供某类功能的代码
微服务:专注于提供某类特定功能的代码,而不是把所有的代码全部放到同一个项目中。会把整个大的项目按照一个特定的功能,逻辑进行拆分,拆分为多个子模块,每个子模块独立运行,独立负责一类功能,子模块之间相互调用互不影响。
微服务实现技术?
Spring Cloud
Spring Cloud Alibaba(本项目使用)
Dubbo(DubboX)
RPC(GRPC、TRPC)
本质上是通过HTTP、或者其他网络协议进行通讯来实现的
微服务的几个重要实现因素:服务管理、服务调用、服务拆分
Spring Cloud Alibaba
推荐参考中文文档来学习:https://sca.aliyun.com/zh-cn/
本质是在原有的基础上,进行了增强。在阿里的原有的业务基础上。
Spring Cloud Alibaba 相关技术栈
Spring Cloud Gateway:网关
Nacos:服务注册和配置中心
Sentinel:熔断限流
Seata:分布式事务
RocketMQ:消息队列,削峰填谷
Docker:使用Docker进行容器化部署
Kubernetes:使用k8s进行容器化部署
注意选择对应的版本。https://sca.aliyun.com/zh-cn/docs/2022.0.0.0/overview/version-explain
此处选择2021.0.5.0
Nacos:集中存管项目中所有的服务信息,便于服务之间找到彼此;同时,还支持存储整个项目中的配置
微服务的请求流程:
改造前的思考
从业务需求出发,思考单机和分布式的区别。
用户登录功能:需要改造为分布式登录。
其他内容:
有没有用到单机锁?改为分布式锁(伙伴匹配系统讲过)
有没有用到本地缓存?改为分布式缓存(redis)
需不需要用到分布式事务?比如多个库的操作
改造分布式登录:
1)application.yml增加redis配置
# Redis 配置
# todo 需替换配置,然后取消注释
redis:
database: 1
host: localhost
port: 6379
timeout: 5000
password: 123456
2)补充依赖
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
3)主类取消Redis自动配置的移除(删除exclude = {RedisAutoConfiguration.class})
@SpringBootApplication(exclude = {RedisAutoConfiguration.class})
4) 修改session存储方式:
spring.session.store-type:redis
5) 使用redis-cli或者redis管理工具,查看是否有登录后的信息
微服务的划分
从业务出发,想一下哪些功能职责是一起的?
公共模块:
common 公共模块(yuoj-backend-common):全局异常处理器、请求响应封装类、公共的工具类等
model 模型模块(yuoj-backend-model):很多服务公用的实体类
公用接口模块 (yuoj-backend-service-client):只存放接口,不存放实现类(多个服务之间要共享),需要引入openfeign在创建子模块时。
依赖服务:
注册中心:Nacos
微服务网关:Gateway 聚合所有的接口,统一接收前端请求
业务功能:
用户模块 (yuoj-backend-userService:8101端口)
注册
登录
用户管理
题目模块(yuoj-backend-questionServicet:8102端口)
创建题目(管理v员)
删除题目(管理员)
修改题目(管理员)
搜索题目(用户)
在线做题 (题目详情页)
题目提交
判题模块((yuoj-backend-judgeServicet较重的操作:8103端口)
执行判题逻辑
错误处理(内存溢出、安全性、超时)
自主实现 代码沙箱(安全沙箱)
开放接口(提供一个独立的新服务)
路由划分
用spring boot的context-path统一修改各项目的接口前缀,比如:
用户服务:
/api/user
/api/user/inner(内部调用,网关层面要做限制)
题目服务:
/api/question
/api/question/inner(内部调用,网关层面要做限制)
判题服务:
/api/judge
/api/judge/inner(内部调用,网关层面要做限制)
Nacos注册中心启动
选择2.2.0版本
教程:
https://sca.aliyun.com/zh-cn/docs/2022.0.0.0/user-guide/nacos/quick-start
官网下载Nacos:https://github.com/alibaba/nacos/releases/tag/2.2.0
Nacos教程官网:
https://nacos.io/zh-cn/docs/quick-start.html
安装好后,进入bin目录:
startup.cmd -m standalone
新建工程
springbcloud 有相当多的依赖,不建议自己写,而是用脚手架创建项目:
https://start.aliyun.com/ 给项目增加全局依赖配置文件
依次使用new modules和spring boot Initializr创建各个模块
需要给各模块之间绑定子父依赖关系
父模块定义modules,子模块引入parent语法,可以通过继承父模块配置,统一项目的定义和版本号
同步代码和依赖
1)common公共模块:全局异常处理器、请求响应封装类、公共的工具类等
在外层的pom.xml中引入公共类
2)model模型模块:很多服务公用的实体类
直接复制model包,注意代码沙箱model的引入
3)公用接口模块:只存放接口不存放实现(多个服务之间共享)先无脑搬运所有的service,judgeService也要搬运
需要指定openfeign(客户端调用工具)的版本:
4)具体业务服务实现
给所有业务服务引入公共依赖
主类引入注解:
引入application.yml配置文件
服务内部调用
现在的问题是,题目服务依赖用户服务,但是代码已经分到不同的包,已经找不到啊对应的Bean。
可以使用Open Feign组件实现跨服务的远程调用。
Open Feign:Http调用客户端,提供了更方便的方式来让你远程调用其他的服务,不用关系服务的调用的地址。
Nacos:注册中心获取服务的调用地址
1)梳理服务的调用关系,确定哪些服务(接口)需要给内部调用。
用户服务:没有其他的依赖
题目服务:
判题服务:
实现client接口
注意,每个服务模块有各自的service接口,这里实现的client接口只是对其他模块来进行提供服务。
对于用户服务,有一些不利于远程调用参数、或者实现起来非常简单(工具类),可以直接默认方法,无需远程调用,节约性能。
开启open feign的支持,把我们的接口暴露出去(服务注册到注册中心上),最为API给其他服务调用(其他服务从注册中心寻找)
需修改每个服务提供者的contex-path全局请求路劲
服务提供者:理解为接口的实现类,实际提供服务的模块(服务注册到注册中心上)
服务消费者:理解为为接口的调用方,需要去找到服务提供者,然后调用(其他服务从注册中心寻找)
注意事项:
要给接口的每个方法打上请求注解,注意区分Get、Post
要给请求参数打上注解,比如是get请求就打上RequestParam、post请求就打上RequestBody
FeignClient定义的请求路径一定要和服务提供方实际的请求路径保持一致
注意path处有两种情况,1是带/api/user能够访问的服务。2是带/api/user/inner的服务
并不是什么只有带/api/user/inner才能访问。
4)修改各业务服务的调用代码为feignClient
5)编写feignClient服务的实现类,注意要和其他之前定义的客户端保持一致
6)开启Nacos配置,让服务器之间能够相互发现
所有模块引入Nacos依赖,然后给业务服务(包括网关)增加配置:
给业务服务项目启动类上打上注解,开启服务发现、找到对应的客户端Bean的位置:
全局引入负载均衡依赖器依赖:
7)启动项目,测试依赖能否注入,能否完成相互调用
微服务网关
微服务网关(yuoj-backend-gateway):Gateway聚合所有的接口,统一接受处理前端的请求
为什么要用?
所有的服务端口不同,增大了前端调用成本
所有服务是分散的,你可能需要集中管理、操作,比如集中处理跨域问题、鉴权、接口文档、服务的路由、接口文档的安全性、流量染色、限流....
Gateway:想自定义一些功能,需要对这个技术有比较深度理解
Gateway:是应用层网关,会有一定的业务逻辑(比如根据用户信息判断权限)
Nginx:是接入层的网关:比如每个接入请求的日志,通常没有业务逻辑
接口路由
统一接手前端的请求,转发请求到对应的服务
如何找到路由?可以编写一套路由配置,通过api地址前缀来找到对应的服务
注意这个配置是在gateway网关模块来配置的,图中的url为负载均衡地址。predicates是找到这个路由的匹配方式(函数本人的理解)。图中的路由配置的意思是通过predicates配置的来找的这个url又由于lb://xxx为负载均衡配置,所以会到Nacos注册中心中找到对应id匹配的服务模块。
gateway需要导入的依赖:
聚合文档
以一个全局的视角集中查看管理接口文档
使用Knife4j接口文档生成器:
https://doc.xiaominfo.com/docs/middleware-sources/spring-cloud-gateway/spring-gateway-introduction
1)先给所有业务服务引入依赖,同时开启接口文档的配置
https://doc.xiaominfo.com/docs/middleware-sources/spring-cloud-gateway/spring-gateway-introduction#手动配置聚合manual
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-gateway-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
Knife4j:
enable: true
2)给网关配置集中管理文档接口
网关项目引入依赖:
引入配置:
3)访问地址即可查看聚合接口文档:
http://localhost:8101/doc.html#/home
(注意上述地址是鱼皮哥的文档接口地址,也是配置在gateway模块中的端口(8801)改下端口号就行了)
分布式Sesson登录(这里还需要去查资料有点不明白)
必须引入spring data redis依赖
解决Cookie跨域问题:
server:
address: 0.0.0.0
port: 8104
servlet:
context-path: /api/judge
#cookie 30天过期
session:
cookie:
max-age: 292000
# (这里是重点)
path: /api
跨域解决:
全局跨域配置:
、
权限校验
可以使用Spring Cloud Gateway的Filter请求拦截,接受到请求后根据请求的路径判断能否访问。
这是来自通过一个拦截器类的方法
扩展:可以在网关实现Sentinel接口实现限流降级,参考教程:
https://sca.aliyun.com/zh-cn/docs/2021.0.5.0/user-guide/sentinel/overview/
扩展:可以使用JWT Token实现用户登录,在网关层面通过toke获取登录信息,实现鉴权
Redisson RateLimiter也可以实现限流,智能BI讲过。
思考
真的有必要使用微服务吗?
真的有必要使用Spring Cloud实现微服务吗?
企业内部一般使用API(RPC、HTTP)实现跨部门、跨服务的调用,数据格式和调用代码全部自动生成,保持统一,同时解耦。
消息队列解耦
这部分等做完BI再回过头来看(函数暂时还没学过mq)
12
今天任务
1简历完善
2背八股面经2小时
3sql题3道题
4项目面试题1小时。
(后天开始用户中心)
6
