java面试
技术面
除了自己的技术,项目之外,还有那些注意的点?
- 技术人员问你有什么问题要问的?
对于技术面,可以了解一下公司目前的业务,公司用的技术和框架,我所应聘的这个Java岗位的职责,以上情况如果之前在招聘途径上了解过就不用问了,免得显得自己很没有诚意,什么都不知道情况。没有写的话可以问一问以示郑重。要是了解以上情况了,还可以问目前进行到的阶段和团队的情况,加班的情况。这些招聘途径上一般是不会写的。不介意平时的加班,这是对自己的提升和对工作的负责。但是周末不希望加班。偶尔不可抗的周末加班表示理解,也会配合。
- 自己的优势,转换优势和劣势。
虽然换行带来暂时的项目经验欠缺的短板。换个方面想从转岗可以看出我对Java的决心毅力,行动力,执行力和自学,快速学习的能力。
- 为什么要转行Java?
个人兴趣方面:喜欢做逻辑处理,业务处理。Java要做的,了解的技术很多,喜欢掌控全局,喜欢挑战。以后会研究更深一层的,比如框架优化,框架是怎么实现的。
就业方面: Java是公司主流。后台都要用Java,就业广。
- 贝因美面试的具体情况。想要了解我的哪些方面。
1.目前的自身情况?什么时候离职的,什么时候开始学Java的,什么时候开始写项目的。会什么技术。怎么学习的,Google,github,论坛,官网,学习原理+跑demo+整合到自己的项目中。
2.所做的项目?天气预报restful接口。个人博客项目。使用dubbo分布式服务框架博客项目远程调用天气预报服务。拓展开来将自己用什么技术,实现了什么功能。功能模块,数据库都是自己设计的。技术选型都是自己选的。
3.为什么要转行?这个不要从我的测试方面说,要从Java方面说。个人兴趣和就业情况两方面来讲。
Java基础
一:抽象类和接口有什么区别?
接口不是类,抽象类是一个功能不齐全的类,都不能实例化对象。
一个类可以实现(implements)多个接口。一个类只能继承(extends)一个抽象类。
接口没有构造函数,所有方法都是 public abstract的,一般不定义成员变量。(所有的成员变量都是 static final ,而且必须显示初始化)。抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
一个实现接口的类,必须实现接口内所描述的所有方法(所有方法都是抽象的方法),否则就必须声明为抽象类。如果一个类包含抽象方法,那么该类必须是抽象类。任何子类必须重写父类的抽象方法,或者声明自身为抽象类。
二:Java String,StringBuffer和StringBuilder之间的区别
当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。String 是被 final 修饰的,他的长度是不可变的,就算调用 String 的 concat 方法,那也是把字符串拼接起来并重新创建一个对象,把拼接后的 String 的值赋给新创建的对象,而 StringBuffer 的长度是可变的,调用StringBuffer 的 append 方法,来改变 StringBuffer 的长度,并且,相比较于 StringBuffer,String 一旦发生长度变化,是非常耗费内存的!
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
总结:
String 长度大小不可变
StringBuffer 和 StringBuilder 长度可变
StringBuffer 线程安全 StringBuilder 线程不安全
StringBuilder 速度快
三:运行时异常和一般异常有何异同?
运行时异常:由java虚拟机抛出的异常。用户不必处理。
一般异常是用户可以抛出的异常,如果抛出调用必须进行处理。
运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。
四:ArrayList和LinkedList的特性是什么?分别用在什么场合?
- ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
- 对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
- 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
五:在Java中有哪几种实现多线程的方式?
- 继承thread类
- 实现runnable接口
- 实现callable接口
六:设计模式及应用场合。
- 单例模式:简单来说就是一个类只能构建一个对象的设计模式。
单例模式的代码实现:
public class Singleton {
private Singleton() {} //私有构造函数
private static Singleton instance = null; //单例对象
//静态工厂方法
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
1.要想让一个类只能构建一个对象,自然不能让它随便去做new操作,因此Signleton的构造方法是私有的。
2.instance是Singleton类的静态成员,也是我们的单例对象。它的初始值可以写成Null,也可以写成new Singleton()。至于其中的区别后来会做解释。
3.getInstance是获取单例对象的方法。
如果单例初始值是null,还未构建,则构建单例对象并返回。这个写法属于单例模式当中的懒汉模式。
如果单例对象一开始就被new Singleton()主动构建,则不再需要判空操作,这种写法属于饿汉模式。
但是以上代码不是线程安全的。假设Singleton类刚刚被初始化,instance对象还是空,这时候两个线程同时访问getInstance方法;因为Instance是空,所以两个线程同时通过了条件判断,开始执行new操作;这样一来,显然instance被构建了两次。让我们对代码做一下修改:
public class Singleton {
private Singleton() {} //私有构造函数
private static Singleton instance = null; //单例对象
//静态工厂方法
public static Singleton getInstance() {
if (instance == null) { //双重检测机制
synchronized (Singleton.class){ //同步锁
if (instance == null) { //双重检测机制
instance = new Singleton();
}
}
}
return instance;
}
}
1.为了防止new Singleton被执行多次,因此在new操作之前加上Synchronized 同步锁,锁住整个类(注意,这里不能使用对象锁)。
2.进入Synchronized 临界区以后,还要再做一次判空。因为当两个线程同时访问的时候,线程A构建完对象,线程B也已经通过了最初的判空验证,不做第二次判空的话,线程B还是会再次构建instance对象。
像这样两次判空的机制叫做双重检测机制。
以上代码还有一个隐藏漏洞,假设这样的场景,当两个线程一先一后访问getInstance方法的时候,当A线程正在构建对象,B线程刚刚进入方法;这种情况表面看似没什么问题,要么Instance还没被线程A构建,线程B执行 if(instance == null)的时候得到true;要么Instance已经被线程A构建完成,线程B执行 if(instance == null)的时候得到false。
真的如此吗?答案是否定的。这里涉及到了JVM编译器的指令重排。
指令重排是什么意思呢?比如java中简单的一句 instance = new Singleton,会被编译器编译成如下JVM指令:
memory =allocate(); //1:分配对象的内存空间
ctorInstance(memory); //2:初始化对象
instance =memory; //3:设置instance指向刚分配的内存地址
但是这些指令顺序并非一成不变,有可能会经过JVM和CPU的优化,指令重排成下面的顺序:
memory =allocate(); //1:分配对象的内存空间
instance =memory; //3:设置instance指向刚分配的内存地址
ctorInstance(memory); //2:初始化对象
当线程A执行完1,3,时,instance对象还未完成初始化,但已经不再指向null。此时如果线程B抢占到CPU资源,执行 if(instance == null)的结果会是false,从而返回一个没有初始化完成的instance对象。 如何避免这一情况呢?我们需要在instance对象前面增加一个修饰符volatile。
public class Singleton {
private Singleton() {} //私有构造函数
private volatile static Singleton instance = null; //单例对象
//静态工厂方法
public static Singleton getInstance() {
if (instance == null) { //双重检测机制
synchronized (Singleton.class){ //同步锁
if (instance == null) { //双重检测机制
instance = new Singleton();
}
}
}
return instance;
}
}
volatile 修饰符阻止了变量访问前后的指令重排,保障了指令执行顺序。如此在线程B看来,instance对象的引用要么指向null,要么指向一个初始化完毕的Instance,而不会出现某个中间态,保证了安全。
七:索引的作用是什么?越多越好么?为什么?
创建索引可以大大提高数据库性能。
- 通过创建唯一性索引可以保证数据库表中每一行数据的唯一性。
- 可以大大加快数据检索的速度。
- 加速表和表自己的连接,特别是在实现数据的参考完整性方面特别有意义。
- 在使用分组和排序 子句进行数据检索时同时可以显著减少查询中分组和排序的时间。
- 可以在查询的过程中,使用优化隐藏器,提供系统的性能。
但索引不是越多越好的
- 创建和维护索引要耗费时间,而且数据量越大,消耗的时间越多。
- 索引要占物理空间,需要的空间会更大。
- 对表中的数据进行增删改的时候,索引也要动态维护,降低了数据维护的速度。
八:同步和异步有何异同,及使用场景。
同步(synchronized)和异步(asynchronized)是对于多线程(multi-threading)而言的。同步可防止并发 主要出于数据安全的考虑 。异步允许并发。
同步交互:指发送一个请求,需要等待返回,然后才能够发送下一个请求,有个等待过程;
异步交互:指发送一个请求,不需要等待返回,随时可以再发送下一个请求,即不需要等待。 区别:一个需要等待,一个不需要等待,在部分情况下,我们的项目开发中都会优先选择不需要等待的异步交互方式。
哪些情况建议使用同步交互呢?比如银行的转账系统,对数据库的保存操作等等,都会使用同步交互操作,其余情况都优先使用异步交互
九:MVC架构和用过的MVC框架。
MVC架构分三成:
- 最上面的一层,是直接面向最终用户的”视图层”(View)。它是提供给用户的操作界面,是程序的外壳。
- 最底下的一层,是核心的”数据层”(Model),也就是程序需要操作的数据或信息。
- 中间的一层,就是”控制层”(Controller),它负责根据用户从”视图层”输入的指令,选取”数据层”中的数据,然后对其进行相应的操作,产生最终结果。
这三层是紧密联系在一起的,但又是互相独立的,每一层内部的变化不影响其他层。每一层都对外提供接口(Interface),供上面一层调用。这样一来,软件就可以实现模块化,修改外观或者变更数据都不用修改其他层,大大方便了维护和升级。
SpringMVC框架见下文的springMVC的原理。
十:应用服务器的作用是什么?应用服务器有哪些?和web服务器的区别是什么?
- 应用服务器的作用?
- 应用服务器处理业务逻辑。
- 一般是用来处理动态请求的服务器。
- web服务器的作用?
- web服务器则主要是让客户可以通过浏览器进行访问。 Web服务器只负责处理HTTP协议,只是简单的通过响应HTML页面来处理HTTP请求。
-
应用服务器有哪些?
Weblogic、Tomcat、Jboss
-
web服务器有哪些?
IIS、 Apache
- 应用服务器和web服务器有什么区别?
- 应用服务器处理业务逻辑,web服务器则主要是让客户可以通过浏览器进行访问。
- Web服务器的设计目的是提供HTTP内容,应用服务器也可以提供HTTP内容,但不限于HTTP,它还可以提供其他协议支持,如RMI / RPC。
- Web服务器主要是为提供静态内容而设计的,不过大多数Web服务器都有插件来支持脚本语言,比如Perl、PHP、ASP、JSP等,通过这些插件,这些服务器就可以生成动态的HTTP内容。
- 大多数应用服务器都将Web服务器作为其不可分割的一部分,这意味着应用服务器可以做任何Web服务器所能做的事情。此外,应用服务器有组件和特性来支持应用级服务,如连接池、对象池、事务支持、消息传递服务等。
- 由于web服务器非常适合用于提供静态内容,而应用服务器适合提供动态内容,因此大多数生产环境都有web服务器充当应用服务器的反向代理。这意味着在页面请求时,web服务器会通过提供静态内容(例如图像/静态HTML)来解释请求,并且它还会使用某种过滤技术(主要是请求资源的扩展)识别动态内容请求,并透明地转发到应用服务器。
十一:一个常见的runtime exception。如何去避免
(一) NullPointerException空指针异常。
Java 空指针异常(java.lang.NullPointerException),顾名思义,即对象没有进行实例化便进行了使用。实例化的意义,就是将对象实例的地址赋值给对象符号。 比如 String a = new String();即在堆中将String的实例构造后,将地址赋值给a。 String a = “123”;即将常量池中的“123”这个对象实例的地址赋值给a。
引发空指针异常,往往是在获取对象实例地址的时候,由于获取的对象实例并不存在,因此返回的地址为null,而又没进行判断,直接使用了该对象实例(地址)引发的。
如何避免:
- 如果要把某个方法的返回值与常量做比较,把常量放在前面,可以避免调用null对象的equals方法。例如上述改成: “root”.equals(userName);
- 判断collection是否为空。
- 使用一些判断方法。
- 异常处理。
- assert关键字和Assert类。
(二) 数组下标越界异常。
如何避免:检查访问的参数是否越界。
十二:SOAP接口和RESTful接口的区别?
- 什么是SOAP接口?和SOA什么关系?
SOAP (Simple Object Access Protocol,简单对象访问协议)) 顾名思义,是一个严格定义的信息交换协议,用于在Web Service中把远程调用和返回封装成机器可读的格式化数据。
- 什么是REST?
REST (REpresentational State Transfort) 形式上应该表述为客户端通过申请资源来实现状态的转换
- SOAP接口和RESTful接口的区别?
- RESTful Web 服务使用标准的 HTTP 方法 (GET/PUT/POST/DELETE) 来抽象所有 Web 系统的服务能力,而不同的是,SOAP 应用都通过定义自己个性化的接口方法来抽象 Web 服务,这更像我们经常谈到的 RPC。
十三:两个List,写一段程序删除两个list中相同的值。 (我写了两个for循环嵌套) 你这段代码可能会出现的问题。
我不知道,提到了迭代器的使用。查一下这个。
十四:下断程序运行的结构是什么,并说明原因。
String str1 = "hello";
String str2 = "he" + new String("llo");
System.err.println(str1 == str2);
输出 > false
原因:因为str2中的llo是新申请的内存块,而==判断的是对象的地址而非值,所以不一样。如果是String str2 .equals(str1),那么就是true了。
这里考察的是 == 和equals的区别。也考察到了string和stringbuffer的区别。
- == 是一个运算符,equals是string对象的方法。
- Java中,值类型是存储在内存的栈中。二引用类型在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。所有字符串的内容相同,引用地址不一定相同,有可能创建了多个对象。 == 操作比较的是两个变量的值是否相等,对于引用类型变量表示的是栈的内容是否相等,即变量地址是否相等。
- equals将此字符串与指定的对象比较。当且仅当该参数不为 null,并且是与此对象表示相同字符序列的 String 对象时,结果才为 true。即堆中的内容是否相同。==比较的是2个对象的地址(栈中),而equals比较的是2个对象的内容(堆中)。所以当equals为true时,==不一定为true。
十四-1: 用一条SQL语句查询出每门课都大于80分的学生姓名。(这里每一个学生的课程数和课程不一定一样)
方法一: not in + 子查询
select distinct Name from Grade where Name not in (select distinct Name from Grade where Score<=80)
方法二:group by + 聚合函数
select Name from Grade group by Name having min(score)>80
十四-2:给出所有购入商品为两种或两种以上的购物人记录
select * from 购物信息 where 购物人 in (select 购物人 from 购物信息 group by 购物人 having count(*) >= 2);
考察了子查询和一些关键字,函数的知识点。 必会的SQL笔试题
十五:B/S和C/S的区别?
首先要了解什么是B/S,什么是C/S结构。
B/S,即Browser/Server(浏览器/服务器)结构。在这种结构下,用户界面完全通过WWW浏览器实 现,一部分事务逻辑在前端实现,但是主要事务逻辑在服务器端实现,形成所谓3-tier结构。B/S结构,主要是利用了不断成熟的WWW浏览器技术,结合浏览器的多种Script语言(VB Script、JavaScript…)和ActiveX技术,用通用浏览器就实现了原来需要复杂专用软件才能实现的强大功能,并节约了开发成本,是一种全新的软件系统构造技术。
C/S,即Client/Server(客户端/服务器)结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销,可以充分利用两端 硬件环境的优势。早期的软件系统多以此作为首选设计标准。
C/S是建立在局域网的基础上的,B/S是建立在广域网的基础上的。
1.硬件环境不同:
C/S 一般建立在专用的网络上, 小范围里的网络环境, 局域网之间再通过专门服务器提供连接和数据交换服务.
B/S 建立在广域网之上的, 不必是专门的网络硬件环境,例与电话上网, 租用设备. 信息自己管理. 有比C/S更强的适应范围, 一般只要有操作系统和浏览器就行
2.对安全要求不同
C/S 对服务端、客户端都安全都要考虑。
B/S 因没有客户端,所以只注重服务端安全即可。
3.对程序架构不同
C/S 程序可以更加注重流程, 可以对权限多层次校验, 对系统运行速度可以较少考虑.
B/S 对安全以及访问速度的多重的考虑, 建立在需要更加优化的基础之上. 比C/S有更高的要求 B/S结构的程序架构是发展的趋势, 从MS的.Net系列的BizTalk 2000 Exchange 2000 等, 全面支持网络的构件搭建的系统. SUN 和IBM推的JavaBean 构件技术等,使 B/S更加成熟. 例如智赢IPOWER,采用AJAX和数据存储优化技术,相比一般B/S架构软件速度提高 30%至99%。
4.软件重用不同
C/S 程序可以不可避免的整体性考虑, 构件的重用性不如在B/S要求下的构件的重用性好.
B/S 对的多重结构,要求构件相对独立的功能. 能够相对较好的重用.就入买来的餐桌可以再利用,而不是做在墙上的石头桌子
5.系统维护不同
系统维护是软件生存周期中,开销大, ——-重要 C/S 程序由于整体性, 必须整体考察, 处理出现的问题以及系统升级. 升级难. 可能是再做一个全新的系统
B/S 构件组成,方面构件个别的更换,实现系统的无缝升级. 系统维护开销减到最小.用户从网上自己下载安装就可以实现升级.
6.处理问题不同
C/S 程序可以处理用户面固定, 并且在相同区域, 安全要求高需求, 与操作系统相关. 应该都是相同的系统
B/S 建立在广域网上, 面向不同的用户群, 分散地域, 这是C/S无法作到的. 与操作系统平台关系最小.
7.用户接口不同
C/S 多是建立的Window平台上,表现方法有限,对程序员普遍要求较高
B/S 建立在浏览器上, 通过WEB服务或其他公共可识别描述语言可跨平台,使用更灵活。不仅可应用在Window平台上,还可应用于unix/Linux等平台。
8.信息流不同
C/S 程序一般是典型的中央集权的机械式处理, 交互性相对低
B/S 信息流向可变化, B-B B-C B-G等信息、流向的变化, 更象交易中心。
B/S模式的优点和缺点:
1.B/S结构的优点:
(1)、具有分布性特点,可以随时随地进行查询、浏览等业务处理。
(2)、业务扩展简单方便,通过增加页面即可增加服务器功能。
(3)、维护简单方便,只需要改变网面,即可实现所有用户的同步更新。
(4)、共享性强
2.B/S 模式的缺点:
(1)、响应速度不及C/S,随着AJAX技术的发展,相比传统B/S结构软件提升一倍速度。
(2)、用户体验效果不是很理想,B/S需要单独界面设计,厂商之间的界面也是千差万别,由于浏览器刷新机制,使用时有刷屏现象,好在AJAX技术解决这一难题。
C/S 模式的优点和缺点
C/S 模式的优点:
1.由于客户端实现与服务器的直接相连,没有中间环节,因此响应速度较快。
2.C/S结构的管理信息系统具有较强的事务处理能力。
C/S 模式的缺点:
1.只适用于局域网。而随着互联网的飞速发展,移动办公和分布式办公越来越普及,这需要我们的系统具有扩展性。这种方式远程访问需要专门的技术,同时要对系统进行专门的设计来处理分布式的数据。
2.客户端需要安装专用的客户端软件。首先涉及到安装的工作量,其次任何一台电脑出问题,如病毒、硬件损坏,都需要进行安装或维护。特别是有很多分部或专卖店的情况,不是工作量的问题,而是路程的问题。还有,系统软件升级时,每一台客户机需要重新安装,其维护和升级成本非常高。
3.对客户端的操作系统一般也会有限制。可能适应于Win98, 但不能用于win2000或Windows XP。或者不适用于微软新的操作系统等等,更不用说Linux、Unix等。
十六:ORM框架是什么?
ORM(Object Relational Mapping)对象关系映射。 基于Java的持久化框架有Hibrtnate和iBATIS,MyBatis。
Java集合
线程&多线程
1.多线程的实现原理是将一个进程分成多个线程,然后让他们并发异步执行,来提高运行效率。
2.创建线程有三种方式。
* 继承Thread类,扩展线程(继承Thread类,覆盖run()方法;创建线程对象并用start()方法启动线程)
* 实现Runnable接口
* 通过Callable和Future创建线程
* 1.创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并有返回值。
* 2.创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
* 3.使用FutreTask对象作为Thread对象的target创建并启动新线程。
* 4.调用FuterTask对象的get()方法来获得子线程执行结束后的返回值。
3.创建线程的三种方式的对比
- 1.采用实现 Runnable、Callable 接口的方式创见多线程时,线程类只是实现了 Runnable 接口或 Callable 接口,还可以继承其他类。
- 2.使用继承 Thread 类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread() 方法,直接使用 this 即可获得当前线程。
4.我们都知道可以通过继承 Thread 类或者调用 Runnable 接口来实现线程,问题是,创建线程哪种方式更好呢?什么情况下使用它?这个问题很容易回答,如果你知道Java不支持类的多重继承,但允许你调用多个接口。所以如果你要继承其他类,当然是调用Runnable接口更好了。
5.在Java当中,线程通常都有五种状态,创建、就绪、运行、阻塞和死亡。
线程状态的转换关系:
6.多线程编程时,需要了解的几个概念:
- 线程同步
- 线程间通信
- 线程死锁
- 线程控制:挂起、停止和恢复
IO同步,异步
数据库优化思想
- MySQL分页查询:limit关键字,和spring-data-jpa的使用
客户端/服务端通信协议
MySQL客户端/服务端通信协议是“半双工”的:在任一时刻,要么是服务器向客户端发送数据,要么是客户端向服务器发送数据,这两个动作不能同时发生。一旦一端开始发送消息,另一端要接收完整个消息才能响应它,所以我们无法也无须将一个消息切成小块独立发送,也没有办法进行流量控制。
客户端用一个单独的数据包将查询请求发送给服务器,所以当查询语句很长的时候,需要设置max_allowed_packet参数。但是需要注意的是,如果查询实在是太大,服务端会拒绝接收更多数据并抛出异常。
与之相反的是,服务器响应给用户的数据通常会很多,由多个数据包组成。但是当服务器响应客户端请求时,客户端必须完整的接收整个返回结果,而不能简单的只取前面几条结果,然后让服务器停止发送。因而在实际开发中,尽量保持查询简单且只返回必需的数据,减小通信间数据包的大小和数量是一个非常好的习惯,这也是查询中尽量避免使用SELECT *以及加上LIMIT限制的原因之一。
查询缓存
数据库设计上的优化:
1.缓存和失效都会带来额外消耗。所有要判断是否使用缓存。
2.合理控制缓存空间大小,一般来说其大小设置为几十兆比较合适.
3.可以通过SQL_CACHE和SQL_NO_CACHE来控制某个查询语句是否需要进行缓存.
4.用多个小表代替一个大表,注意不要过度设计.
5.批量插入代替循环单条插入.
最后的忠告是不要轻易打开查询缓存,特别是写密集型应用。如果你实在是忍不住,可以将query_cache_type设置为DEMAND,这时只有加入SQL_CACHE的查询才会走缓存,其他查询则不会,这样可以非常自由地控制哪些查询需要被缓存。
数据库事务
事务是一系列的数据库操作的集合。要么全部执行,要么都不执行。
ACID特性是如何实现的:
- 原子性:想要保证事务的原子性,就需要在异常发生时,对已经执行的操作进行回滚,而在 MySQL 中,恢复机制是通过回滚日志(undo log)实现的,所有事务进行的修改都会先记录到这个回滚日志中,然后在对数据库中的对应行进行写入。
- 一致性:数据库对于 ACID 中的一致性的定义是这样的:如果一个事务原子地在一个一致地数据库中独立运行,那么在它执行之后,数据库的状态一定是一致的。
- 隔离性:四种隔离级别。①未提交读 read uncommitted 会出现脏读,不可重复读,幻读 ②已提交读 read commit 不可重复读,幻读 因为读取不阻止其他事务.导致前后两次读取不一样 ③重复读 repeatable read 读取操作会阻止update和delete.但是不能阻止insert.导致幻读 ④serializable 序列化.性能太低.事务按顺序执行.很少使用
- 持久性:事务的持久性就体现在,一旦事务被提交,那么数据一定会被写入到数据库中并持久存储起来。当事务已经被提交之后,就无法再次回滚了,唯一能够撤回已经提交的事务的方式就是创建一个相反的事务对原操作进行『补偿』,这也是事务持久性的体现之一。与原子性一样,事务的持久性也是通过日志来实现的,MySQL 使用重做日志(redo log)实现事务的持久性,重做日志由两部分组成,一是内存中的重做日志缓冲区,因为重做日志缓冲区在内存中,所以它是易失的,另一个就是在磁盘上的重做日志文件,它是持久的。
乐观锁和悲观锁的区别(事物)
-
悲观锁
悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。
悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。
Java synchronized 就属于悲观锁的一种实现,每次线程要修改数据时都先获得锁,保证同一时刻只有一个线程能操作数据,其他线程则会被block。
-
乐观锁
乐观锁(Optimistic Lock),顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。乐观锁适用于读多写少的应用场景,这样可以提高吞吐量。
乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。
乐观锁一般来说有以下2种方式:
1.使用数据版本(Version)记录机制实现,这是乐观锁最常用的一种实现方式。何谓数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据。
2.使用时间戳(timestamp)。乐观锁定的第二种实现方式和第一种差不多,同样是在需要乐观锁控制的table中增加一个字段,名称无所谓,字段类型使用时间戳(timestamp), 和上面的version类似,也是在更新提交的时候检查当前数据库中数据的时间戳和自己更新前取到的时间戳进行对比,如果一致则OK,否则就是版本冲突。
RESTful是什么
RESTful架构,就是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。
REST,即Representational State Transfer的缩写。我对这个词组的翻译是”表现层(表述性)状态转化”。REST指的是一组架构约束条件和原则。
REST的名称”表现层状态转化”中,省略了主语。”表现层”其实指的是”资源”(Resources)的”表现层”。
总结一下什么是RESTful架构:
(1)每一个URI代表一种资源;
(2)客户端和服务器之间,传递这种资源的某种表现层;
(3)客户端通过四个HTTP动词(get,post,put,delete),对服务器端资源进行操作,实现”表现层状态转化”。
mybatis
MyBatis是一个Java持久化框架,通过XML或者注解把对象与存储过程或SQL语句关联起来。
与其他的ORM框架(如hibernate)不同,mybatis(iBATIS)没有将Java对象和数据库表关联起来,而是提供SQL Maps和DAO将Java方法与SQL语句关联起来。
Spring
spring 是要跑在tomcat上
spring IOC,DI&AOP作用&原理(spring的核心概念是IOC和AOP,降低耦合)
-
IOC(inversion of control)控制反转
IOC一般分为两种类型:依赖注入(DI)和依赖查找(Dependency Lookup)。依赖注入应用比较广泛。
Spring IOC负责创建对象,管理对象(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所以来的对象的引用传递给它。也可以说,依赖被注入到对象中。
-
DI(dependence injection)依赖注入
Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。 采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。
依赖注入的实现方法有:
1.基于接口。
2.基于set方法。
3.基于构造函数。
4.基于注解。(主要用的就是这个 在私有变量前加@Autowired等注解来实现)
-
AOP(aspect oriented programming)面向切面编程(java的动态代理) AOP是基于动态代理实现的。
所谓”切面”,简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
-
动态代理的原理
SpringMVC 消息处理
核心架构的具体流程:
1.首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;
2.DispatcherServlet——>HandlerMapping, HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器)对象,通过这种策略模式,很容易添加新的映射策略;
3.DispatcherServlet——>HandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;
4.HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名);
5.ModelAndView的逻辑视图名——> ViewResolver, ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
6.View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
7.返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。
Spring Boot
是什么?
spring boot 是一个比spring 更加轻量级的一个框架。是spring的一个封装,内嵌了tomcat服务器,实现了自动配置。
spring大家都知道,boot是启动的意思。所以,spring boot其实就是一个启动spring项目的一个工具而已。从最根本上来讲,Spring Boot就是一些库的集合,它能够被任意项目的构建系统所使用。
为什么用spring boot?好处?
1.使编码变得更简单:spring boot采用java config的方式,对spring进行配置,并且提供了大量的注解,极大地提高了工作效率。
2.使配置变得更简单:spring boot提供许多默认配置,当然也提供自定义配置。但是所有spring boot的项目都只有一个配置文件:application.properties/application.yml。
3.使部署变得更简单:spring boot内置了三种servlet容器:tomcat,jetty,undertow。只需要一个java的运行环境就可以跑spring boot的项目了。spring boot的项目可以打成一个jar包,然后通过java -jar xxx.jar来运行。(spring boot项目的入口是一个main方法,运行该方法即可。 )
4.使监控变得简单 :spring boot提供了actuator包,可以使用它来对你的应用进行监控。
5.提供starter简化Manen配置:spring boot提供各种starter,其实就是一些spring bao的集合,只不过spring boot帮我们整合起来了而已。
什么是微服务框架
微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。微服务直接使用HTTP的API进行资源访问与操作。
比如我要开发一个购票系统。就可以简单的拆分为用户管理微服务和售票系统微服务。两个服务都可以独立运行,都有自己的数据库,他们之间通过restapi 进行通信。
而spring boot就是搭建微服务的一个很好的选择。
spring->spring boot->spring cloud微服务框架
dubbo分布式服务框架,微服务
dubbo基于RPC协议。
Dubbo的架构模块
- provider 服务提供者
- container 服务运行容器
- consumer 服务消费者
- registry 注册中心
- monitor 监控中心
spring cloud
spring cloud的主要模块有:
- Spring Cloud Netflix
- Spring Cloud Config:为分布式系统提供了配置服务器和配置客户端,通过对它们的配置,可以很好的管理集群中的配置文件。
- Spring Cloud Sleuth:服务跟踪框架,可以与Zipkin、Apache HTrace和ELK等数据分析、服务跟踪系统进行整合,为服务跟踪、解决问题提供了便利。
- Spring Cloud Stream:用于构建消息驱动微服务的框架,该框架在Spring Boot的基础上,整合了“Spring Integration”来连接消息代理中间件。
- Spring Cloud Bus:连接RabbitMQ、Kafka等消息代理的集群消息总线。
redis做缓存
加入maven依赖,配置redis数据库信息
在serviceimpl层实现缓存,实体类加上implements Serializable可序列化关键字
JVM
什么是JVM?
JVM是Java Virtual Machine(Java虚拟机)的缩写,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。由一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域等组成。JVM屏蔽了与操作系统平台相关的信息,使得Java程序只需要生成在Java虚拟机上运行的目标代码(字节码),就可在多种平台上不加修改的运行,这也是Java能够“一次编译,到处运行的”原因。
Java程序的执行过程:
Java源代码文件(.java文件)——>Java compiler(Java编译器)——>Java字节码文件(.class文件)——>类加载器(Class Loader)——>Runtime Data Area(运行时数据区)-> Execution Engine(执行引擎)。
运行时数据区包括:程序计数器,Java虚拟机栈,本地方法栈,方法区,堆。
- 1.程序计数器(Program Counter Register)用来指示程序执行哪一条指令,这跟汇编语言的程序计数器的功能在逻辑上是一样的。JVM规范中规定,如果线程执行的是非native方法,则程序计数器中保存的是当前需要执行的指令地址,如果线程执行的是native方法,则程序计数器中的值undefined。每个线程都有自己独立的程序计数器。为什么呢?因为多线程下,一个CPU内核只会执行一条线程中的指令,因此为了使每个线程在线程切换之后能够恢复到切换之前的程序执行的位置,所以每个线程都有自己独立的程序计数器。
- 2.Java虚拟机栈(VM Stack)Java虚拟机栈中存放的是一个个栈帧,当程序执行一个方法时,就会创建一个栈帧并压入栈中,当方法执行完毕之后,便会将栈帧移除栈。我们所说的“栈”是指Java虚拟机栈,一个栈帧中包括:局部变量表、操作数栈、动态连接、方法返回地址、附加信息
- 3.本地方法栈(Native Method Stack)本地方法栈与虚拟机栈所发挥的作用是非常相似的,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。与虚拟机栈一样,本地方法栈区域也会抛出StackOverflowError和OutOfMemoryError异常。
- 4.方法区(Method Area)方法区与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、以及编译器编译后的代码等。运行时常量池(Runtime Constant Pool)是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。在JVM规范中,没有强制要求方法区必须实现垃圾回收。很多人习惯将方法区称为“永久代”,是因为HotSpot虚拟机以永久代来实现方法区,从而JVM的垃圾收集器可以像管理堆区一样管理这部分区域,从而不需要专门为这部分设计垃圾回收机制。不过自从JDK7之后,Hotspot虚拟机便将运行时常量池从永久代移除了。
- 5.在C语言中,程序员可以通过malloc函数和free函数在堆上申请和释放空间。那么在Java中是怎么样的呢?Java中的堆是用来存储对象本身的以及数组(当然,数组引用是存放在Java栈中的),几乎所有的对象实例都在这里分配内存。在Java中,程序员基本不用去关心空间释放的问题,Java的垃圾回收机制会自动进行处理。另外,堆是被所有线程共享的,在JVM中只有一个堆。
JRE.JDK.JVM的关系
JRE(Java Runtime Environment, Java运行环境)是Java平台,所有的程序都要在JRE下才能够运行。包括JVM和Java核心类库和支持文件。
JDK(Java Development Kit,Java开发工具包)是用来编译、调试Java程序的开发工具包。包括Java工具(javac/java/jdb等)和Java基础的类库(java API )。
JVM(Java Virtual Machine, Java虚拟机)是JRE的一部分。JVM主要工作是解释自己的指令集(即字节码)并映射到本地的CPU指令集和OS的系统调用。Java语言是跨平台运行的,不同的操作系统会有不同的JVM映射规则,使之与操作系统无关,完成跨平台性。
JVM生命周期?
当启动一个Java程序时,一个虚拟机实例就诞生了,当程序关闭退出时,这个虚拟机实例随之消亡。JVM实例通过main()方法来运行一个Java程序。而这个main()方法必须是共有的(public)、静态的(static)、返回void,并且接收一个字符串数组为参数。Java程序初始类中的main()方法,将作为改程序初始线程的起点,任何其他线程都是由这个初试线程启动的。 JVM内部有两种线程:守护线程与非守护线程。守护线程通常是由虚拟机自己使用的,比如垃圾回收线程。当该程序所有的非守护线程都终止时,JVM实例将自动退出。
反射注解
什么是反射机制:
Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。
Java反射机制容许程序在运行时加载、探知、使用编译期间完全未知的classes。
换言之,Java可以加载一个运行时才得知名称的class,获得其完整结构。
Java反射机制提供的功能:
Java反射机制提供如下功能:
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判段任意一个类所具有的成员变量和方法
在运行时调用任一个对象的方法
在运行时创建新类对象
在使用Java的反射功能时,基本首先都要获取类的Class对象,再通过Class对象获取其他的对象。
Servlet
-
servlet是运行在web服务器或者应用服务器上的程序,是作为来自web浏览器或者其他HTTP客户端的请求和HTTP服务器上的数据库或者应用程序之间的中间层。
-
servlet的作用是收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
servlet执行以下主要任务:
- 读取客户端(浏览器)发送的显式的数据。包括网页上HTML表单,或者也可以是来自applet或者自定义的HTTP客户端程序的表单。
- 读取客户端(浏览器)发送的隐式的HTTP请求数据。包括cookie、媒体类型和浏览器能理解的压缩格式等。
- 处理数据并生成结果。这个过程可能会需要访问数据库,执行RMI或CORBA调用,调用web服务器,或者直接计算得出对应的响应。
- 发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML或XML)、二进制文件(GIF图像)、Excel等。
- 发送隐式的HTTP响应到客户端(浏览器)。这个包括告诉浏览器或者其他客户端被返回的文档类型,设置cookie和缓存参数,以及其他类似的任务。
servlet的生命周期:
- 通过调用 init () 方法进行初始化。
- 调用 service() 方法来处理客户端的请求。
- 通过调用 destroy() 方法终止(结束)。
- 最后由 JVM 的垃圾回收器进行垃圾回收。
JSP& freemaker
JSP:后端模板,用于输出前端页面。后缀.jsp
JSP 与 PHP、ASP、ASP.NET 等语言类似,运行在服务端的语言。
JSP(全称Java Server Pages)是由 Sun Microsystems 公司倡导和许多公司参与共同创建的一种使软件开发者可以响应客户端请求,而动态生成 HTML、XML 或其他格式文档的Web网页的技术标准。
JSP 技术是以 Java 语言作为脚本语言的,JSP 网页为整个服务器端的 Java 库单元提供了一个接口来服务于HTTP的应用程序。 freemaker:后缀.ftl常用的模板引擎
Java基本数据类型
- 1.byte 8位
- 2.short 16位
- 3.int 32位
- 4.long 64位
- 5.float 32位
- 6.double 64位
- 7.char 16位
- 8.boolean 1位
语法基础
一、Java类初始化顺序
这里是所有情况的类初始化顺序,如果实际类中没有定义则跳过:父类静态变量->父类静态代码块->子类静态变量->子类静态代码块->父类非静态变量->父类非静态代码块->父类构造函数->子类非静态变量->子类非静态代码块->子类构造函数。 基本顺序:(静态变量、静态初始化块)>(变量、初始化块)>构造器。
二、 值传递和引用传递
消息队列MQ
概述:
消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题。实现高性能,高可用,可伸缩和最终一致性架构。是大型分布式系统不可缺少的中间件。
常用的消息队列:
目前在生产环境,使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ等。
应用场景:
消息队列在实际应用中常用的使用场景。异步处理,应用解耦,流量削锋和消息通讯四个场景。
HR面
个人待遇方面需要了解的方面:
工资看岗位薪资略作调整。目前的情况和市场的情况是这个要求,只有是合理的,愿意按照公司岗位接收工资。
试用期,是否有试用期,试用期几个月,试用期期间工资是否80%,试用期期间五险一金是否缴纳
五险一金,虽然不是很懂,还是问一下五险一金的缴纳标准
上班时间,上班下班时间,中午休息时间,是否打卡
加班情况,平时是否加班,周末是否加班,加班是否有加班费或者调休
双休情况,个人要求一定要双休的公司,偶尔不可抗因素周末加班可以理解
晋升,主要指加薪方面,了解一下,以显示自己向上的精神和打算长期稳定在此公司发展的意愿。最后表示一切按照公司的规章制度来办。
以上,除了双休,其他条件了解就可以。不强求,具体情况具体分析。
Comments
Leave a comment