Java基础:
1、JAVA中能创建volatile数组吗?volatile能使得一个非原子操作变成原子操作吗?
回答: 能,Java 中可以创建 volatile 类型数组,不过只是一个指向数组的引用,而不是整个数组。
Java 中读取 long 类型变量不是原子的,需要分成两步,如果一个线程正在修改该 long 变量的值,另一个线程可能只能看到该值的一半(前 32 位)。但是volatile 型的 long 或 double 变量的读写是原子。
2、10个线程和2个线程的同步代码,哪个更容易写?
回答:从写代码的角度来说,两者的复杂度是相同的,因为同步代码与线程数量是相互独立的。但是同步策略的选择依赖于线程的数量,因为越多的线程意味着更大的竞争,所以你需要利用同步技术,如锁分离,这要求更复杂的代码和专业知识。
3、什么是线程局部变量?
回答: 对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
4、我们自己写一个容器类,然后使用for-each循环吗?
回答:可以,你可以写一个自己的容器类。如果你想使用 Java 中增强的循环来遍历,你只需要实现 Iterable接口。如果你实现 Collection 接口,默认就具有该属性。
5、说出5条IO的最佳实践?
回答:1.使用有缓冲区的 IO 类,而不要单独读取字节或字符。
2.使用 NIO 和 NIO2
3.在 finally 块中关闭流,或者使用 try-with-resource 语句。
4.使用内存映射文件获取更快的 IO。
5.使用非阻塞式而不要使用阻塞式的IO
6、说出至少5点在Java中使用线程的最佳实践?
回答:1.对线程命名
2.将线程和任务分离,使用线程池执行器来执行 Runnable 或 Callable。
3.使用线程池
4.如果可以,更偏向于使用 volatile 而不是 synchronized。
5.优先使用并发集合,而不是对集合进行同步。并发集合提供更好的可扩展性。
7、我能在不进行强制转换的情况下将一个double值赋值给long类型的变量吗?
回答:不行,因为 double 类型的范围比 long 类型更广,所以必须要进行强制转换。
8、我们能在Switch中使用String吗?
回答:在jdk 7 之前,switch 只能支持 byte、short、char、int 这几个基本数据类型和其对应的封装类型。switch后面的括号里面只能放int类型的值,但由于byte,short,char类型,它们会 自动 转换为int类型(精精度小的向大的转化),所以它们也支持。
jdk1.7后,整形,枚举类型,boolean,字符串都可以。
jdk1.7并没有新的指令来处理switch string,而是通过调用switch中string.hashCode,将string转换为int从而进行判断。
9、poll()方法和remove()方法的区别?
回答: poll() 和 remove() 都是从队列中取出一个元素,但是 poll() 在获取元素失败的时候会返回空,但是 remove() 失败的时候会抛出异常。
10、LinkedList和ArrayList的区别?
回答:1.ArrayList和LinkedList可想从名字分析,它们一个是Array(动态数组)的数据结构,一个是Link(链表)的数据结构,此外,它们两个都是前者是数组队列,相当于动态数组;后者为双向链表结构,也可当作堆栈、队列、双端队列对List接口的实现。
2.当随机访问List时(get和set操作),ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。
3.当对数据进行增加和删除的操作时(add和remove操作),LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。
4.从利用效率来看,ArrayList自由性较低,因为它需要手动的设置固定大小的容量,但是它的使用比较方便,只需要创建,然后添加数据,通过调用下标进行使用;而LinkedList自由性较高,能够动态的随数据量的变化而变化,但是它不便于使用。
5.ArrayList主要控件开销在于需要在lList列表预留一定空间;而LinkList主要控件开销在于需要存储结点信息以及结点指针信息。
11、hashmap的扩容问题new hashmap(19)它的长度是多少?
回答:初始长度是19,当达到默认加载因子的时候会进行扩容
12、hashtable为什么是线程安全的?
回答:Hashtable是线程安全的,其实现方式是在对应的方法上加上synchronized关键字,效率不高,不建议使用。目前,如果要使用线程安全的哈希表的话,推荐使用ConcurrentHashMap。
13、java异常处理怎么做?
回答:1.对代码块用try..catch进行异常捕获处理;
2.在 该代码的方法体外用throws进行抛出声明,告知此方法的调用者这段代码可能会出现这些异常,你需要谨慎处理。此时有两种情况:1)如果声明抛出的异常是非运行时异常,此方法的调用者必须显示地用try..catch块进行捕获或者继续向上层抛出异常;2)如果声明抛出的异常是运行时异常,此方法的调用者可以选择地进行异常捕获处理。
3.在代码块用throw手动抛出一个异常对象,此时也有两种情况,跟2中的类似:1)如果抛出的异常对象是非运行时异常,此方法的调用者必须显示地用try..catch块进行捕获或者继续向上层抛出异常;2)如果抛出的异常对象是运行时异常,此方法的调用者可以选择地进行异常捕获处理。
14、异常处理的作用是什么?
回答: 因为你不可能保证程序不出错,所以使用异常处理来防止程序出错的时候你无从下手的局面,对于调试程序和项目实际开发都是有用的
15、jvm内存的分配?
回答:1.程序计数器:线程私有,当前线程执行的字节码的行号指示器。
2.虚拟机栈:线程私有,存放基本数据类型、对象引用和returnAddress类型。
3.本地方法栈:为虚拟机使用到的Native方法服务。
4.Java堆:线程共享,存放对象的实例,也是GC回收器管理的主要区域。
5.方法区:线程共享,存放已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。
6.运行时常量池:方法区的一部分,存放编译期生成的各种字面量和符号引用。
7.直接内存:不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,容易引起OOM异常,NIO会调用,不受Java堆大小的限制。
16、Abstract和interface区别?
回答:1.abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface。
2.在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在 interface中一般不定义数据成员),所有的成员方法都是abstract的。
3.abstract class和interface所反映出的设计理念不同。其实abstract class表示的是"is-a"关系,interface表示的是"like-a"关系。
4.实现抽象类和接口的类必须实现其中的所有方法。抽象类中可以有非抽象方法。接口中则不能有实现方法。
5.接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。
6.抽象类中的变量默认是 friendly 型,其值可以在子类中重新定义,也可以重新赋值。
7.接口中的方法默认都是 public,abstract 类型的。
17、有没有遇到过内存溢出,内存溢出怎么解决?
回答: 分不同情况解决,大多数情况下,此时如果代码没有问题的情况下,适当调整-Xmx和-Xms是可以避免的,不过一定是代码没有问题的前提,为什么会溢出呢,要么代码有问题,要么访问量太多并且每个访问的时间太长或者数据太多,导致数据释放不掉,因为垃圾回收器是要找到那些是垃圾才能回收,这里它不会认为这些东西是垃圾,自然不会去回收了。
18、jvm调优有哪几种方式
回答:1.观察内存释放情况、集合类检查、对象树
2.线程监控
3.内存泄漏检查
4.具体调优方式:https://www.cnblogs.com/jay36/p/7680008.html
19、java中invokeAndWait和invokeLater有什么区别?
回答: 这两个方法是Swing API 提供给Java开发者用来从当前线程而不是事件派发线程更新GUI组件用的。InvokeAndWait()同步更新GUI组件,比如一个进度条,一旦进度更新了,进度条也要做出相应改变。如果进度被多个线程跟踪,那么就调用invokeAndWait()方法请求事件派发线程对组件进行相应更新。而invokeLater()方法是异步调用更新组件的。
20、Swing API中哪些方法是线程安全的?
回答:Swing的规则是:一旦Swing组件被具现化(realized),所有可能影响或依赖于组件状态的代码都应该在事件派发线程中执行。所以有这3个线程安全的方法:repaint(),revalidate(),andinvalidate()。
21、如何在Java中创建immutable对象?
回答: 1.immutable对象的状态在创建之后就不能发生改变,任何对它的改变都应该产生一个新的对象。
2.Immutable类的所有的属性都应该是final的。
3.对象必须被正确的创建,比如:对象引用在对象创建过程中不能泄露(leak)。
4.对象应该是final的,以此来限制子类继承父类,以避免子类改变了父类的immutable特性。
5.如果类中包含mutable类对象,那么返回给客户端的时候,返回该对象的一个拷贝,而不是该对象本身(该条可以归为第一条中的一个特例)
22、Java中的readwritelock是什么?
回答: 一般而言,读写锁是用来提升并发程序性能的锁分离技术的成果。Java中的ReadWriteLock是Java 5 中新增的一个接口,一个ReadWriteLock维护一对关联的锁,一个用于只读操作一个用于写。在没有写线程的情况下一个读锁可能会同时被多个读线程 持有。写锁是独占的,你可以使用JDK中的ReentrantReadWriteLock来实现这个规则,它最多支持65535个写锁和65535个读 锁。
23、多线程中的忙循环是什么?
回答: 忙循环就是程序员用循环让一个线程等待,不像传统方法wait(), sleep() 或 yield() 它们都放弃了CPU控制,而忙循环不会放弃CPU,它就是在运行一个空循环。这么做的目的是为了保留CPU缓存,在多核系统中,一个等待线程醒来的时候可能会在另一个内核运行,这样会重建缓存。为了避免重建缓存和减少等待重建的时间就可以使用它了。
24、volatile变量和atomic变量有什么不同?
回答:volatile 变量和 atomic 变量看起来很像,但功能却不一样。Volatile变量可以确保先行关系,即写操作会发生在后续的读操作之前, 但它并不能保证原子性。例如用volatile修饰count变量那么 count++ 操作就不是原子性的。而AtomicInteger类提供的atomic方法可以让这种操作具有原子性如getAndIncrement()方法会原子性的进行增量操作把当前值加一,其它数据类型和引用变量也可以进行相似操作。
25、如果同步块内的线程抛出异常会发生什么?
回答: 这个问题坑了很多Java程序员,若你能想到锁是否释放这条线索来回答还有点希望答对。无论你的同步块是正常还是异常退出的,里面的线程都会释放锁,所以对比锁接口我更喜欢同步块,因为它不用我花费精力去释放锁,该功能可以在finally block里释放锁实现。
26、单例模式的双检锁式是什么?
回答: 双重检验锁模式(double checked locking pattern),是一种使用同步块加锁的方法。程序员称其为双重检查锁,因为会有两次检查 instance == null,一次是在同步块外,一次是在同步块内。为什么在同步块内还要再检验一次?因为可能会有多个线程一起进入同步块外的 if,如果在同步块内不进行二次检验的话就会生成多个实例了。
27、如何在Java中创建线程安全的singleton?
回答:
public class Singleton {
private static Singleton instance = null;
private Singleton() {}
public static synchronized Singleton getInstance(){
if (instance == null) instance = new Singleton();
return instance;
}
}
28、说说jdk1.8的新特性?
回答:1.随着大数据的兴起,函数式编程在处理大数据上的优势开始体现,引入了Lambada函数式编程
2.使用Stream彻底改变了集合使用方式:只关注结果,不关心过程
3.新的客户端图形化工具界面库:JavaFX
4.良好设计的日期/时间API
5.增强的并发/并行API
6.Java与JS交互引擎 -nashorn
7.其他特性
29、gc回收机制原理?
回答:用户Java程序运行过程中,Java虚拟机提供了另外一个系统级的线程,专门负责回收不再被使用的对象占用的内存,这一过程称为垃圾回收。垃圾回收需要对堆内存中的对象进行标记,并对堆内存进行整理。这一过程的某些阶段需要暂时终止用户Java线程,等回收工作完成后再恢复执行。因此,频繁地触发虚拟机垃圾回收操作的行为会影响程序的运行效率。那么什么情况下会频繁地出发垃圾回收操作呢?- 比如:堆内存设置过小- 再比如:程序频繁地分配大型局部对象数组。
javaweb:
1、tomcat的优化方式?
回答:
Tomcat的优化我准备从三方面来说:
第一部分: 内存优化
Tomcat的默认内存配置比较低,不用说大项目,就算是小项目,并发量达到一定程度也就可能会抛出OutOfMemoryError异常,
为了解决这个问题,我们要修改JVM的一些配置,在tomcat的bin目录下的catalina配置文件中,配置Xms和Xmx,也就是
Java虚拟机初始化时堆的最小内存和最大内存,这俩值通常会配置成一样,这样GC不必再为扩展内存空间而消耗性能.
除了这两个,还可以配置XX:PermSize和XX:MaxPermSize,它们是Java虚拟机永久代大小和最大值,除了这几个参数
还可以再根据具体需要配置其他参数。
第二部分: 配置优化
配置优化,主要有三方面:
1. Connector 优化
Connector是连接器,它负责接收客户的请求,以及向客户端回送响应的消息。
默认情况下Tomcat只支持200线程访问,超过这个数量的连接将被等待甚至超时放弃,所以我们需要提高这方面的处理能力.
修改这部分配置需要修改conf下的server.xml,找到Connector 标签项,修改protocol,默认的协议类型是BIO,也就是阻塞式I/O操作,
简单项目及应用可以采用BIO.
第二种协议类型是NIO,它就是一种基于缓冲区是、并能提供非阻塞I/O操作的java API,它有更好的并发运行性能. NIO更适合后台需要耗时完成请求的操作
第三种协议类型是APR,它主要可以提高Tomcat对静态文件的处理性能.
选择哪个协议也是根据实际项目进行配置.
除了这个协议类型,还有一个非常重要的参数要改,就是maxThreads,就是当前连接器能够处理同时请求的最大数目.这个数目也并非
越大越好,它也受操作系统等硬件制约,所以这个值要根据压力测试后实际数据进行配置.
2. 线程池
使用线程池的好处在于减少了创建销毁线程的相关消耗,而且可以提高线程的使用效率。使用线程池就在Service标签中配置Executor就可以了
3. Listener
还有一个影响tomcat性能的因素是内存泄漏,我们在Server标签中配置一个JreMemoryLeakPreventionListener就可以用来预防JRE内存泄漏
第三部分: 组件优化
可以选用Tomcat Native组件,它可以让 Tomcat使用 Apache 的 APR包来处理包括文件和网络IO操作,从而提升性能及兼容性
2、http协议有哪些部分组成?
回答:1.请求部分:1)请求行:请求方式 路径 协议及版本 2)请求头:请求头中保存的是本地浏览器信息的,是发送到服务器,被服务器解析的 3)请求体:请求体中存储的是请求数据,请求方式是POST时,请求体中才有内容;
2.响应部分:1)响应行:协议及版本 状态码 状态码描述 2)响应头:包含了服务器信息以及响应内容信息,被浏览器解析的 3)响应体:存储响应数据,给一般用户看的
3、Get和Post的区别?
回答:Get请求方式:地址栏里会显示我们提交的数据(不安全),并且地址栏中支持提交少量数据,请求的数据存在请求行中;
Post请求方式:地址栏里不显示我们提交的数据信息(相对安全),可以提交大量数据,请求的数据存在请求正文中。
4、cookie和session的区别?
回答:共同点:cookie和session都是用来跟踪浏览器用户身份的会话方式;
区别:cookie数据保存在客户端,保存数据不安全且存储数据量有限;session数据保存在服务器端,保存数据安全且存储数据量大,session是基于cookie进行信息处理的;
5、什么是ajax,为什么要使用ajax?
回答:Ajax是一种创建交互式网页应用的网页开发技术;Asynchronous JavaScript and XML的缩写;
Ajax的优势:1.通过异步模式,提升了用户体验;
2.优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了宽带占用;
3.Ajax引擎在客户端运行,承担了一部分本来由服务器承担的工作,从而减少了大用户量下的服务器负载;
Ajax的最大特点:可以实现局部刷新,在不更新整个页面的前提下维护数据,提升用户体验度。
注意:ajax在实际项目开发中使用率非常高(牢固掌握)。
6、浅谈你对ajax的认识?
回答:同上(第5个问题)
7、Cookie和Session以及Servlet的生命周期?
回答:1.Cookie的生命周期是累计的,从创建时,就开始计时,20分钟后,cookie生命周期结束。
2. Session的生命周期是间隔的,从创建时,开始计时如在20分钟,没有访问session,那么session生命周期被销毁;但是,如果在20分钟内(如在第19分钟时)访问过session,那么将重新计算session的生命周期。注意:关机会造成session生命周期的结束,但是对cookie没有影响。
3.init():在Servlet的生命周期中,仅执行一次init()方法。它是在服务器装入Servlet时执行的,负责初始化Servlet对象。可以配置服务器,以在启动服务器或客户机首次访问Servlet时装入Servlet。无论有多少客户机访问Servlet,都不会重复执行init()。
service():它是Servlet的核心,负责响应客户的请求。每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用,而且传递给这个方法一个”请求”(ServletRequest)对象和一个”响应”(ServletResponse)对象作为参数。在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能。
destroy():仅执行一次,在服务器端停止且卸载Servlet时执行该方法。当Servlet对象退出生命周期时,负责释放占用的资源。一个Servlet在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。
8、说一下你熟悉的常用linux命令?
回答:1.列出文件列表:ls
2.创建目录和移除目录:mkdir rmdir
3.用于显示文件后几行内容:tail
4.打包:tar -xvf
5.打包并压缩:tar -zcvf
6.查找字符串:grep
7.显示当前所在目录:pwd
8.创建空文件:touch
9:编辑器:vim vi
9、后台传过的json数据前台怎么接收?
回答:在前台可以使用js代码接收,也可以通过ajax接收,也有专门的前端框架接收
10、后台传过来一个集合前台怎么接收?
回答:使用el表达式或者ognl表达式,或者根据实际情况从域中取数据
数据库:
1、MySQL的delete与truncate区别?
回答:delete语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行回滚操作,不清空AUTO_INCREMENT记录数;
truncate则直接将表删除并重新建表,不会把单独的删除操作记录记入日志保存,删除行是不能恢复的,AUTO_INCREMENT将置为0,效率比delete高。
2、MySQL的存储过程是什么?
回答:存储过程是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它;
创建存储过程:”pr_add”是个简单的MySQL存储过程,这个MySQL存储过程有两个int类型的输入参数”a”,”b”,返回这两个参数的和。
1)drop procedure if exists pr_add;
2)计算两个数之和
create procedure pr_add( a int , b int )begin declare c int;
if a is null then set a = 0;
end if;
if a is null then set b = 0;
end if;
set c = a+b;
select c as sum ;
3、谈谈你对索引的理解?
回答:索引是对数据库中一对多个列值的排序,帮助数据库高效获取数据的数据结构。假如我们用类比的方法,数据库中的索引就相当于书籍中的目录一样,当我们想找到书中的某个知识点,我们可以直接去目录中找而不是在书中每页的找,但是这也抛出了索引的一个缺点,在对数据库修改的时候要修改索引,导致时间变多。
索引分为:普通索引,唯一索引,主键索引,全文索引
优点:加快检索速度;唯一索引确保每行数据的唯一性;在使用索引的过程可以优化隐藏器,提高系统性能
缺点:插入删除,修改,维护速度下降;占用物理和数据空间;
4、简单描述一下数据库的事务?
回答:应用的场景:存在并发数据访问时才需要事务
ACID四大特性:a)原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间的某个环节。任何一项操作的失败都会导致整个事务的失败;
b)一致性:在事务开始之前和事务结束之后,数据库的完整性约束没有被破坏;
c)隔离性:并发执行的事务彼此无法看到对方的中间状态;
d)持久性:在事务完成以后,该事务所对数据库所操作的更改便持久的保存在数据库之中,并不会被回滚。
问题:a)脏读:一个事务读取到另一个事务未提交的数据
b)不可重复读:一个事务中两次查询的数据不一致 -->一个事务读到了另一个事务,已经提交数据(update 操作)
c)虚读(幻读):一个事务中两次查询的数据不一致 -->一个事务读到了另一个事务,已经提交数据(insert 操作)
隔离级别:安全从低到高,性能从高到低;
a)读未提交:也叫脏读,是事务可以读取其他事务未提交的数据。—>未解决任何问题
b)读已提交:在事务未提交之前所做的修改其它事务是不可见的。—>解决脏读问题
c)可重复读:保证同一个事务中的多次相同的查询的结果是一致的。—>解决脏读,不可重复读的问题
d)可串行化:保证读取的范围内没有新的数据插入,比如事务第一次查询得到某个范围的数据,第二次查询也同样得到了相同范围的数据,中间没有新的数据插入到该范围中。—>解决脏读,不可重复读,虚读(幻读)问题。
常用数据库默认隔离级别:
MySQL:可重复读;Oracle:读已提交;SQLServe:读已提交。r
5、Oracle是怎么样分页的?
回答:Oracle中使用rownum来进行分页,这个是效率最好的分页方法,hibernate也是使用rownum来进行Oracle分页的;
select * from
(select round r,a from tabName where round <= 20)
where r > 10
6、说说Oracle中经常使用到得函数?
回答:Length长度 、lower 小写、upper 大写、to_date 转化日期、to_char 转化字符,Ltrim 去左边空格、substr 取字符串、add_month 增加或者减掉月份、to_number 转变为数字
7、谈谈你对Oracle高水位的理解?
回答:所有的oracle段(segments,在此,为了理解方便,建议把segment作为表的一个同义词) 都有一个在段内容纳数据的上限,我们把这个上限称为"high water mark"或HWM。这个HWM是一个标记,用来说明已经有多少没有使用的数据块分配给这个segment。HWM通常增长的幅度为一次5个数据块,原则上HWM只会增大,不会缩小,即使将表中的数据全部删除,HWM还是为原值,由于这个特点,使HWM很象一个水库的历史最高水位,这也就是HWM的原始含义,当然不能说一个水库没水了,就说该水库的历史最高水位为0。但是如果我们在表上使用了truncate命令,则该表的HWM会被重新置为0。
8、MySQL、Oracle、SqlServer三者之间的区别?
回答:
1. mysql
使用风险:SQL server 完全重写代码经历了长期测试,需要时间来证明并十分兼容;
优点:
体积小、速度快、总体拥有成本低,开源;支持多种操作系统;是开源数据库,提供的接口支持多种语言连接操作。
缺点:
不支持热备份;
MySQL最大的缺点是其安全系统,主要是复杂而非标准,另外只有到调用mysqladmin来重读用户权限时才发生改变;
没有一种存储过程(Stored Procedure)语言,这是对习惯于企业级数据库的程序员的最大限制;
MySQL的价格随平台和安装方式变化。Linux的MySQL如果由用户自己或系统管理员而不是第三方安装则是免费的,第三方案则必须付许可费。Unix或Linux 自行安装 免费 、Unix或Linux 第三方安装 收费;
2. oracle
优点:
开放性:Oracle 能在所有主流平台上运行(包括 windows)完全支持所有工业标准, 采用完全开放策略,使客户选择适合解决方案;
可伸缩性,并行性:Oracle 并行服务器通过使组结点共享同簇工作来扩展windownt能 力,提供高用性和高伸缩性簇解决方案。
安全性:获得最高认证级别的ISO标准认证。
性能:Oracle 性能高 保持开放平台下TPC-D和TPC-C世界记录;
客户端支持及应用模式:Oracle 多层次网络计算支持多种工业标准用ODBC、JDBC、OCI 等网络客户连接
使用风险:Oracle 长时间开发经验完全向下兼容得广泛应用地风险低 。
缺点:
对硬件的要求很高;
价格比较昂贵;
管理维护麻烦一些;
操作比较复杂,需要技术含量较高;
3. sqlserver
优点:
易用性、适合分布式组织的可伸缩性、用于决策支持的数据仓库功能、与许多其他服 器软件紧密关联的集成性、良好的性价比等;
SQLServer是一个具备完全Web支持的数据库产品,提供了对可扩展标记语言 (XML) 的核心支持以及在Internet上和防火墙外进行查询的能力;
缺点:SQL Server 只能windows上运行,没有丝毫开放性操作系统。
伸缩性并行性 :数据卷伸缩性有限;
安全性:没有获得任何安全证书。
性能 :SQL Server 多用户时性能佳 ;
客户端支持及应用模式: 客户端支持及应用模式。只支持C/S模式,SQL Server C/S 结构只支持windows客户用ADO、DAO、OLEDB、ODBC连接;
9、数据库语句优化有哪些?
回答:1、对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及 order by 涉及的列上建立索引。
2、应尽量避免在where 字句中对字段进行null 值判断,否则将导致引擎放弃使用索引二进行全表扫描。
3、应尽量避免在where 字句中使用or 来连接条件,否则将导致引擎放弃使用索引二进行全表扫描。
4、应尽量避免在where字句中使用!=或<>操作符,否则引擎将放弃使用索引二进行全表扫描。
5、in 和 not in 也要慎用,否则会导致全表扫描。
6、索引并不是越多越好,索引固然可以提高相应的select 的效率,但同时也降低了 insert 及 update 的效率,因为insert 或update时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常用到的列上建的索引是否有必要。
7、查询结果不要用 * 来查询所有字段,要明确指明结果字段。
8、根据查询条件,简历索引,如果查询条件不止一个时,使用组合索引。
9、在查询条件表达式的左侧尽量不要使用函数,否则索引失效。
10、如果有like话,尽量避免%xxx%两侧都有%的条件,单侧%可以使用索引,多侧不可以。
11、建立索引时字段不能有null值
10、MySQL数据库优化有哪些?
回答:1. EXPLAIN 你的 SELECT 查询;2. 当只要一行数据时使用 LIMIT 1;3. 使用 ENUM 而不是 VARCHAR;4. 固定长度的表会更快;5. 分库分表
11、Oracle数据库优化有哪些?
回答:1、调整数据结构的设计。2、调整操作系统参数。3、调整应用程序结构设计。4、调整数据库SQL语句。5、调整服务器内存分配。6、调整硬盘I/O。
框架:
1、谈谈对spring框架的了解 ,spring有什么作用(IOC,AOP),spring的核心是什么?
回答:Spring是一个开源框架,它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
Spring的核心是控制反转(IoC)和面向切面(AOP)。
Spring的作用:1)方便解耦,简化开发:通过Spring提供的IOC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免编码所造成的过度程序耦合。有了Spring,用户不必再为单例模式类、属性文件解析等这些很多底层的需求编写代码,可以更专注于上层的应用。
2)AOP编程的支持:通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。
3)声明式事务的支持:在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提供开发效率和质量。
4)方便程序的测试:可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而是随手可做的事情。例如:Spring对Junit4支持,可以通过注解方便的测试Spring程序。
5)方便集成各种优秀框架:Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架的直接支持。
6)降低Java EE API的使用难度:Spring对很多难用的Java EE API 提供了一个薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。
注:Spring的源码设计精巧、结构清晰、匠心独运,处处体现着大师对Java设计模式灵活运用以及Java技术的高深造诣。Spring框架源码无疑是Java技术的最佳实践范例。如果想在短时间内迅速提高自己的Java技术水平和应用开发水平,学习和研究Spring源码将会使你收到意想不到的效果。
2、SpringMVC的常用注解,执行流程,都有哪几种解析器,必须要返回modelAndView么,SpringMVC接收一个json数据时怎么处理的,用什么注解?
回答:SpringMVC常用注解:1)@Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller对象。
2)@RequestMapping 是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
3)@Resource和@Autowired 两者都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是java.annotation.Resource,需要导入,但是Spring支持该注解的注入。@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。
4)@PathVariable 用于将请求URL中的模板变量映射到功能处理方法的参数上,即取出uri模板中的变量作为参数。
5)@Cookie 用来获取Cookie中的值。
6)@RequestParam 用于将请求参数区数据映射到功能处理方法的参数上。
7)@SessionAttrbutes 即将值放到session作用域中,写在class上面;除了可以通过属性名指定需要放到会话中的属性外(value 属性值),还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(types 属性值)。
8)@ModelAttribute 代表的是:该Controller的所有方法在调用前,先执行此@ModelAttribute方法,可用于注解和方法参数中,可以把这个@ModelAttribute特性,应用在BaseController当中,所有的Controller继承BaseController,即可实现在调用Controller时,先执行@ModelAttribute方法。
9)@ResponseBody 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区;返回数据不是html标签的页面,而是其他某种格式的数据时(如son、xml等)使用。
10)@RequestBody 该用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上;再把HttpMessageConverter返回的对象数据绑定到controller中方法的参数上。
SpringMVC的执行流程:
常用的视图解析器:(AbstractCachingViewResolver、UrlBasedViewResolver、XmlViewResolver、BeanNameViewResolver、ResourceBundleViewResolver、FreeMarkerViewResolver、VolocityViewResolver)
必须要返回modelAndView么,SpringMVC接收一个json数据时怎么处理的,用什么注解?
不是,使用@ResponseBody把后台pojo转换json对象,返回到页面;@RequestBody接受前台json,把json数据自动封装pojo。
3、Spring 依赖注入的几种方式?
回答:Spring常用的依赖注入方式是:Setter方法注入、构造器注入、Filed注入(用于注解方式);
1)Setter方法注入:首先要配置被注入的bean,在该bean对应的类中,应该有要注入的对象属性或者基本数据类型的属性。
2)构造器注入:在PersonBiz类中注入PersonDAO和一个String类型的数据;在该类中,不用为PersonDAO属性和String数据类型的属性设置setter方法,但是需要生成该类的构造方法;在配置文件中配置该类的bean,并配置构造器,在配置构造器中用到了<constructor-arg>节点。
3)Filed注入(用于注解方式):在spring中,注入依赖对象可以采用手工装配或自动装配,在实际应用开发中建议使用手工装配,因为自动装配会产生许多未知情况,开发人员无法预见最终的装配结果。
4、Spring设置为单例 ,那么线程安全问题怎么解决?
回答:首先了解一下在什么情况下,单例的Bean对象存在线程安全问题,当Bean对象对应的类存在可变的成员变量并且其中存在改变这个变量的线程时,多线程操作该Bean对象时会出现线程安全;产生的原因是当多线程中存在线程改变了bean对象的可变成员变量时,其他线程无法访问该bean对象的初始状态,从而造成数据错乱;
解决办法:1)在Bean对象中尽量避免定义可变的成员变量;2)在Bean对象中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal中。
5、 Struts2 和SpringMVC的区别 ?
回答:1)Struts2是类级别上的拦截,一个Action对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文;而且Struts2过滤后是去Struts2配置文件中Action,而SpringMVC过滤后是去Controller中找对应于@RequestMapping注解的uri绑定的方法,从这里看Struts2使用起来更麻烦,因为你要每个类的请求你都要配置对应的拦截器。
2)因为拦截器的原因,导致Struts2的action比较乱,因为它要定义属性来获取请求中参数的数据,而属性在一个类的方法间是共享的(方法间不能独享request、response数据),所以会有点乱;SpringMVC方法之间基本独立,独享request、response之间的数据。请求数据通过参数获取,处理结果通过model Map交回给框架(方法间不共享变量)。
3)SpringMVC集成了Ajax,使用非常方便,只需要一个注解@ResponseBody就可以实现,然后直接返回响应文本即可,而Struts2拦截器集成了Ajax,在Action中处理时一般必须安装插件或者自己写代码集成进去,使用起来也相对不方便。
6、Struts2可以是单例的吗 为什么?
回答:Struts2的Action是多例模式的,也就是每次请求产生一个Action的对象,但是通过spring可以控制成单例,控制成单例的话,可以减少内存的消耗,因为可以保存action不被销毁,但不保证这些数据在多线程的环境下不被相互影响。
7、什么是有状态对象,什么是无状态对象?
回答:1)有状态对象,多线程环境下不安全,那么适合用Prototype原型模式。Prototype: 每次对bean的请求都会创建一个新的bean实例;
2)无状态对象(Stateless Bean),就是没有实例变量的对象,不能保存数据,是不变类,是线程安全的。
8、Spring的常用注解?
回答:@Controller:标记于一个类上面;用来注解这个bean(类)是MVC模型中的一个控制层,使分发处理器识别到该类,该类会被spring的auto-scan扫到纳入管理。
@RequestMapping:标记于一个被@Controller标注的类上;标记于被@Controller标注类里面的方法上面;表示该被标注类下面所有方法的父类标注。
@Service:用于标注业务层组件上;标注与业务层组件上表示定义一个bean,自动根据所标注的组件名称实例化一个首字母为小写的bean。
@Resource:标注于字段上或者setter方法上,@Resource默认按ByName进行自动装配;用来自动装配Bean,激活一个命名资源的依赖注入,@Resource属性name可以定义被自动装配Bean的名称。
@Autowired:与@Resource的用法和作用基本一致;@Resource属于J2EE,@Autowired属于Spring;@Autowired是根据类型(ByType)进行自动装配的;@Autowired没有name属性,如果要按名称进行装配,需要配合@Qualifier使用。
@Repository:是用户标注数据访问层组件(DAO层);实现DAO访问,将类识别为Bean,同时它将所标注的类中抛出的数据访问异常封装为Spring的数据访问异常类型。
@Component:泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注;和前面@Service、@Repository、@Controller一样,只是它们比@Component更细化。
9、报表用的什么生成图表?
回答:1)JFreeChart :http://www.jfree.org/jfreechart/;
2)ECharts:http://git.oschina.net/free/ECharts;
3) jCharts:http://jcharts.sourceforge.net/;
4)DynamicReports:http://www.dynamicreports.org/;
5)JChartLib:http://sourceforge.net/projects/jchartlib/;
6)SWTChart:http://www.swtchart.org/;
以上JAVA常用的生成图表工具。
10、Spring 是如何管理事务的?
回答:Spring的事务机制包括声明式事务和编程式事务;编程式事务管理(Spring推荐使用TransactionTemplate,实际开发中使用声明式事务较多);声明式事务管理(将我们从复杂的事务处理中解脱出来,获取连接,关闭连接,事务提交、回滚、异常处理等这些操作都不用我们处理了,Spring都会帮我们处理;使用了AOP面向切面编程实现的,本质就是在目标方法执行前后进行拦截。在目标方法执行前加入或创建一个事务,在执行方法执行后,根据实际情况选择提交或是回滚事务。)
Spring事务管理主要包括3个接口,Spring的事务主要由它们三个共同完成的。
1)PlatformTransactionManager:事务管理器(主要用于平台相关事务的管理),主要有三个方法(commit 事务提交;rollback 事务回滚;getTransaction 获取事务状态);
2)TransactionDefinition:事务定义信息(用来定义事务相关的属性,给事务管理器PlatformTransactionManager使用),主要有四个方法(getIsolationLevel 获取隔离级别、getPropagationBehavior 获取传播行为、getTimeout 获取超时时间、isReadOnly 是否只读);
3)TransactionStatus:事务具体运行状态(事务管理过程中,每个时间点事务的状态信息)。
声明式事务:优点(不需要在业务逻辑代码中编写事务相关代码,只需要在配置文件配置或使用注解(@Transaction),这种方式没有入侵性);
缺点(声明式事务的最细粒度作用于方法上,如果像代码块也有事务需求,只能变通下,将代码块变为方法)。
11、简单说说你知道的spring的底层?
回答:1)Spring对Bean进行实例化(相当于程序中的new Xx())
2)Spring将值和Bean的引用注入进Bean对应的属性中
3)如果Bean实现了BeanNameAware接口,Spring将Bean的ID传递给setBeanName()方法(实现BeanNameAware清主要是为了通过Bean的引用来获得Bean的ID,一般业务中是很少有用到Bean的ID的)
4)如果Bean实现了BeanFactoryAware接口,Spring将调用setBeanDactory(BeanFactory bf)方法并把BeanFactory容器实例作为参数传入。(实现BeanFactoryAware 主要目的是为了获取Spring容器,如Bean通过Spring容器发布事件等)
5)如果Bean实现了ApplicationContextAwaer接口,Spring容器将调用setApplicationContext(ApplicationContext ctx)方法,把y应用上下文作为参数传入.(作用与BeanFactory类似都是为了获取Spring容器,不同的是Spring容器在调用setApplicationContext方法时会把它自己作为setApplicationContext 的参数传入,而Spring容器在调用setBeanDactory前需要程序员自己指定(注入)setBeanDactory里的参数BeanFactory )
6)如果Bean实现了BeanPostProcess接口,Spring将调用它们的postProcessBeforeInitialization(预初始化)方法(作用是在Bean实例创建成功后对进行增强处理,如对Bean进行修改,增加某个功能)
7)如果Bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet方法,作用与在配置文件中对Bean使用init-method声明初始化的作用一样,都是在Bean的全部属性设置成功后执行的初始化方法。
8)如果Bean实现了BeanPostProcess接口,Spring将调用它们的postProcessAfterInitialization(后初始化)方法(作用与6的一样,只不过6是在Bean初始化前执行的,而这个是在Bean初始化后执行的,时机不同)
9)经过以上的工作后,Bean将一直驻留在应用上下文中给应用使用,直到应用上下文被销毁
10)如果Bean实现了DispostbleBean接口,Spring将调用它的destory方法,作用与在配置文件中对Bean使用destory-method属性的作用一样,都是在Bean实例销毁前执行的方法。
12、说说solr的底层 ?
回答:1) 索引过程:(1、有一系列被索引文件;2、被索引文件经过语法分析和语言处理形成一系列词(Term);3、经过索引创建形成词典和反向索引表;4、通过索引存储将索引写入硬盘。)
2)搜索过程:(1、用户输入查询语句;2、 对查询语句经过语法分析和语言分析得到一系列词(Term);3、通过语法分析得到一个查询树;4、通过索引存储将索引读入到内存;5、利用查询树搜索索引,从而得到每个词(Term)的文档链表,对文档链表进行交,差,并得到结果文档;6、将搜索到的结果文档对查询的相关性进行排序;7、返回查询结果给用户。)
源码实现:https://blog.csdn.net/jj380382856/article/details/52240899
13、Solr如何搭建,简单介绍一下,你用的什么版本?
回答:solr-4.10.3搭建:1)下载solr-4.10.3版本,JDK需要1.7及以上版本;2)解压solr-4.10.3;3)创建solr工程;4)部署到tomcat容器;5)新建solrCore,在此目录下新建core2文件夹;6)查询数据表数据;7)java通过solr查询数据库表。
详细过程参考:https://blog.csdn.net/qq_15862785/article/details/71055652
14、Mybatis和hibernate的区别?
回答:mybatis:1)入门简单,即学即用,提供数据库查询的自动对象绑定功能,而且延续了很好的SQL使用经验,对于没有那么高的对象模型要求的项目来说,相当完美;
2)可以进行更为细致的SQL优化,可以减少查询字段;
3)缺点就是框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改;
4)二级缓存机制不佳。
hibernate:1)功能强大,数据库无关性好,O/R映射能力强,如果你对Hibernate相当精通,而且对Hibernate进行了适当的封装,那么你的项目整个持久层代码会相当简单,需要写的代码很少,开发速度很快,非常爽;
2)有更好的二级缓存机制,可以使用第三方缓存;
3)缺点就是学习门槛不低,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何取得平衡,以及怎样用好Hibernate方面需要你的经验和能力都很强才行。
15、对于hibernate3,4,5有什么了解,其中的特性是什么?
回答:hibernate4中的新特性基于hibernate3中的改变:1)数据库方言的设置(在3.3版本中连接MySQL数据库只需要指明MySQLDialect即可。在4.1版本中可以指出MySQL5Dialect)
2)buildSessionFactory(4.1版本中buildSessionFactory()已经被buildSessionFactory(ServiceRegistry ServiceRegistry)取代)
3)annotation(4.1版本中推荐使用annotation配置,所以在引进jar包时把requested里面的包全部引进来就已经包含了annotation必须包了)
4)事务,hibernateTemplate(hibernate4已经完全可以实现事务了与spring3.1中的hibernatedao,hibernateTemplate等有冲突,所以spring3.1里已经不提供hibernatedaosupport,hibernateTemplate)
5)自动建表(hibernate4.1已经可以自动建表,所以开发时只需要自己开发类然后配置好久OK)
hibernate5的新特性:1)明确了关联关系映射;2)明确Hibernate检索优化;3)明确Hibernate缓存机制;4)明确Hibernate对事务并发控制的管理;5)明确Hibernate注解开发。
16、SpringMVC的底层是基于什么实现的?
回答:Spring MVC是基于servlet功能实现的,通过实现Servlet接口的DispatcherServlet来封装其核心功能实现,通过将请求分派给处理程序,同时带有可配置的处理程序映射、视图解析、本地语言、主题解析以及上传下载文件支持。
17、请罗列出您所理解的微服务架构应具有的关键组件及关键指标?
回答:1)负载平衡:Linkerd提供了多种负载均衡算法,它们使用实时性能指标来分配负载并减少整个应用程序的尾部延迟。
2)熔断:Linkerd包含自动熔断,将停止将流量发送到被认为不健康的实例,从而使他们有机会恢复并避免连锁反应故障。
3)服务发现:Linkerd 与各种服务发现后端集成,通过删除特定的(ad-hoc)服务发现实现来帮助您降低代码的复杂性。
4)动态请求路由:Linkerd 启用动态请求路由和重新路由,允许您使用最少量的配置来设置分段服务(staging service),金丝雀(canaries),蓝绿部署(blue-green deploy),跨DC故障切换和黑暗流量(dark traffic)。
5)重试次数和截止日期:Linkerd可以在某些故障时自动重试请求,并且可以在指定的时间段之后让请求超时。
6)TLS:Linkerd可以配置为使用TLS发送和接收请求,您可以使用它来加密跨主机边界的通信,而不用修改现有的应用程序代码。
7)HTTP代理集成:Linkerd可以作为HTTP代理,几乎所有现代HTTP客户端都广泛支持,使其易于集成到现有应用程序中。
8)透明代理:您可以在主机上使用iptables规则,设置通过Linkerd的透明代理。
9)gRPC:Linkerd支持HTTP/2和TLS,允许它路由gRPC请求,支持高级RPC机制,如双向流,流程控制和结构化数据负载。
10)分布式跟踪:Linkerd支持分布式跟踪和度量仪器,可以提供跨越所有服务的统一的可观察性。
11)仪器仪表:Linkerd支持分布式跟踪和度量仪器,可以提供跨越所有服务的统一的可观察性。
18、hibernate的二级缓存有什么用?
回答:因为应用程序访问数据库,读写数据的代价非常高,而利用持久层的缓存可以减少应用程序与数据库之间的交互,即把访问过的数据保存到缓存中,应用程序再次访问已经访问过的数据,这些数据就可以从缓存中获取,而不必再从数据库中获取。同时如果数据库中的数据被修改或者删除,那么是该数据所对应的缓存数据,也会被同步修改或删除,进而保持缓存数据的一致性。
19、介绍一下mybatis?
回答:1)入门简单,即学即用,提供数据库查询的自动对象绑定功能,而且延续了很好的SQL使用经验,对于没有那么高的对象模型要求的项目来说,相当完美;
2)二级缓存机制不佳。
3)可以进行更为细致的SQL优化,可以减少查询字段;
4)缺点就是框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改;
20、 Shiro的原理?
回答:shiro是apache的一个开源框架,是一个权限管理的框架,实现用户认证,用户授权。spring中有spring security(原名Acegi),是一个权限框架,它和spring依赖过于紧密,没有shiro使用简单。shiro不依赖与spring,shiro不仅可以实现web应用的权限管理,还可以实现c/s系统,分布式系统权限管理,shiro属于轻量级框架,越来越多的企业项目使用shiro。使用shiro实现系统的权限管理,有效提高开发效率,从而降低开发成本。
shiro架构有3个主要概念:Subject、SecurityManager、Realms。
1)Subject,正如我们在教程中所说,Subject其实代表的就是当前正在执行操作的用户,只不过因为“User”一般指代人,但是一个“Subject”可以是人,也可以是任何的第三方系统,服务账号等任何其他正在和当前系统交互的第三方软件系统。
所有的Subject实例都被绑定到一个SecurityManager,如果你和一个Subject交互,所有的交互动作都会被转换成Subject与SecurityManager的交互。
2)SecurityManager。SecurityManager是Shiro的核心,他主要用于协调Shiro内部各种安全组件,不过我们一般不用太关心SecurityManager,对于应用程序开发者来说,主要还是使用Subject的API来处理各种安全验证逻辑。
3)Realm,这是用于连接Shiro和客户系统的用户数据的桥梁。一旦Shiro真正需要访问各种安全相关的数据(比如使用用户账户来做用户身份验证以及权限验证)时,他总是通过调用系统配置的各种Realm来读取数据。
正因为如此,Realm往往被看做是安全领域的DAO,他封装了数据源连接相关的细节,将数据以Shiro需要的格式提供给Shiro。当我们配置Shiro的时候,我们至少需要配置一个Realm来提供用户验证和权限控制方面的数据。我们可能会给SecurityManager配置多个Realm,但是不管怎样,我们至少需要配置一个。
Shiro提供了几种开箱即用的Realm来访问安全数据源,比如LDAP、关系数据库、基于ini的安全配置文件等等,如果默认提供的这几种Realm无法满足你的需求,那么你也可以编写自己的定制化的Realm插件。
和其他内部组件一样,SecurityManager决定了在Shiro中如何使用Realm来读取身份和权限方面的数据,然后组装成Subject实例。
shiro详细架构:
21、Webservice是什么,怎么用 ?
回答:从表面上看,WebService就是一个应用程序,它向外界暴露出一个能够通过Web进行调用的API。这就是说,你能够用编程的方法通过Web调用来实现某个功能的应用程序。从深层次上看,Web Service是一种新的Web应用程序分支,它们是自包含、自描述、模块化的应用,可以在网络(通常为Web)中被描述、发布、查找以及通过Web来调用;Web Service便是基于网络的、分布式的模块化组件,它执行特定的任务,遵守具体的技术规范,这些规范使得Web Service能与其他兼容的组件进行互操作。它可以使用标准的互联网协议,像超文本传输协议HTTP和XML,将功能体现在互联网和企业内部网上。WebService平台是一套标准,它定义了应用程序如何在Web上实现互操作性。你可以用你喜欢的任何语言,在你喜欢的任何平台上写Web Service;WebService 为Internet 上的组件服务•通过网络提供,以URL 定位方法调用•以Internet技术为基础•未來的分散式应用程序。
第一步:创建一个Java项目
第二步:创建一个类,加入Webservice注解
@WebService是jdk提供的一个注解,它位于javax.jws.*这个包中。
第三步:创建一个方法
第四步:在main方法中调用jdk提供的发布服务的方法
通过EndPoint(端点服务)发布一个webService。
Endpoint也是jdk提供的一个专门用于发布服务的类,它的publish方法接收两个参数,一个是本地的服务地址,二是提供服务的类。它位于javax.xml.ws.*包中。
static Endpoint.publish(String address, Object implementor) 在给定地址处针对指定的实现者对象创建并发布端点。
stop方法用于停止服务。
EndPoint发布完成服务以后,将会独立的线程运行。所以,publish
之后的代码,可以正常执行
22、solr存数据是不是要创建索引?
回答:要创建,存数据之前需要创建标签并设置属性,需要创建的索引必须在Schema里面有。
redis:
1、什么是Redis?
回答:Redis是一个基于内存的高性能key-value数据库;
应用场景:1)会话缓存(Session Cache) 2)全页缓存(FPC)3)队列 4)排行榜/计数器 5)发布/订阅
2、使用Redis有哪些好处?
回答:1)速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);
2)支持丰富的数据类型,支持string,list,set,sorted set,hash;
3)支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行;
4)丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除;
3、Redis的特点?
回答:Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过10万次读写操作,是已知性能最快的Key-Value DB.
Redis的出色之处不仅仅是性能,Redis最大的魅力是支持保存多种数据结构,此外单个value的最大限制是1GB,不像memcached只能保存1MB的数据,另外Redis也可以对存入的Key-Value设置expire时间。
Redis的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。
4、为什么Redis需要把所有数据放到内存中?
回答:Redis为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以redis具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘I/O速度会严重影响redis的性能。如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。
5、Redis常见的性能问题怎么解决?
回答:1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件;
2)如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次;
3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内;
4)尽量避免在压力很大的主库上增加从库;
5)主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3…;
这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。
6、Redis与memcached有什么区别?
回答:1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型;
2) redis的速度比memcached快很多;
3) redis可以持久化其数据;
7、Redis有哪些数据结构?
回答:常用的五种数据结构(string、list、set、hash、zset)
1)string :可以是字符串,整数或者浮点数,对整个字符串或者字符串中的一部分执行操作,对整个整数或者浮点执行自增(increment)或者自减(decrement)操作。
2)list:一个链表,链表上的每个节点都包含了一个字符串,虫链表的两端推入或者弹出元素,根据偏移量对链表进行修剪(trim),读取单个或者多个元素,根据值查找或者移除元素。
3)set:包含字符串的无序收集器(unordered collection)、并且被包含的每个字符串都是独一无二的。添加,获取,移除单个元素,检查一个元素是否存在于集合中,计算交集,并集,差集,从集合里面随机获取元素。
4)hash:包含键值对无序散列表,添加,获取,移除当键值对,获取所有键值对。
5)zset :字符串成员(member)与浮点数分值(score)之间的有序映射,元素的排列顺序由分值的大小决定。添加,获取,删除单个元素,根据分值范围(range)或者成员来获取元素。
8、Redis持久化方案区别以及优缺点?
回答:redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。
RDB方式:是一种快照式的持久化方法,将某一时刻的数据持久化到磁盘中。
1)redis在进行数据持久化的过程中,会先将数据写入到一个临时文件中,待持久化过程都结束了,才会用这个临时文件替换上次持久化好的文件。正是这种特性,让我们可以随时来进行备份,因为快照文件总是完整可用的。
2)对于RDB方式,redis会单独创建(fork)一个子进程来进行持久化,而主进程是不会进行任何IO操作的,这样就确保了redis极高的性能。
3)如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。
AOF方式:是将执行过的写指令记录下来,在数据恢复时按照丛前到后的顺序再将指令执行一遍。
1)AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大.默认的AOF持久化策略是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中),因为在这种情况下,redis仍然可以保持很好的处理性能,即使redis故障,也只会丢失最近1秒钟的数据。
2)如果在追加日志时,恰好遇到磁盘空间满、inode满或断电等情况导致日志写入不完整,也没有关系,redis提供了redis-check-aof工具,可以用来进行日志修复。
3)因为采用了追加方式,如果不做任何处理的话,AOF文件会变得越来越大,为此,redis提供了AOF文件重写(rewrite)机制,即当AOF文件的大小超过所设定的阈值时,redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。举个例子或许更形象,假如我们调用了100次INCR指令,在AOF文件中就要存储100条指令,但这明显是很低效的,完全可以把这100条指令合并成一条SET指令,这就是重写机制的原理。
4)在进行AOF重写时,仍然是采用先写临时文件,全部完成后再替换的流程,所以断电、磁盘满等问题都不会影响AOF文件的可用性。
9、如何来维护集群之间的关系,或者说集群之间如何建立连接?
回答:1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
2)节点的fail是通过集群中超过半数的节点检测失效时才生效.
3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
4)redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value
10、Redis如何存取实体?
回答:存储的时候需要将实体序列化,然后就可以当字符串一样存储,取数据时也一样,取出来的数据需要反序列化。
11、Redis保留时间多久?
回答:如果未设置则一直存在,除非服务停掉且没有保存到磁盘。如果已手动或自动保存过,则再次启动服务还会存在。
EXPIRE <KEY> <TTL> : 将键的生存时间设为 ttl 秒
PEXPIRE <KEY> <TTL> :将键的生存时间设为 ttl 毫秒
EXPIREAT <KEY> <timestamp> :将键的过期时间设为 timestamp 所指定的秒数时间戳
PEXPIREAT <KEY> <timestamp>: 将键的过期时间设为 timestamp 所指定的毫秒数时间戳.
12、Redis挂掉后怎么办?介绍Redis是怎么实现高可用的?
回答:主要取决于,你是把redis作为缓存还是nosql,如果是缓存那丢了也无所谓,从别的地方恢复重建就行了,如果是nosql的话,redis是有snapshot和aof的机制来保证数据持久化的。
高可用实现流程:https://blog.csdn.net/fwk19840301/article/details/80675463
13、Redis有事务吗,简单的说一下?
回答:1) 开启:以MULTI开始一个事务
2) 入队:将多个命令入队到事务中,找到这些命令并不会立即执行,而是放到等待执行事务队列里面
3) 执行:由EXEC命令触发事务
三个特性:单独的隔离操作:事务的所有命令都会序列化、按顺序地实行
没有隔离级别的概念:事务提交前任何指令都不会被实际执行
不保证原子性:redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,不回滚