1. java io 字节流 字符流 使用场景
2. java序列化 什么时候会用到
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,将数据分解成字节流,以便存储在文件中或在网络上传输。
可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。
序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用
ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流;
序列化分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。
反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例
什么时候使用序列化:
一:对象序列化可以实现分布式对象。主要应用例如:RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。
二:java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。
3. java集合类 哪些是线程安全的 为什么它们是线程安全的
vector:就比arraylist多了个同步化机制(线程安全)
statck:堆栈类,先进后出
hashtable:就比hashmap多了个线程安全
ConcurrentHashMap:是一种高效但是线程安全的集合。
enumeration:枚举,相当于迭代器
4. String a = "a"创建了几个对象
如果字符串常量池中存在abc,则该语句并不会创建对象,只是讲字符串常量池中的引用返回而已。
如果字符串常量池中不存在abc,则会创建并放入字符串常量池,并返回引用,此时会有一个对象进行创建。
5. mysql存储引擎 隔离级别
REPEATABLE-READ(可重读)
原子性: 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
一致性: 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;
隔离性: 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
持久性: 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
事务是逻辑上的一组操作,要么都执行,要么都不执行。
在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务(多个用户对统一数据进行操作)。并发虽然是必须的,但可能会导致以下的问题。
1.脏读(Dirty read): 当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。
2.丢失修改(Lost to modify): 指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改。 例如:事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。
3.不可重复读(Unrepeatableread): 指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。
4.幻读(Phantom read): 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。不可重复度和幻读区别:
不可重复读的重点是修改,幻读的重点在于新增或者删除。
例1(同样的条件, 你读取过的数据, 再次读取出来发现值不一样了 ):事务1中的A先生读取自己的工资为 1000的操作还没完成,事务2中的B先生就修改了A的工资为2000,导 致A再读自己的工资时工资变为 2000;这就是不可重复读。
例2(同样的条件, 第1次和第2次读出来的记录数不一样 ):假某工资单表中工资大于3000的有4人,事务1读取了所有工资大于3000的人,共查到4条记录,这时事务2 又插入了一条工资大于3000的记录,事务1再次读取时查到的记录就变为了5条,这样就导致了幻读。SQL 标准定义了四个隔离级别:
READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。
隔离级别脏读不可重复读幻影读
6. spring中resources注解和Autowired的区别
首先,@Resource 是 JSR-250 标准的注释,不属于 Spring 中的标准注解,而@Autowired 属于 Spring 中的注解。
@Autowired 与@Resource 都可以用来装配 bean. 都可以写在字段上, 或写在 setter 方法上。
不同在于:
@Autowired 默认按类型装配(byType),如果要按名称装配的话,必须和@Qualifier 注解一起使用。@Autowired() @Qualifier("myBean") private MyBean myBean;
@Resource,默认按名称进行装配(byName),通过 name 属性设置名称,如果没有设置 name 属性,则默认取字段名名称进行查找。如果还是找不到名称,则会按照类型进行装配。需要注意的是,如果 name 属性被设置了,那么必须是按照名称进行装配。
@Resource("myBean") private MyBean myBean;
7. mybatis缓存
MyBatis 中的缓存就是说 MyBatis 在执行一次SQL查询或者SQL更新之后,这条SQL语句并不会消失,而是被MyBatis 缓存起来,当再次执行相同SQL语句的时候,就会直接从缓存中进行提取,而不是再次执行SQL命令。
8. 反射以及其意义
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;
这种动态获取的以及动态调用对象的方法的功能称为java语言的反射机制。
反射的应用场合:在编译时根本无法知道该对象或类可能属于哪些类,程序只依靠运行时信息来发现该对象和类的真实信息.
意义:1.增加程序的灵活性,避免将程序写死到代码里。
2.代码简洁,提高代码的复用率,外部调用方便3.对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法
主要用途:
反射最重要的用途就是开发各种通用框架。
https://blog.csdn.net/qq_43473073/article/details/88935183
package cn.yonyong.reflection.testdemo;
interface Fruit { //水果接口
public void eat() ; //吃水果
}
class Apple implements Fruit{ //定义苹果
public void eat() {
System.out.println("**吃苹果。");
}
}
class Orange implements Fruit{
public void eat() {
System.out.println("**吃橘子。");
}
}
class Factory{
public static Fruit getInstance(String className){
Fruit fruit = null ;
try{
fruit = (Fruit) Class.forName(className).newInstance() ;
}catch(Exception e ){
e.printStackTrace() ;
}
return fruit ;
}
}
public class FactoryDemo{
public static void main(String args[]){
//通过工厂类取得接口实例,传入完整的包.类名称
Fruit f = Factory.getInstance("cn.yonyong.reflection.testdemo.Apple") ;
if(f!=null){ //判断是否取得接口实例
f.eat() ;
}
}
}
如果不用反射,那么我们如果再加一个西瓜类,就得在Factory里判断,每添加一个类都要修改一次Factory,但用了反射只用在调用的时候传入完整的类名就可完成。结果:用反射,修改一处代码;不用反射,修改两处代码。
9. linux命令 查看进程 查看文件
查看进程:ps -ef/ax
-e:显示系统内所有进程的信息。与 -A 选项功能相同
-f:使用完整 (full) 的格式显示进程信息,如果只有 ps -e 则输出进程信息的格式和只使用 ps 一样(都只有PID TTY TIME CMD这几项,但是输出信息的内容和ps的不一样)
a:显示当前终端下的所有进程信息,包含其他用户的进程信息。和 x 选项结合使用可以显示系统中所有进程的信息
x:显示当前用户在所有终端下的进程信息
查看文件:lsof命令,可以列出被进程所打开的文件的信息。
cat:从第一行开始显示文本内容(适用于内容较少的)
tac:从最后一行开始显示,是 cat 的逆顺序
more:一页一页的显示文本内容(适用于内容较多的)
less:与 more 类似,但是比 more 更好的是,它可以往前翻页!
head:只看文本的前面几行
tail:只看文本的后面几行
nl:显示文本内容与行号
10. spring中bean的构造器注入?
spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。
依赖注入的方式
依赖注入有3种方式:构造器注入、set注入和注解注入。
www.cnblogs.com/Jason-Xiang/p/5345342.html
11. spring中的bean默认是单例还是多例
Spring容器管理的bean在默认情况下是单例的,也即,一个bean只会创建一个对象,存在内置map中,之后无论获取多少次该bean,都返回同一个对象。
配置多例:多例 scope="prototype" 单例 scope="singleton" (默认方式)
例:<bean id="dog" class="com.dreamguard.domain.Dog" scope="prototype"></bean>
单例模式下的生命周期
bean在单例模式下,spring容器启动时解析xml发现该bean标签后,直接创建该bean的对象存入内部map中保存,此后无论调用多少次getBean()获取该bean都是从map中获取该对象返回,一直是一个对象。此对象一直被Spring容器持有,直到容器退出时,随着容器的退出对象被销毁。
多例模式下的生命周期
bean在多例模式下,spring容器启动时解析xml发现该bean标签后,只是将该bean进行管理,并不会创建对象,此后每次使用 getBean()获取该bean时,spring都会重新创建该对象返回,每次都是一个新的对象。这个对象spring容器并不会持有,什么销毁取决于使用该对象的用户自己什么时候销毁该对象。
12. java设计模式 工厂方法如何实现
14. 银行金额的计算在java中怎么实现比较好
在牵涉到金额的计算时,为了保持高精度的准确性,使用bigDecimal类型.
在使用BigDecimal类来进行计算的时候,主要分为以下步骤:
1、用float或者double变量构建BigDecimal对象。
2、通过调用BigDecimal的加,减,乘,除等相应的方法进行算术运算。
3、把BigDecimal对象转换成float,double,int等类型。
一般来说,可以使用BigDecimal的构造方法或者静态方法的valueOf()方法把基本类型的变量构建成BigDecimal对象。
1 BigDecimal b1 = new BigDecimal(Double.toString(0.48));
2 BigDecimal b2 = BigDecimal.valueOf(0.48);
对于常用的加,减,乘,除,BigDecimal类提供了相应的成员方法。
1 public BigDecimal add(BigDecimal value); //加法
2 public BigDecimal subtract(BigDecimal value); //减法
3 public BigDecimal multiply(BigDecimal value); //乘法
4 public BigDecimal divide(BigDecimal value); //除法
进行相应的计算后,我们可能需要将BigDecimal对象转换成相应的基本数据类型的变量,可以使用floatValue(),doubleValue()等方法。
15. 线程如何返回一个值
一、通过变量和方法返回数据
二、通过回调函数返回数据
三、实现 Callable 接口
isDone:利用state变量判断call方法有没有被执行
get:如果call方法已经执行完就返回call方法的返回值,如果call方法没有执行完就一直阻塞
https://blog.csdn.net/qq_18505715/article/details/78726164
https://blog.csdn.net/qq877728715/article/details/107003268/