2019/4/13
1. 手写三种单例模式
双重校验锁:支持延迟加载,多线程安全,效率高
public class Singleton{
private static Singleton singleton;
private Singleton(){
}
public static Singleton getInstance(){
if(singleton == null){
synchronized(Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
懒汉式:支持延迟加载,多线程安全,但是效率不高
public class Singleton{
private static Singleton singleton;
private Singleton(){
}
public static synchronized Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
饿汉式:不支持延迟加载,多线程安全,效率高
public class Singleton{
private static Singleton singleton = new Singleton();
private Singleton(){
}
public static Singleton getInstace(){
return singleton;
}
}
2. 事务是什么
在数据库中,事务是指一组逻辑操作单元(一组sql语句),要么全部成功,完成提交;要么全部失败,事务回滚。
3. 事务的四大特性(ACID)
- 原子性(Atomicity):是指事务是一个不可分割的工作单位,事务中的操作要么全部成功,
要么全部失败。 - 一致性(Consistency):是指事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
- 隔离性(Isolation):是指一个事务的执行不能被其他事务干扰。
- 持久性(Durability):一个事务一旦被提交,它对数据库中数据的改变就是永久性的
扩展知识:事务的 ACID 是通过 InnoDB 日志和锁来保证。事务的隔离性是通过数据库锁的机制实现的;持久性通过 Redo Log(重做日志)来实现,记录的是新数据的备份;原子性和一致性通过 Undo Log(回滚日志)来实现,操作前备份原始数据。
4. 如何让多个 SQL 语句作为一个事务执行
1)执行语句前调用 Connection 对象的 setAutoCommit(false),以取消自动提交事务
2)在所有的 SQL 语句都成功执行后,调用 commit()方法提交事务
3)在出现异常时,调用 rollback()方法回滚事务。
5.什么是脏读、不可重复读、虚读(幻读)
1)脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。
例如:用户A向用户B转账100元,对应SQL命令如下:
update account set money = money + 100 where name=’B’; (此时A通知B)
update account set money = money - 100 where name=’A’;
当只执行第一条SQL时,A通知B查看账户,B发现确实钱已到账(此时即发生了脏读),无论第二条sql是否执行,只要该事务不提交,所有操作都将回滚,B以后再次查看账户时就会发现钱并没有转。
2)不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
例如:事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发生了不可重复读。
不可重复读和脏读的区别:脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。(某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主。但在另一些情况下就有可能发生问题,例如对于同一个数据A和B依次查询就可能不同了)
3)幻读是事务非独立执行时发生的一种现象。
例如:事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。
三者的区别:幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体。
6. 事务的隔离级别
1)Serializable (串行化):以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待。隔离级别最高,执行效率最低,可避免脏读、不可重复读、幻读的发生。
2)Repeatable read (可重复读):可避免脏读、不可重复读的发生。
3)Read committed (读已提交):一个事务不可以操作另外一个未提交的事务,可避免脏读的发生。
4)Read uncommitted (读未提交):一个事务可以操作另外一个未提交的事务,隔离级别最低,并发性能最高,任何情况都无法保证。
扩展知识:MySQL数据库中,支持上面四种隔离级别,默认的为Repeatable read (可重复读);Oracle数据库中,只支持Serializable (串行化)级别和Read committed (读已提交)这两种级别,默认的为Read committed级别。
7. 事务的传播行为
事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。
例如:methodA事务方法调用methodB事务方法时,methodB是继续在调用者methodA的事务中运行,还是为自己开启一个新事务运行,这就是由methodB的事务传播行为决定的。
1)PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务,则开启一个新的事务。
2)PROPAGATION_SUPPORTS:如果存在一个事务,则支持当前事务。如果没有事务,则非事务的执行。
3)PROPAGATION_MANDATORY:如果存在一个事务,则支持当前事务。如果没有事务,则抛出异常。
4)PROPAGATION_REQUIRES_NEW:使用PROPAGATION_REQUIRES_NEW,需要使用 JtaTransactionManager作为事务管理器。 它会开启一个新的事务。如果一个事务已经存在,则先将这个存在的事务挂起。
5)PROPAGATION_NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。需要使用JtaTransactionManager作为事务管理器。
6)PROPAGATION_NEVER:总是非事务地执行,如果存在一个活动事务,则抛出异常。
7)PROPAGATION_NESTED:如果事务存在,则运行在一个嵌套的事务中。 如果没有事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。
扩展知识:详细看个人收藏的一篇博客:看完就明白_spring事务的7种传播行为
8. 本地事务数据库断电,怎么保证数据一致性(怎么恢复)
使用SQL Server来举例,我们知道我们在使用 SQL Server 数据库是由两个文件组成的,一个数据库文件和一个日志文件,通常情况下,日志文件都要比数据库文件大很多。数据库进行任何写入操作的时候都是要先写日志,同样的道理,我们在执行事务的时候数据库首先会记录下这个事务的redo操作日志,然后才开始真正操作数据库,在操作之前首先会把日志文件写入磁盘,那么当突然断电的时候,即使操作没有完成,在重新启动数据库时候,数据库会根据当前数据的情况进行undo回滚或者是redo前滚,这样就保证了数据的强一致性。
9. 什么是分布式事务
分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简单言之就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。本质上来说,就是为了保证不同数据库的数据一致性。
2019/4/14
10. 分布式事务产生的原因
1)数据库分库分表
2)应用SOA化
本质就是要操作的数据库变多
11. 分布式事务的应用场景,举2个例子
1)支付:最经典的场景就是支付了,一笔支付,是对买家账户进行扣款,同时对卖家账户进行加钱,这些操作必须在一个事务里执行,要么全部成功,要么全部失败。而对于买家账户属于买家中心,对应的是买家数据库,而卖家账户属于卖家中心,对应的是卖家数据库,对不同数据库的操作必然需要引入分布式事务。
2)在线下单:买家在电商平台下单,往往会涉及到两个动作,一个是扣库存,第二个是更新订单状态,库存和订单一般属于不同的数据库,需要使用分布式事务保证数据一致性。
12. 什么是CAP理论
数据库的 ACID 四大特性,已经无法满足分布式事务,这时就有新的理论出现,CAP定理(又称布鲁尔定理)是由加州大学伯克利分校Eric Brewer教授提出来的,他指出WEB服务无法同时满足以下3个属性:
C (一致性):对某个指定的客户端来说,读操作能返回最新的写操作。【对于数据分布在不同节点上的数据来说,如果在某个节点更新了数据,那么在其他节点如果都能读取到这个最新的数据,那么就称为强一致,如果有某个节点没有读取到,那就是分布式不一致】
A (可用性):非故障的节点在合理的时间内返回合理的响应(不是错误和超时的响应)。【合理的时间指的是请求不能无限被阻塞,应该在合理的时间给出返回。合理的响应指的是系统应该明确返回结果并且结果是正确的,这里的正确指的是比如应该返回 50,而不是返回 40】
P (分区容错性):当出现网络分区后,系统能够继续工作。【打个比方,这里集群有多台机器,有台机器网络出现了问题,但是这个集群仍然可以正常工作】
扩展知识:选择CA放弃P,当发生分区现象时,为了保证一致性,这个时候必须拒绝请求,但是 A 又不允许,所以分布式系统理论上不可能选择 CA 架构,只能选择 CP 或者 AP 架构。
CP:放弃可用性,追求一致性和分区容错性,ZooKeeper 其实就是追求的强一致。
AP:放弃一致性(这里说的一致性是强一致性),追求分区容错性和可用性,这是很多分布式系统设计时的选择,BASE也是根据AP来扩展。
注意:CAP 理论中是忽略网络延迟,也就是当事务提交时,从节点 A 复制到节点 B 没有延迟,但是在现实中这个是明显不可能的,所以总会有一定的时间是不一致。
13. 什么是BASE理论
BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent (最终一致性)三个短语的缩写,是对 CAP 中 AP 的一个扩展。
基本可用:分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用。
软状态:允许系统中存在中间状态,这个状态不影响系统可用性,这里指的是 CAP 中的不一致。
最终一致:最终一致是指经过一段时间后,所有节点数据都将会达到一致。
【BASE 解决了 CAP 中理论没有网络延迟,在 BASE 中用软状态和最终一致,保证了延迟后的一致性。BASE 和 ACID 是相反的,它完全不同于 ACID 的强一致性模型,而是通过牺牲强一致性来获得可用性,并允许数据在一段时间内是不一致的,但最终达到一致状态】
14. 什么是XA协议
XA是一个分布式事务协议,由Tuxedo提出。XA中大致分为两部分:事务管理器和本地资源管理器。其中本地资源管理器往往由数据库实现,比如Oracle、DB2这些商业数据库都实现了XA接口,而事务管理器作为全局的调度者,负责各个本地资源的提交和回滚。
15. 分布式事务的解决方案
1)两阶段提交(2PC):基于XA协议的两阶段提交实现分布式事务的原理如下:
阶段一:事务管理器要求每个涉及到事务的数据库预提交(precommit)此操作,并反映是否可以提交。
阶段二:事务协调器要求每个数据库提交数据,或者回滚数据。
优点:尽量保证了数据的强一致,实现成本较低,在各大主流数据库都有自己实现
缺点:
① 单点问题:事务管理器在整个流程中扮演的角色很关键,如果其宕机,比如在第一阶段已经完成,在第二阶段正准备提交的时候事务管理器宕机,资源管理器就会一直阻塞,导致数据库无法使用。
② 同步阻塞:在准备就绪之后,资源管理器中的资源一直处于阻塞,直到提交完成,释放资源。
③ 数据不一致:两阶段提交协议虽然为分布式数据强一致性所设计,但仍然存在数据不一致性的可能。比如:在第二阶段中,假设协调者发出了事务 Commit 的通知,但是因为网络问题该通知仅被一部分参与者所收到并执行了 Commit 操作,其余的参与者则因为没有收到通知一直处于阻塞状态,这时候就产生了数据的不一致性。
2)补偿事务(TCC):TCC 其实就是采用的补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。它分为三个阶段:
阶段一:Try 阶段主要是对业务系统做检测及资源预留
阶段二:Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。
阶段三:Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。
举个例子:Bob要向Smith转账100元,思路大概是:我们有一个本地方法,里面依次调用
① 首先在 Try 阶段,要先调用远程接口把 Smith 和 Bob 的钱给冻结起来。
② 在 Confirm 阶段,执行远程调用的转账的操作,转账成功进行解冻。
③ 如果第2步执行成功,那么转账成功,如果第二步执行失败,则调用远程冻结接口对应的解冻方法 (Cancel)。
优点:相较于2PC,它解决了单点问题(由主业务方发起并完成这个业务活动。业务活动管理器也变成多点,引入集群);解决同步阻塞(引入超时,超时后进行补偿,并且不会锁定整个资源,将资源转换为业务逻辑形式,粒度变小)
缺点:Confirm阶段和Cancel阶段都有可能失败,TCC属于应用层的一种补偿方式,所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。
3)本地消息表(异步确保):本地消息表这种实现方式应该是业界使用最多的,其核心思想是将分布式事务拆分成本地事务进行处理,这种思路是来源于ebay
基本思路就是:
① 消息生产方,需要额外建一个消息表,并记录消息发送状态。消息表和业务数据要在一个事务里提交,也就是说他们要在一个数据库里面。然后消息会经过MQ发送到消息的消费方。如果消息发送失败,会进行重试发送。
② 消息消费方,需要处理这个消息,并完成自己的业务逻辑。此时如果本地事务处理成功,表明已经处理成功了,如果处理失败,那么就会重试执行。如果是业务上面的失败,可以给生产方发送一个业务补偿消息,通知生产方进行回滚等操作。
③ 生产方和消费方定时扫描本地消息表,把还没处理完成的消息或者失败的消息再发送一遍。
【如果有靠谱的自动对账补账逻辑,这种方案还是非常实用的。这种方案遵循BASE理论,采用的是最终一致性,笔者认为是这几种方案里面比较适合实际业务场景的,即不会出现像2PC那样复杂的实现(当调用链很长的时候,2PC的可用性是非常低的),也不会像TCC那样可能出现确认或者回滚不了的情况】
优点:避免了分布式事务,实现了最终一致性。
缺点:消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。
4)MQ 事务消息:部分第三方的MQ是支持事务消息的,比如RocketMQ,他们支持事务消息的方式类似于采用的二阶段提交(RabbitMQ 和 Kafka 都不支持)
RocketMQ 中间件为例,其思路大致为:
第一阶段:Prepared消息,会拿到消息的地址
第二阶段:执行本地事务
第三阶段:通过第一阶段拿到的地址去访问消息,并修改状态
也就是说在业务方法内要向消息队列提交两次请求,一次发送消息和一次确认消息。如果确认消息发送失败了RocketMQ会定期扫描消息集群中的事务消息,这时候发现了Prepared消息,它会向消息发送者确认,所以生产方需要实现一个check接口,RocketMQ会根据发送端设置的策略来决定是回滚还是继续发送确认消息。这样就保证了消息发送与本地事务同时成功或同时失败。
优点: 实现了最终一致性,不需要依赖本地数据库事务。
缺点: 实现难度大,主流MQ不支持,RocketMQ事务消息部分代码也未开源。
5)Sagas 事务模型:核心思想是将长事务拆分为多个本地短事务,由 Saga 事务协调器协调,如果正常结束那就正常完成,如果某个步骤失败,则根据相反顺序一次调用补偿操作。
16. Vector & ArrayList的区别
1)Vector的方法都是同步的(Synchronized),是线程安全的,而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。
2)当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,所以,ArrayList更有利于节约内存空间。
17. hashMap和hashtable的区别
map是一个键值对的存储接口,Map有两个具体的实现类是HashMap和HashTable,HashMap多线程不安全,HashTable是多线程安全的,所以HashMap的效率高于HashTable;HashMap允许空值空键,HashTable不许空值空键
18. map的底层是什么
map的底层,是通过数组加链表的形式来进行存放的,比如要存储一对<key,value>,我们会根据key的hashcode()值与数组的长度进行取余,然后根据余数存放到数组对应的位置上;通过key取值也是一样,我们也是根据key的hashcode()与数组长度取余,然后根据余数找到数组上相对应的位置。这里存在一个问题,就是余数会有重复的情况,我们通过加上一个链表来解决。通过key取到链表之后,我们就将链表进行循环,然后相比较来查询出相对应的值。
19. String,Stringbuffer,Stringbuilder 的区别
首先这些都是用来定义字符串的;String是一个字符串常量,被final修饰,长度不可变,拼接字符串的时候使用 +=,每一次拼接字符串都会是一个新的内存空间;Stringbuffer是字符串变量,存在缓存区,长度是可变的,通过append来追加即可,不需要开辟新的内存空间,多线程安全;Stringbuilder 也是字符串变量,和Stringbuffer差不多,但是没有同步锁,多线程不安全;(大数据量拼接的时候才会使用Stringbuffer和Stringbuilder )
20. Set,list,conllection,conllections的区别
List 和set都是接口,都继承自接口conllection;List是一个有序可重复的集合,而set是无序不可重复的集合;conllection是集合的顶层接口;conllections是一个封装了许多操作集合的静态化方法的工具类,由于构造方法是私有的,不能实例化;List接口的实现类有arraylist ,linkedlist 和vector,arraylist和vector都是基于数组实现的,所以查询速度快,增删慢,linkedlist 是基于链式存储结构,查询速度比前面两个慢。
21. HashMap的底层原理
HashMap底层就是数组+链表,新建一个HashMap时,会初始化一个数组。Entry(key-value)就是数组中的元素,它持有一个指向下一个元素的引用,这就构成了链表。HashMap 底层采用一个Entry[] 数组来保存所有的 key-value 对,要存储一个 Entry 对象时,根据hash算法来决定其在数组中的存储位置,再根据equals方法决定其在该数组位置上的链表中的存储位置;取Entry对象也是一样的方法;HashMap默认是构建一个初始容量为 16,负载因子为 0.75 的容器。默认情况下,数组大小为16,当HashMap中元素个数超过12时,数组的大小会扩大一倍,然后重新计算每个元素在数组中的位置,这是一个非常消耗性能的操作,所以如果我们已经预知HashMap中元素的个数,预设元素的个数能够有效的提高HashMap的性能。
22. 堆和栈的区别
堆是所有线程共享的内存区域,栈是运行时线程私有的内存区域;堆所占的内存区域要比栈大;堆用来存放对象实例,栈存放基本数据类型和引用数据类型。
23. ArrayList和LinkedList的区别
ArrayList底层是基于数组实现的,特点是查询效率高(每次只需要一个偏移量就可查到),增删效率低(数组中间插入数据,插入过程是以迭代的方式,让它后面的每一项依次往后挪),线程不安全; LinkedList底层用双向循环链表实现,双向链表的存储特点是不挨着,它存储的每个元素分为三段:上一项的地址、下一项的地址、元素的内容,特点是:增删效率高(最多只会影响两个元素),查询效率低 (元素全部过一遍)。
24. 运行时异常与一般异常有何异同
定义不同:运行时异常都是RuntimeException类及其子类异常;一般异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。
处理方法不同:运行时异常是不检查异常,程序中可以选择捕获处理,也可以不处理;一般异常,JAVA编译器强制要求用户必需对出现的这些异常进行catch并处理,否则程序就不能编译通过。
发生原因不同:运行时异常一般是由程序逻辑错误引起的,程序应该从逻辑角度避免这类异常的发生。面对这种异常只能自己去写catch块去处理可能的异常。
25. 常见的运行时异常有哪些
ArithmeticException——由于除数为0引起的异常;
ArrayStoreException——由于数组存储空间不够引起的异常;
ClassCastException—一当把一个对象归为某个类,但实际上此对象并不是由这个类 创建的,也不是其子类创建的,则会引起异常;
IllegalMonitorStateException——监控器状态出错引起的异常;
NegativeArraySizeException——一数组长度是负数,则产生异常;
NullPointerException——一程序试图访问一个空的数组中的元素或访问空的对象中的 方法或变量时产生异常;
OutofMemoryException——用new语句创建对象时,如系统无法为其分配内存空 间则产生异常;
SecurityException——由于访问了不应访问的指针,使安全性出问题而引起异常;
IndexOutOfBoundsExcention——由于数组下标越界或字符串访问越界引起异常;
IOException——由于文件未找到、未打开或者I/O操作不能进行而引起异常;
ClassNotFoundException——未找到指定名字的类或接口引起异常;
CloneNotSupportedException——一程序中的一个对象引用Object类的clone方法,但此对象并没有连接Cloneable接口,从而引起异常;
InterruptedException——一当一个线程处于等待状态时,另一个线程中断此线程,从 而引起异常
NoSuchMethodException——所调用的方法未找到,引起异常;
Illega1AccessExcePtion——一试图访问一个非public方法;
StringIndexOutOfBoundsException——访问字符串序号越界,引起异常;
ArrayIndexOutOfBoundsException——一访问数组元素下标越界,引起异常;
NumberFormatException——字符的UTF代码数据格式有错引起异常;
IllegalThreadException——一线程调用某个方法而所处状态不适当,引起异常;
FileNotFoundException——未找到指定文件引起异常;
EOFException——未完成输入操作即遇文件结束引起异常。
26. 手写一个冒泡排序算法
public static void bubbleSort(int[] arr){
int[] arr = {12,23,34,56,56,56,78};
for(int i = 0; i < arr.length-1; i++){
for(int j =0;j<arr.length-i-1;j++){ // -1为了防止溢出
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
27. 抽象类特点
① 一个类拥有抽象方法, 那么该类就必须被定义为抽象类,通过abstract声明;
② 抽象类允许普通属性,普通方法和抽象方法(使用abstract修饰的方法)存在;
③ 抽象类不能被实例化;
④ 抽象类必须被继承(extends),并且实现里面的所有抽象方法才能被使用。
28. 接口的特点
① 接口是一个抽象类型,是抽象方法的集合,通过interface来声明,只允许常量和抽象方法存在;
② 一个类通过继承接口的方式,从而来继承接口的抽象方法;
③ 接口无法被实例化,但是可以被实现,一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类;
④ 接口可以实现多继承(继承多个接口)。
29. 接口与抽象类的区别
① 抽象类可以有构造方法,接口中不能有构造方法;
② 抽象类中可以有普通成员变量和普通方法,接口中没有普通成员变量,所有方法必须都是抽象方法;
③ 抽象类中的抽象方法的访问类型可以是public,protected和默认类型,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型;
④ 抽象类中可以包含静态方法,接口中不能包含静态方法;
⑤ 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型;
⑥ 一个类可以实现多个接口,但只能继承一个抽象类。
30. 方法重写和重载的区别
① 方法重写的方法名,参数列表和返回值必须相同;方法重载的方法名相同,参数列表不同(个数,类型,顺序),和返回值无关
② 子类重写方法的访问修饰符的限制一定要大于被重写方法的访问修饰符(比如父类是public,子类必须是public,不能比父类小);重载可以有不同的访问修饰符
③ 子类重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常;重载可以抛出不同异常
2019/5/12
31. BS和CS的区别以及优缺点
C/S(Client/Server):客户/服务器模式。服务器通常采用高性能的PC、工作站或小型机,并采用大型数据库系统,客户端需要安装专用的客户端软件。
B/S(Brower/Server):浏览器/服务器模式,客户机上只要安装一个浏览器,浏览器通过Web Server 同数据库进行数据交互。
C/S的特点:客户端响应速度快,客户端的计算机电脑配置要求较高,客户端都必须安装和配置客户端软件,客户端需要升级程序,也可以采用自动升级,一般面向相对固定的用户群,程序更加注重流程,它可以对权限进行多层次校验,提供了更安全的存取模式,对信息安全的控制能力很强。
B/S的特点:客户端的计算机电脑配置要求较低,使用浏览器访问,易推广,可以在任何地方进行操作而不用安装任何专门的软件。
32. JDK1.8的新特性
1、允许接口中有默认方法实现
2、函数式接口
3、接口里允许使用方法体
4、允许::调用方法
5、加入全新的日期API(这些功能都放在java.time包下)提出了时间的加减乘除?
6、允许在类和接口上写注解
33. get和post请求的区别
1、get请求用来从服务器上获得资源,而post是用来向服务器提交数据;
2、get请求将参数添加到url上,post是将表单中的数据放在HTTP协议的请求头或消息体中,所以post请求更加安全
3、get请求传输的数据要受到url长度限制(1024字节),而post可以传输大量的数据;
34. &和&&的区别
&&为短路与,&不是短路与。另外&可以做为整数的位运算符
35. "=="和equals方法的区别
“==” 比较的是内存地址 ;equals是方法,默认是用内存地址比较,重写后,主要是用来比较两侧的对象的值是否相同;" == "可以两侧都为null,但equals左侧的引用指向的对象不能空,不然有NullPointerException;
36. Integer与int的区别
int是java提供的8种原始数据类型之一,意思整型,占用4字节;Integer是java为int提供的封装类,是引用数据类型;int的默认值为0,而Integer的默认值为null
37. 面向对象的特征有哪些
1、封装,隐藏内部实现,只暴露公共行为
2、继承,提高代码的重用性
3、多态,体现现实生活中相似对象的差异性
4、抽象,抽取现实世界中相似对象的共同点
2019/5/24
38. JAVA中的几种基本数据类型是什么,各自占用多少字节。
数值型:{整数型:byte 1字节,short 2字节,int 4字节,long 8字节;浮点型:float 4字节,double 8字节};字符型:char 2字节;布尔型:boolean 1字节
39. String类能被继承吗,为什么?
不能,因为String类有final修饰符,而final修饰的类是不能被继承的。
40. 讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,当new的时候,他们的执行顺序
父类的静态数据—>父类的静态代码块—>子类的静态数据—>子类的静态代码块—>父类字段—>父类构造函数—>子类字段—>子类构造函数
41. 用过哪些Map类,都有什么区别,HashMap是线程安全的吗,并发下使用的Map是什么,他们的内部原理分别是什么,比如存储方式,hashcode,扩容,默认容量等。
HashMap、HashTable、TreeMap、ConcurrentHashMap、LinkedHashMap