1.Java基础
string和stringbuffer,stringbuffer和stringbudiler区别
string数值内容是不可变的,stringbuffer数值内容是可变的,stringbuffer线程是非安全的,stringbudiler线程是安全的
int和integer区别
int是java提供的原始数据类型,integer是java为int提供的封装数据类型,int默认值是0,integer默认值为null,即integer可以区分未赋值和值为0,int不能区分。
静态变量和实例变量的区别
语法定义上:静态变量要加static,实例变量不用。
实例变量是某个对象的属性,必须创建实例对象,才能使用实例变量。静态变量不属于某个实例变量,是属于类的。
overload和override的区别,overloaded的方法是否可以改变返回值类型
overload是重载,重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
override是重写,表示子类中的方法可以和父类的某个方法的名称和参数完全相同,通过子类创建实例对象调用这个方法,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了。overloaded的方法不可以改变返回值类型
接口可以继承接口,抽象类可以实现接口,抽象类可以继承具体类,抽象类中可以有静态main方法
构造器不能被继承,所以不能被重写,但可以重载
抽象类和接口的区别
1.抽象类可以有构造方法,接口没有
2.抽象类有普通成员变量,接口没有,
3.抽象类可以包含非抽象方法,接口中的方法都是抽象的
4.抽象类的访问类型可以是public,protected,接口只能是public
5.抽象类可以包含静态方法,接口没有静态方法
6.一个类可以实现多个接口,但只能继承一个抽象类
java实现多态的机制:
靠的是父类和接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才多态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法
什么是内部类,
内部类就是在一个类的内部定义的类,内部类不能定义静态成员,内部类可以直接访问外部类中的成员变量,内部类可以定义在外部类的方法外面。
string s = new String("xyz");创建了几个String object?两者之间有什么区别?
两个对象,一个是“xyx”,一个是指向“xyx”的引用对象s
final,finally,finalize的区别
final:用于声明属性,方法和类
finally是异常处理语句结构的一部分,表示总是执行
finalize:是object类的一个方法,在垃圾回收器执行的时候会调用被回收对象的此方法
error和exception区别:
error表示恢复不是不可能但很困难的情况下出现的一种严重问题,不可能指望程序能处理这样的情况,exception表示一种设计或实现问题,一般程序运行正常,不会出现这种情况
java中的异常处理机制的简单原理与应用
java对异常进行了分类,不同的异常用不同的java类表示,所有异常的根类是java.lang.Throwable.。
Throwable有派生了两个类,error和exception
常见的5个RuntimeException
NullPointerExeption(空指针异常),IndexOutBoundsException(下标越界异常),classCastException(类型强转异常),NumberFormatException(数字格式异常),SecurityException(安全异常)
6、多线程有几种实现方法?同步有几种实现方法?
多线程有两种实现方法,分别是继承Thread类与实现Runnable接口
同步的实现方面有两种,分别是synchronized,wait与notify
wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException(中断异常)异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
7、启动一个线程是用run()还是start()? .
启动一个线程是调用start()方法,使线程就绪状态,以后可以被调度为运行状态,一个线程必须关联一些具体的执行代码,run()方法是该线程所关联的执行代码。
8、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
分几种情况:
1. 其他方法前是否加了synchronized关键字,如果没加,则能。
2. 如果这个方法内部调用了wait,则可以进入其他synchronized方法。
3. 如果其他个方法都加了synchronized关键字,并且内部没有调用wait,则不能。
4. 如果其他方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是this。
9、线程的基本概念、线程的基本状态以及状态之间的关系
一个程序中可以有多条执行线索同时执行,一个线程就是程序中的一条执行线索,每个线程上都关联有要执行的代码,即可以有多段程序代码同时运行,每个程序至少都有一个线程,即main方法执行的那个线程。如果只是一个cpu,它怎么能够同时执行多段程序呢?这是从宏观上来看的,cpu一会执行a线索,一会执行b线索,切换时间很快,给人的感觉是a,b在同时执行,好比大家在同一个办公室上网,只有一条链接到外部网线,其实,这条网线一会为a传数据,一会为b传数据,由于切换时间很短暂,所以,大家感觉都在同时上网。
状态:就绪,运行,synchronize阻塞,wait和sleep挂起,结束。wait必须在synchronized内部调用。
调用线程的start方法后线程进入就绪状态,线程调度系统将就绪状态的线程转为运行状态,遇到synchronized语句时,由运行状态转为阻塞,当synchronized获得锁后,由阻塞转为运行,在这种情况可以调用wait方法转为挂起状态,当线程关联的代码执行完后,线程变为结束状态。
sleep:使一个正在运行的线程处于睡眠状态
notify:唤醒一个处于等待状态的线程;
Allnotity:唤醒所有处于等待状态的线程
arraylist和vector区别
都实现了list接口,都是有序的
vector线程是安全的,arraylist线程是不安全的
vector数据增长是原来的一倍,arraylist是数据增长是原来的0.5倍
hashmap和hashable的区别
hashmap是hashable的轻量级实现,hashmap允许空键值,hashable不允许
hashable的方法是同步的,hashmap是不同步的
list和map,set的区别
list是存储单列数据的集合,map是存储双列数据集合;list中存储的数据是有序的,允许重复,map存储的数据是没有顺序的,键不能重复,值能重复.set也是存储单列数据的集合,数据不允许重复
HashMap实现原理
HashMap是数组+链表实现的,既然用到hash散列,那么肯定不可避免的会出现冲突问题,HashMap解决冲突的方法是拉链法,因为这里有用到数组,那么当容量不足的时候就需要进行扩容操作了,在HashMap中有个术语叫冲突,当冲突几率越来越高的时候就需要进行扩容操作了,那什么情况就叫冲突几率高呢?就是当我们的数组元素个数超过了数组原先大小*装填因子,默认情况下的装填因子是0.75,扩容有个坏处就是每次扩容之后都必须重新计算原先数组中的元素在新数组中的存储位置,这点比较消耗性能,所以一般情况下如果你已经能够确定最大需要多大散列范围的数组的话,建议还是能够指定大小;
接下来就是HashMap的put和set原理了:
put操作和set操作进行操作的对象是主要是key,如果你查看源码的话会发现value只是跟着key的步伐在走而已,并没有实质性的进行操作,对于put操作,首先会计算出当前key对应的hash值,接着找到计算出来的hash值在数组中的下标位置,查看该下标位置处对应的链表是否为null,为空的话直接将当前键值对插入到该链表首位,不会执行当前key对象的equals方法;如果下标位置处对应的链表不为null的话,会通过for循环来通过key的equals方法来查看这个链表中有没有与当前键值相等的键值对Entry存在,有的话,会用当前值替换原先这个键值对的value值,遍历结束如果不存在的话,会将当前键值对插入到链表的头部,这个就是put过程了;
get操作过程思想可以借助于put过程,首先会计算出当前key值的hash值,接着找到此hash值在数组中的位置,找到这个位置对应的链表,接着通过for循环遍历这个链表,遍历过程中调用equals方法查看有没有等于当前key的键值对存在,有的话直接返回这个键值对对应的value值即可;
HashMap注意点:
HashMap是非线程安全的,也就是说你在使用迭代器的过程中有其他线程修改了map的话,你的程序可能会抛出ConcurrentModificationException异常,这就是我们常见的fail-fast机制了,原因在于我们在调用HashMap的迭代器里面的每个方法的时候,都会通过判断原先map被修改次数和当前被修改次数是否相等,不等的话直接就抛出了ConcurrentModificationException异常了,这点在ArrayList里面使用迭代器也会出现,具体解决方法就是使用ConcurrentHashMap代替HashMap了;
HashMap是允许你的键或者值为null的;
HashMap是不能保证随着时间的推移,你里面元素之间的顺序不变,原因就在于map中存放hash值的数组在扩容的时候会重新计算原先元素在新数组中位置的;
垃圾回收器的基本原理
GC,当程序员创建对象时,GC就开始监控这个对象的地址,大小,以及使用情况,GC采用有向图的记录方式和管理堆中的所有对象,通过这种方式确定哪些是“可达的”,哪些是 “不可达的”。当GC确定哪些是不可达的,GC就回收这些内存空间。程序员可以手动执行System.gc(),通知GC回收资源
collection和collections的区别
collection是集合类的上级接口,继承与他的接口主要有set和list
collections是针对集合类的一个帮助类
&和&&区别
&和&&的区别?①&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。 ②&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,例如,对于if(str != null && !str.equals(“ ”))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。If(x==33 & ++y>0) y会增长,If(x==33 && ++y>0)不会增长 ③&还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如,0x31 & 0x0f的结果为0x01。 |
"=="和equals方法究竟有什么区别?
①==比较的是值,equals比较的是地址值
②一般我们会重写equals让它按照我们的意愿去比较相关属性,而不是单纯的比较地址值。
hashmap和hashable的区别
hashmap是hashable的轻量级实现,hashmap允许空键值,hashable允许将null作为一个entry的key或者value
throw和throws的区别
throw用于主动抛出java.lang.Throwable 类的一个实例化对象,意思是说你可以通过关键字 throw 抛出一个 Error 或者 一个Exception,如:throw new IllegalArgumentException(“size must be multiple of 2″), 而throws 的作用是作为方法声明和签名的一部分,方法被抛出相应的异常以便调用者能处理。Java 中,任何未处理的受检查异常强制在 throws 子句中声明。
关于序列化
Java 中,Serializable 与 Externalizable 的区别
Serializable 接口是一个序列化 Java 类的接口,以便于它们可以在网络上传输或者可以将它们的状态保存在磁盘上,是 JVM 内嵌的默认序列化方式,成本高、脆弱而且不安全。Externalizable 允许你控制整个序列化过程,指定特定的二进制格式,增加安全机制。
关于JVM
JVM特性
平台无关性. Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用模式Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。
简述堆和栈的区别
VM 中堆和栈属于不同的内存区域,使用目的也不同。栈常用于保存方法帧和局部变量,而对象总是在堆上分配。栈通常都比堆小,也不会在多个线程之间共享,而堆被整个 JVM 的所有线程共享。
简述JVM内存分配
基本数据类型比变量和对象的引用都是在栈分配的
堆内存用来存放由new创建的对象和数组
类变量(static修饰的变量),程序在一加载的时候就在堆中为类变量分配内存,堆中的内存地址存放在栈中
实例变量:当你使用java关键字new的时候,系统在堆中开辟并不一定是连续的空间分配给变量,是根据零散的堆内存地址,通过哈希算法换算为一长串数字以表征这个变量在堆中的"物理位置”,实例变量的生命周期--当实例变量的引用丢失后,将被GC(垃圾回收器)列入可回收“名单”中,但并不是马上就释放堆中内存
局部变量: 由声明在某方法,或某代码段里(比如for循环),执行到它的时候在栈中开辟内存,当局部变量一但脱离作用域,内存立即释放
sleep和wait区别
sleep是线程类的方法,导致此线程暂停执行指定时间,给执行机会给其他线程
jsp9个内置对象
request
respone
pageContext
session
application
out
config
page
exception
两种跳转方式是什么?有什么区别
分别是:
<jsp:include page=include.jsp flush=true>
<jsp:forword page=nextpage.jsp/>
前者页面不会跳转到include所指页面,只是显示该页结果,相当于函数调用;后者页面完全转向新页面,不会再回来,相当于go to
MVC各个部分都有哪些技术实现,如何实现
MVC即model-view-controller的缩写,model代表的是应用的业务逻辑(通过javaBean,EJB实现),VIEW是应用的表示面(由JSP页面产生),controller是提供应用的处理过程控制(一般是一个servlet)
wait是object类的方法,对此对象调用wait方法导致本线程放弃对象锁
overload和overrride的区别,overloaded的方法是否可改变返回值类型
override是重写:方法名称,参数个数,类型,顺序,返回值类型都必须是和父类方法一致
overload重载:方法名称不变,其余的都是可以变更的,同一方法名,不同的方法参数或返回值
overloaded可以改变返回值类型
error和exception的区别
error表示恢复不是不可能但很困难的情况下的一种严重问题,比如内存溢出,不可指望程序处理这种问题的情况
exception表示一种设计或实现问题,它表示如果程序正常运行,从不会发生的情况
同步和异步区别
如果数据在线程间共享,例如正在写的数据以后可能被另一线程读到,或者正在读的数据被另一个线程写过,,那么这些数据就是共享数据,必须用同步存取
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步
抽象类和接口的区别
抽象类和接口都不能实例化,而且都可以包含抽象方法
数据库连接池
答:数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态的对池中的连接进行申请、使用、释放;
(1)程序初始化时创建连接池
(2)使用时向连接池申请可用连接
(3)使用完毕,将连接返还给连接池
(4)程序退出时,断开所有的连接,并释放资源
设计模式
1.工厂模式
2.抽象工厂模式
3.单例模式
4.建造者模式
1、单例模式的几种写法
懒汉模式
public class Singleton {
private static Singleton instance = null;
private Singleton(){}
public static synchronized Singleton getInstance(){
//如果还没有被实例化过,就实例化一个,然后返回
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
饿汉模式
public class Singleton {
//类加载的时候instance就已经指向了一个实例
private static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
双重检验锁
public class Singleton {
private static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
synchronized (Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
静态内部类:因为JAVA静态内部类的特性,加载的时候不会加载内部静态类,使用的时候才会加载,而使用的时候类加载又是线程安全的,这就完美达到了效果;
public class Singleton {
private static class SingletonHolder{
private static Singleton instance = new Singleton();
}
private Singleton(){}
public static Singleton getInstance(){
return SingletonHolder.instance;
}
}
枚举:
public enum Singleton {
INSTANCE;
}
servlet的生命周期:
1.加载和实例化
2.初始化
3.请求处理
4.服务终止
servlet容器负责加载和实例化servlet,在servlet实例化之后,容器将调用servlet的init()方法初始化这个对象,servlet容器调用service()方法对请求进行处理,在调用service()方法调用之前,init()方法必须成功执行,当容器检测到一个servlet实例应该从服务中移除时,容器调用destroy()方法
mybatis和hibernate的区别
1.hibernate是自动的,mybatis是半自动的,自动指的是hibernate因为有良好的映射机制,针对高级查询,也不必手动编写SQL
2.SQL的优化方面,hibernate默认是会把表中所有的列都查出来,而mybatis是指定要查哪些列,mybatis在SQL优化上还是比hibernate灵活
3,。hibernate自带日志统计,而mybatis需要依靠log4j来实现
4.mybatis比hibernate更适合开发复杂查询的的项目,更容易上手
springmvc和Struts的区别:、
1.springmvc的开发效率高于Struts2;
2.springmvc可以认为已经100%零配置;
3.Struts2是类级别的拦截,一个类对应一个request上下文,springmvc是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个URL对应;
4.springmvc的方法之间基本上独立的;
5.springmvc的入口是servlet,而Struts2是filter
6.springmvc和spring是无缝的,从这个项目管理和安全上也比Struts高
spring框架的理解:
spring是一个容器,spring的目的就是让对象与对象之间的关系没有通过代码来关联,都是通过配置文件管理。spring内部最核心的就是IOC,动态注入,让一个对象的创建不用new了,可以自动的生产,另一个核心就是aop,这个是面向切面编程,可以为某一类对象进行监督和控制。
spring常用注解:
1.@controller
2.@resource和autowired,共同点两者都可以写在字段和setter方法上;
不同点:autowired为spring的注解,按照byType注入,resource默认byName注入
3.requestmapping
4.pathvariable
5.cookieValue,获取cookie的值
6.requestparam
spring工作原理
处理对象的创建以及对象的依赖关系
IOC:
对象的创建交给外部容器完成,这个就做控制反转
依赖注入:
处理对象的依赖关系
AOP:
面向切面编程
静态代理:代理对象,要实现与目标接口一样的接口,可以做到在不修改目标对象的功能前提下,对目标对象功能扩展。
动态代理:代理对象不需要实现接口,分为JDK代理,接口代理。代理对象不需要实现接口,但是目标对象一定要实现接口;否则不能用动态代理。
spring ioc常用的依赖注入实现方式 aop事务的异常处理 声明式事务管理和编程式事务管理
spring ioc有三种注入方式:接口注入,setter方法注入,构造器注入,常用的是setter方法注入;
spring aop对异常的处理有良好的支持。spring 提供了一个接口 ThrowsAdvice,spring aop对异常的处理有良好的支持。spring 提供了一个接口 ThrowsAdvice
编程式事务:所谓编程式事务指的是通过编码方式实现事务,即类似于JDBC编程实现事务管理。管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。
声明式事务:管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。
显然声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式。
声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持。和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。
静态代理:要实现与目标对象一样的接口。
动态代理:代理对象不需要实现接口,目标对象一定要实现接口
复习springmvc的工作流程
(1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获;
2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;
3. DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法)
4. 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
5. Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
6. 根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
7. ViewResolver 结合Model和View,来渲染视图
8. 将渲染结果返回给客户端。
简化:
用户向服务器发送请求 ---》 请求被dispatherServlet捕获--》dispatherServlet对请求进行解析,获取URI,调用HandleMapping获取handler相关配置--》dispatherServlet根据获取的handler选择适合的handlerAdapter-->执行handler,向dispatherServlet返回一个ModelAndView-->根据返回的ModelAndView,选择一个合适的ViewResolver返回给dispatherServlet-->ViewResolver结合model和view来渲染视图,将渲染结果返回给客户端
)
json:
是一种轻量级的数据交互语言,以文本字符串为基础,易于别人阅读。
jquery:
一款跨浏览器的javascript库,简化javascript对html操作。
优点:(1)写代码少,做事情多;(2)免费,开源且轻量级的js库,容量很小
springcloud和dubbo的区别
最大区别:SpringCloud抛弃了Dubbo的RPC通信,采用的是基于HTTP的REST方式。
严格来说,这两种方式各有优劣。虽然从一定程度上来说,后者牺牲了服务调用的性能,但也避免了上面提到的原生RPC带来的问题。而且REST相比RPC更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的强依赖,这在强调快速演化的微服务环境下,显得更加合适。
品牌机与组装机的区别
很明显,Spring Cloud的功能比DUBBO更加强大,涵盖面更广,而且作为Spring的拳头项目,它也能够与Spring Framework、Spring Boot、Spring Data、Spring Batch等其他Spring项目完美融合,这些对于微服务而言是至关重要的。使用Dubbo构建的微服务架构就像组装电脑,各环节我们的选择自由度很高,但是最终结果很有可能因为一条内存质量不行就点不亮了,总是让人不怎么放心,但是如果你是一名高手,那这些都不是问题;而Spring Cloud就像品牌机,在Spring Source的整合下,做了大量的兼容性测试,保证了机器拥有更高的稳定性,但是如果要在使用非原装组件外的东西,就需要对其基础有足够的了解。
微服务
强调的是服务的大小,它关注的是某一个点,是具体解决某一个问题/提供落地对应服务的一个服务应用,
狭意的看,可以看作Eclipse里面的一个个微服务工程/或者Module
微服务架构是⼀种架构模式,它提倡将单⼀应⽤程序划分成⼀组⼩的服务,服务之间互相协调、互相配合,为⽤户提供最终价值。每个服务运⾏在其独⽴的进程中,服务与服务间采⽤轻量级的通信机制互相协作(通常是基于HTTP协议的RESTful API)。每个服务都围绕着具体业务进⾏构建,并且能够被独⽴的部署到⽣产环境、类⽣产环境等。另外,应当尽量避免统⼀的、集中式的服务管理机制,对具体的⼀个服务⽽⾔,应根据业务上下⽂,选择合适的语⾔、⼯具对其进⾏构建。
微服务的优缺点
优点
每个服务足够内聚,足够小,代码容易理解这样能聚焦一个指定的业务功能或业务需求
开发简单、开发效率提高,一个服务可能就是专一的只干一件事。
微服务能够被小团队单独开发,这个小团队是2到5人的开发人员组成。
微服务是松耦合的,是有功能意义的服务,无论是在开发阶段或部署阶段都是独立的。
微服务能使用不同的语言开发。
易于和第三方集成,微服务允许容易且灵活的方式集成自动部署,通过持续集成工具,如Jenkins, Hudson, bamboo 。
微服务易于被一个开发人员理解,修改和维护,这样小团队能够更关注自己的工作成果。无需通过合作才能体现价值。
微服务允许你利用融合最新技术。
微服务只是业务逻辑的代码,不会和HTML,CSS 或其他界面组件混合。
每个微服务都有自己的存储能力,可以有自己的数据库。也可以有统一数据库。
缺点
开发人员要处理分布式系统的复杂性
多服务运维难度,随着服务的增加,运维的压力也在增大
系统部署依赖
服务间通信成本
数据一致性
系统集成测试
性能监控……
索引的优点和缺点
一、为什么要创建索引呢(优点)?
这是因为,创建索引可以大大提高系统的性能。
第一, 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
第二, 可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
第三, 可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
第四, 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
第五, 通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
二、建立方向索引的不利因素(缺点)
也许会有人要问:增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢?这种想法固然有其合理性,然而也有其片面性。虽然,索引有许多优点,但是,为表中的每一个列都增加索引,是非常不明智的。这是因为,增加索引也有许多不利的一个方面。
第一, 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
第二, 索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
第三, 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。
三、创建方向索引的准则
索引是建立在数据库表中的某些列的上面。因此,在创建索引的时候,应该仔细考虑在哪些列上可以创建索引,在哪些列上不能创建索引。
CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。
一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
分区容忍性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。
CAP原则的精髓就是要么AP,要么CP,要么AC,但是不存在CAP。如果在某个分布式系统中数据无副本, 那么系统必然满足强一致性条件, 因为只有独一数据,不会出现数据不一致的情况,此时C和P两要素具备,但是如果系统发生了网络分区状况或者宕机,必然导致某些数据不可以访问,此时可用性条件就不能被满足,即在此情况下获得了CP系统,但是CAP不可同时满足。必然导致某些数据不可以访问,此时可用性条件就不能被满足,即在此情况下获得了CP系统,但是CAP不可同时满足 [1] 。
因此在进行分布式架构设计时,必须做出取舍。当前一般是通过分布式缓存中各节点的最终一致性来提高系统的性能,通过使用多节点之间的数据异步复制技术来实现集群化的数据一致性。通常使用类似 memcached 之类的 NOSQL 作为实现手段。虽然 memcached 也可以是分布式集群环境的,但是对于一份数据来说,它总是存储在某一台 memcached 服务器上。如果发生网络故障或是服务器死机,则存储在这台服务器上的所有数据都将不可访问。由于数据是存储在内存中的,重启服务器,将导致数据全部丢失。当然也可以自己实现一套机制,用来在分布式 memcached 之间进行数据的同步和持久化,但是实现难度是非常大的
java高级面试题之前端技术部分
1、什么是jsp,什么是Servlet?jsp 和Servlet 有什么区别?
jsp本质上就是一个Servlet,它是Servlet的一种特殊形式(由SUN公司推出),每个jsp页面都是一个servlet实例。Servlet是由Java提供用于开发web服务器应用程序的一个组件,运行在服务端,由servlet容器管理,用来生成动态内容。一个servlet实例是实现了特殊接口Servlet的Java类,所有自定义的servlet均必须实现Servlet接口。
区别:
- jsp是html页面中内嵌的Java代码,侧重页面显示;
- Servlet是html代码和Java代码分离,侧重逻辑控制,mvc设计思想中jsp位于视图层,servlet位于控制层
jsp运行机制:如下图
JVM只能识别Java类,并不能识别jsp代码!web容器收到以.jsp为扩展名的url请求时,会将访问请求交给tomcat中jsp引擎处理,每个jsp页面第一次被访问时,jsp引擎将jsp代码解释为一个servlet源程序,接着编译servlet源程序生成.class文件,再有web容器servlet引擎去装载执行servlet程序,实现页面交互。
2、jsp有哪些域对象和内置对象及他们的作用?
四大域对象:
- pageContext page域-指当前页面,在当前jsp页面有效,跳到其它页面失效。
- requestrequest域-指一次请求范围内有效,从http请求到服务器处理结束,返回响应的整个过程。在这个过程中使用forward(请求转发)方式跳转多个jsp,在这些页面里你都可以使用这个变量。
- sessionsession域-指当前会话有效范围,浏览器从打开到关闭过程中,转发、重定向均可以使用。
- applicationcontext域-指只能在同一个web中使用,服务器未关闭或者重启,数据就有效。
3、什么是xml,使用xml的优缺点,xml的解析器有哪几种,分别有什么区别?
xml是一种可扩展性标记语言,支持自定义标签(使用前必须预定义)使用DTD和XMLSchema标准化XML结构。
优点:用于配置文件,格式统一,符合标准;用于在互不兼容的系统间交互数据,共享数据方便;
缺点:xml文件格式复杂,数据传输占流量,服务端和客户端解析xml文件占用大量资源且不易维护
xml常用解析器有2种,分别是:DOM和SAX。主要区别在于它们解析xml文档的方式不同。使用DOM解析,xml文档以DOM树形结构加载入内存,而SAX采用的是事件模型。
4、谈谈你对ajax的认识?
Ajax是一种创建交互式网页应用的的网页开发技术;AsynchronousJavaScriptandXML的缩写。
Ajax的优势:通过异步模式,提升了用户体验。优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用。Ajax引擎在客户端运行,承担了一部分本来由服务器承担的工作,从而减少了大用户量下的服务器负载。
Ajax的最大特点:可以实现局部刷新,在不更新整个页面的前提下维护数据,提升用户体验度。
5、jsonp原理是什么?
JavaScript是一种在Web开发中经常使用的前端动态脚本技术。在JavaScript中,有一个很重要的安全性限制,被称为“Same-OriginPolicy”(同源策略)。这一策略对于JavaScript代码能够访问的页面内容做了很重要的限制,即JavaScript只能访问与包含它的文档在同一域下的内容。
JavaScript这个安全策略在进行多iframe或多窗口编程、以及Ajax编程时显得尤为重要。根据这个策略,在baidu.com下的页面中包含的JavaScript代码,不能访问在google.com域名下的页面内容;甚至不同的子域名之间的页面也不能通过JavaScript代码互相访问。对于Ajax的影响在于,通过XMLHttpRequest实现的Ajax请求,不能向不同的域提交请求,例如,在abc.example.com下的页面,不能向def.example.com提交Ajax请求,等等。然而,当进行一些比较深入的前端编程的时候,不可避免地需要进行跨域操作,这时候“同源策略”就显得过于苛刻。JSONP跨域GET请求是一个常用的解决方案,下面我们来看一下JSONP跨域是如何实现的,并且探讨下JSONP跨域的原理。jsonp的最基本的原理是:动态添加一个
Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elasticsearch 并不仅仅是 Lucene 那么简单,它不仅包括了全文搜索功能,还可以进行以下工作:
- 分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。
- 实时分析的分布式搜索引擎。
- 可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。