java日常小知识记录--待更

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/study_notime/article/details/94390206

**、private修饰得方法可以通过反射得方式获取访问权限,那其意义是什么?
首先private作为类,方法,变量得访问权限,同public,protect一样,针对面向对象得一种访问权限修饰。也就是我们常说的封装概念。它并不是针对安全性的,绝对的不能访问得。下面上自己写的代码例子:
在这里插入图片描述在这里插入图片描述在这里插入图片描述

**、反射中得getFields与getDeclareFields方法得区别:
getFields只能访问public字段,如果继承了某个父类,则包括父类得public方法,而getDeclareFields返回当前类得所有修饰(private,protect,public)得字段。但是不包括父类得任何字段。
同理
访问方法
getMethods
getDeclaredMethods
访问内部类
getClasses
getDeclaredClasses
访问构造方法
getConstructors
getDeclaredConstructors

**、java类得初始化顺序
初始化顺序:实现类:静态变量–>静态方法 -->普通变量–>普通方法–>构造方法
接口-父类-子类 :接口静态变量-父类静态变量-父类静态方法-子类静态变量-子类静态方法-父类普通-父类构造-子类普通-子类构造。

**、jvm中得方法区与永久代得理解
方法区是共享区域,储存已经被虚拟机加载得类信息,常量,静态常量,即时编译后得代码信息等。
1 持久代也就是你说的永久代,翻译不同 这个区域会存储包括类定义、结构、字段、方法(数据及代码)以及常量在内的类相关数据。它可以通过-XX:PermSize及-XX:MaxPermSize来进行调节。如果它的空间用完了,会导致java.lang.OutOfMemoryError: PermGenspace的异常。而JDK8开始,持久代已经被彻底删除了,取代它的是另一个内存区域也被称为元空间。
2 存放数据
方法区存储的是每个class的信息:
1.类加载器引用(classLoader)
2.运行时常量池
所有常量、字段引用、方法引用、属性
3.字段数据
每个方法的名字、类型(如类的全路径名、类型或接口) 、修饰符(如public、abstract、final)、属性
4.方法数据
每个方法的名字、返回类型、参数类型(按顺序)、修饰符、属性
5.方法代码
每个方法的字节码、操作数栈大小、局部变量大小、局部变量表、异常表和每个异常处理的开始位置、结 束位置、代码处理在程序计数器中的偏移地址、被捕获的异常类的常量池索引

**、通过栈(jvm虚拟机栈中栈帧本地变量表所储存得引用地址)上得reference来访问内存中对象得两种方式
1、通过句柄池间接访问实例数据(栈中得引用地址为句柄池地址)
jvm会在java堆中开辟一部分内存用来当作句柄池,里面包括对象实例得地址与对象在方法区中得地址两部分内容
2、通过指针直接访问(实例数据得直接地址)
直接通过地址访问到实例数据对象。
区别:
当对象是易回收,容易发生GC时选择句柄池访问会好点。当是常用得对象,经常被访问时,用指针直接访问得方式比较好。
备注:hotspot使用的是指针直接访问得方式。

**、class.forname()与classloader之间得区别
classs.forName()其内部也是调用classLoader对类进行加载得,不同点在于forName中会调用一个forName方法,方法中有一个boolean参数,如果为ture则会对类加载并进行初始化(初始化静态方法, 静态变量等)。而classLoader只对类进行加载。
举例:spring中的ioc容易,就是采用的classLoader进行类加载得(双亲委派模式-bootstrapclassLoader(启动类加载器,加载指定路径下得jar,类库),Extendion ClassLoader(扩展类加载器,加载环境变量下指定路径得类库),applicationClassLoader,应用类加载器,加载用户指定路径下得类库,平时编写的代码采用的就是这个)。jdbc采用得是class.forName()方法对类加载(jdbc中driver需要向driverManage注册自己,而driverManage在类中是静态得,需要进行初始化,完成注册。)
补充:自定义加载器,需要重写classLoader中的findclass方法,并使用define最后生成class对象。
在这里插入图片描述 **、java中的socket
socket是针对tcp协议进行得一次封装,是操作系统抽象出来的一个概念,直接可在上层应用中进行编程。
socket可以理解为:协议 客户端IP 客户端port 服务端ip 服务端port
port是为了区别不同得进程之间建立socket连接得。
socket编程:
客户端: 系统可以自动分配port和自动获取ip
clientfd = socket{…} connect(clientfd,服务器Ip,服务器port,。。。。。) ; send(clientfd,数据); receiver(clientfd,…); close();
服务器端: 1、需要监听客户端发送得请求。2、根据客户端发送得多个请求,进行socket区分。
listenfd = socket{…}; bind(listenfd,本机得IP和端口,。。。) ; listen(listenfd,…) ;
while(true){
connfd = accept(listendfd,…);
receive(connfd,…);
send(connfd,…)
}
close();
connfd 相当于与客户端完成了三次握手的链接。用户通过此链接发送可靠消息。
每一个socket是通过客户端ip客户端port服务器端ip服务器端port加协议。当访问服务器得同一个进程时,服务器端不需要创建新的端口。为了区别socket可通过客户端得ip与客户端得port.

**、数据库得四种隔离级别与四种特性
设定 :写为w锁,读为r锁 ,两个事务,A事务,B事务
1、read uncommit 未提交读。会出现脏读。此时A写获取锁,A事务未提交,释放写锁,B获取读锁,A事务回滚,B读出来数据有问题。(读取到未提交的数据)
2、read commit 提交读。会出现不可重复读。A获取读锁,A事务未提交,A释放读锁,B获取写锁,B释放写锁,B事务提交,A获取读锁,A读取数据,发现数据已经改变,提交事务。(读取到更新或者删除的数据)
3、repeatable read 可重复读,会出现幻读,A,B事务顺序执行,A事务修改数据,B事务插入数据(插入的数据为A刚修改后的数据),A发现事务并没有修改(其实是B刚插入的数据)。(读取到新插入的数据)
4、serializable 顺序读。A事务修改时,B事务进行了插入操作。

1、原子性:同一个事务中,对数据库的操作要么成功,要么失败。
2、一致性:一个事务前后,无论操作是否成功,数据库都处于一个完整的状态
3、隔离性:多个事务之间对数据库的操作互不影响
4、持久性:一个事务的提交,那么该操作的影响是永久的
备注:一个事务中,若满足原子性,就满足一致性。多个事务中,满足原子性与隔离性,则满足一致性。

mysql隔离级别
隔离级别为可重复读。会出现幻读,通过innodb的mvcc多版本并发控制解决了该问题
事务版本号,新建一个事务时,版本号递增
系统版本号,当前操作的版本号等于事务版本号

新增数据,该行新增版本号为事务版本号
删除数据,改行删除版本号为事务版本号

查询时满足条件 当前事务版本号 < 新增数据版本号 当前事务版本号 > 删除数据版本号。

**、java中的静态与非静态
1、静态(常量,方法)是在类加载时就会初始化,通过类可直接访问。非静态是使用时进行初始化。
2、静态得效率比非静态高。非静态使用前会进行一些安全检查, 比如判断所属得对象是否为NULL。
3、静态得生命周期高于非静态。静态从加载就一直保存,不论是否被使用。
4、静态一般使用场景为一些工具类,提供一些功能, 无需访问非静态方法。由此导致了无法做扩展(继承,多态)的缺点

**、机器学习概念
1、通过一些现象,进行一些分析,得到预期的结果
2、随着数据量越大,得到的预期结果将会越高
3、机器学习分为三大类,有监督学习,无监督学习,半监督学习。
4、监督学习:通过一些输入,经过一个函数计算,得到一个合适的输出
5、无监督学习:通过一些输入,对数据中一些东西进行关联。
6、半监督学习:两者结合。

**、服务器返回码
200,访问正常
400,语法格式问题,服务器无法理解
401 主人, 这个东西没有授权你访问个啥啊
403 主人, 服务器不想搭理你
404 主人,找不到啊, 看看你敲的网址对不对
500 主人, 服务器崩溃了
503 主人, 服务器可能太忙了, 你等会再试吧
301,重定向。

**、spring中得依赖注入(DI)与控制反转(IOC)
经常听到得词,也是面试中经常问到得要点。以前百度看了很多,很官方,也很专业,下面用白话文得方式,以自己的理解写一下。

众所周知,java是面向对象编程得。在我们编程得过程中,难免会遇到一个类需要用到另外一个类得情况。类似于:
加粗样式
上面Person这个类,需要去读书,就需要借助读书类ReadBook 去创建对象,然后调用读书得方法。我们可以说Person这个类需要(依赖)ReadBook 这个类。同理依赖Play这个类去打游戏。
当spring还没出世得时候,人们得写法都是这样得。刚开始的是时候人们写起来很方便,也觉得不错,但是随着业务得复杂,发现一个类需要依赖得类太多了,每个类之间得关系也变得很乱很复杂。不得不进行代码优化。会用到常说得工厂模式(后续具体介绍java得设计模式)
类似这样:
在这里插入图片描述
简而言之就是通过子类ReadBook 与PlayGame 继承一个Interest父类,需要什么就传对应得type就可以了。这样Person这个类只需要依赖一个Inerest这个类就行了。看起来确实依赖关系简化了一些。但到后来,代码还是看着太多,每个类使用都要去初始化,去构造一下,还是太麻烦。人们想着能不能通过别的方式去管理这些类得之间关系,后来出现spring通过xml文件去维护。在配置文件中去配置这些类以及类得引用,也就是我们常说的bean,类似这样:
在这里插入图片描述
这样就够了吗,显然不够,spring还需要通过xml文件解析器解析配置文件中的bean,根据bean,通过java反射,得到类的实例,再通过上面得类似工厂模式下的,调用创建实例得方法,创建需要依赖得类的实例。依赖关系通过注解即可。spring大体的思路是这样的实现,具体的很多细节得去源码中查看,当然,比上面说的复杂得很多。
那么什么叫控制反转呢?spring还未出现之前,依赖类得时候,需要通过自己手动去实例化这个类。但是现在不一样了,spring提供了一个ioc。就像是一个容器,所有的类都在里面,当你需要什么,你就和容器说一下(配置bean),我要这个,容器就会给你提供。以前由自己去创建实例,现在改为由ioc容器管理了,控制得权限由自己变成容器了,也就叫做控制反转。

**、spring中得aop面向切面编程
面向切面编程,简而言之,找到切入点去编程。那在实际项目中得应用是什么。随着软件产业发展,随着业务需求得复杂化。项目中所需要的安全保障,性能,质量就得有所提高。
一个简单的支付项目会包括以下基本模块:用户信息,订单中心,支付中心,后台管理等。这个业务模块都必须依赖一些其他功能,比如:日志管理,事务管理,安全管理等公共模块。
新手程序员可能这样写:
在这里插入图片描述
功能实现了,但是整个代码中,业务相关的代码基本被覆盖了,很没有必要,有经验的程序员就会进行改善,用到了设计模式中的模板方法,模板方法模式简而言之就是设定一个父类,这些公用的功能在父类中去实现,业务类的代码通过子类去继承父类,只需重写父类中的业务相关方法即可。类似这样:
在这里插入图片描述
在这里插入图片描述
包括别的子类也一样,同样继承这个父类,只需关心自己的业务代码就可以了,不需要关心那些公共的功能。似乎解决了问题,但是问题又来了。如果按上述这样写。当有的子类不需要父类所有的方法,不是所有子类需要记录日志,或者性能测试等功能,这样写,让每个子类业务需求去继承,去实现一下,是不是有点浪费。父类中的那些功能顺序,子类也无法去改变,只能无条件接受父类的实现。过于死板,所以需要用到另外一种设计模式。装饰者模式。就是在模板方法上继续向上抽象一个父类,所有的业务类与功能类都继承他,类似如下:
在这里插入图片描述
当需要对应的功能,只需要对应实例化即可,类似于:
Common common = new OrderMng (new TransactionMng ());
common.excute();
如果需要加上日志管理,接着加上就行:
Common common = new OrderMng (new TransactionMng (new LogM()));
common.excute();
顺序也可以交换。
运用装饰者模式,是不是可以看的出,业务代码和功能代码基本分开了。
那么spring是通过什么方式来完成这些的呢。和装饰者差不多,但是优势在于,通过维护xml文件完全将这两者分离了。在编译的时候,读取aop的配置信息,将两者维护到一起。但这是静态态维护的,所以spring加上了通过动态代理(后续博客会详细介绍动态代理)产生一个代理类,动态的将需要切面的代码(公用的功能)放到代理类中。完成功能。

猜你喜欢

转载自blog.csdn.net/study_notime/article/details/94390206
今日推荐