创建JDBC步骤
① 导入jar包
② 注册驱动
③ 获取数据库连接
④ 获取执行者对象
⑤ 执行sql语句并返回结果
⑥ 处理结果
⑦ 释放资源
并发事务带来的问题以及如何解决
脏读:一个事务读取了另一个事务修改但未提交的数据。
丢失修改:数据被两个事务连续修改,第一个事务的修改丢失了。
不可重复读,一个事务连续读两次数据,但结果不一样。(两次读之间,数据被其他事务修改)。
幻读:一个事务连续读两次数据,读取数据量不一样。(两次读之前,数据被其他事务删除或新增)。
事务隔离级别:
1、读未提交。可以读取尚未提交的数据。能导致脏读,不可重复读,幻读。
2、读已提交。允许读取并发事务已经提交的数据。导致不可重复读,幻读。
3、可重复读。意义在哪????对同一字段,多次读取结果一致。导致幻读。
不可重复读很容易让人陷入一个思维定式那就是 我干嘛需要多次读取一个值还要保证一致
要跳出这个思维看本质:我在事务中会不会受到其他事务的影响?
举个简单的例子 数据校对(只是举个例子体现意思 不用太在意具体的业务)
我要取当前的余额 当前的账单 上个月的余额 我要检验一下数据对不对
我在事务中取了当前的账单和上个月的余额,好嘛,这时候又有新的订单提交了,我再获取余额是不是就不一致了?
4、串行化。所有事务,依次执行。没啥问题。(这个串行化是针对行锁的,不同行的事务可以并发)
设置隔离级别之后,并不是不能并发,而是并发的时候,一个事务的修改数据(绝对读到,提交的才能读到。提交不提交,更新的数据都读不到。提交不提交,增删的数据都读不到),什么时候才能被另一个事务读到。但彼此的逻辑操作没有影响。
Innodb和Myisam的区别(4点)及各自适合的操作
1、MyISAM不支持事务,而Innodb支持事务。
2、Myisam是表级锁,而Innodb是行级锁。
3、外键支持:mysiam表不支持外键,而InnoDB支持。
4、count运算:myisam缓存有表的行数,这种缓存只是表行的总数,where筛选无效。而Innodb没有。
MyISAM适合:(1)做很多count 的计算;(2)读密集;(3)没有事务。
InnoDB适合:(1)要求事务;(2)写密集(3)高并发
请简要说一下Request的常用方法(随意5个)
setAttribute(String name,Object):设置名字为name的request的参数值
getAttribute(String name):返回由name指定的属性值
getAttributeNames():返回request对象所有属性的名字集合,结果是一个枚举的实例
getCookies():返回客户端的所有Cookie对象,结果是一个Cookie数组
getCharacterEncoding():返回请求中的字符编码方式
getContentLength():返回请求的Body的长度
getHeader(String name):获得HTTP协议定义的文件头信息
getHeaders(String name):返回指定名字的request Header的所有值,结果是一个枚举的实例
getHeaderNames():返回所以request Header的名字,结果是一个枚举的实例
getInputStream():返回请求的输入流,用于获得请求中的数据
getMethod():获得客户端向服务器端传送数据的方法
getParameter(String name):获得客户端传送给服务器端的有name指定的参数值
getParameterNames():获得客户端传送给服务器端的所有参数的名字,结果是一个枚举的实例
getParameterValues(String name):获得有name指定的参数的所有值
getProtocol():获取客户端向服务器端传送数据所依据的协议名称
getQueryString():获得查询字符串
getRequestURI():获取发出请求字符串的客户端地址
getRemoteAddr():获取客户端的IP地址
getRemoteHost():获取客户端的名字
getSession([Boolean create]):返回和请求相关Session
getServerName():获取服务器的名字
getServletPath():获取客户端所请求的脚本文件的路径
getServerPort():获取服务器的端口号
removeAttribute(String name):删除请求中的一个属性
HAVNG 子句 和 WHERE 的异同点?
1. 语法上:where 用表中列名,having 用 select 结果别名
2. 影响结果范围:where 从表读出数据的行数,having 返回客户端的行 数
3. 索引:where 可以使用索引,having 不能使用索引,只能在临时结果 集操作
4. where 后面不能使用聚集函数,having 是专门使用聚集函数的
MySQL 中 InnoDB 引擎的行锁是通过加在什么上完成(或称实现) 的?
InnoDB 行锁是通过给索引上的索引项加锁来实现的,这一点 MySQL 与 Oracle 不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB 这 种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB 才使用行级锁,否则,InnoDB 将使用表锁!
什么是 ORM 框架?简要说说什么是mybatis框架以及它的好处
对象关系映射(Object-Relational Mapping,简称ORM),
指的是持久化数据和实体对象的映射模式,为了解决面向对象与关系型数据库存在的互不匹配的现象的技术。
ORM:对象关系映射,将表以及表中的数据映射成类和对象。
表--->类
表中的字段--->类中的属性
表中的数据--->类的对象
mybatis, hibernate 这样的框架 通过 指定 表与 java类的对应关系, 就可以实现 将数据封装到java 类的对象中去, 这 就称之为 对象关系 映射, 这样的 框架就称之为 ORM 框架.
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
(1)Mybatis对JDBC对了封装,可以简化JDBC代码。
(2)Mybatis支持连接池(也可以配置其他的连接池),因此可以提高程序的效率
(3)Mybatis是将SQL配置在mapper文件中,修改SQL只是修改配置文件,类不需要重新编译。
(4)对查询SQL执行后返回的ResultSet对象,Mybatis会帮我们处理,转换成Java对象。
(2)1、是一个持久层框架,封装了原始的jdbc操作。2、mybatis支持xml和注解两种方式配置sql。3、mybatis支持ORM思想封装执行sql的结果。
mysql 的行锁和表锁的区别?
表级锁:开销小,加锁快,不会出现死锁。锁定粒度大,发生锁冲突的概率最高,并发量最低。
行级锁:开销大,加锁慢,会出现死锁。锁力度小,发生锁冲突的概率小,并发度最高。
MyISAM 只支持表锁,InnoDB 支持表锁和行锁,默认为行锁。
mysql 的内连接、左连接、右连接有什么区别?
内连接关键字:inner join;左连接:left join;右连接:right join。
内连接是把匹配的关联数据显示出来;左连接是左边的表全部显示出来,右边的表显示出符合条件的数据;右连接正好相反。
谈一下对于MyBatis中缓存的理解,并说明缓存何时被创建,何时被清除,如果不清楚缓存会产生什么问题
MyBatis缓存分为一级缓存和二级缓存.
一级缓存是SqlSession级别的缓存,在操作数据库时需要构造sqlSession对象,在对象中使用HashMap存储缓存数据,不同的sqlSession之间的缓存数据区域是互相不影响的.在用户发起查询请求时将查询信息添加到一级缓存中,并在进行增删改操作时清空缓存,如果不清除缓存的话就会产生脏读问题.
二级缓存是mapper级别的缓存,当多个SqlSession去操作同一个Mapper的sql语句时就可以共用二级缓存了,二级缓存是跨SqlSession的,默认不启用二级缓存
Mybatis存在xml文件开发和注解开发方式,对于xml文件开发简单说明下常用的除增删改查之外的标签及其作用,对于注解开发简单说明下常用的除增删改查外的注解及其作用
XML:
(1)sql,include:对SQL语句进行抽取,提高复用性
(2)resultMap:用来描述如何从数据库结果集中来加载对象,处理多表查询
(3)if,where和foreach:用于动态生成SQL语句
(4)mapper:映射配置文件根标签,用于生成sql映射
注解:
(1)Results,Result:映射查询结果集到实体类属性
(2)Param:用于给参数起名字,确定参数的顺序传递
(3)SelectProvider:用于生成查询用的SQL语句
(4)Options:返回自增主键的数据
简述下java中线程的分类并简单进行说明
(1)java中线程分为守护线程和用户线程两种,通过Thread.setDaemon(boolean on)方法进行设置
(2)守护线程是一种特殊的线程,在后台默默地完成一些系统性的服务,比如垃圾回收(Garbage Collection)线程、运行时编译JIT(Just In Time)线程都是守护线程。与之对应的是用户线程,用户线程可以理解为是系统的工作线程,例如main线程,自己new出来的线程都叫用户线程,它会完成这个程序需要完成的业务操作。如果用户线程全部结束了,意味着程序需要完成的业务操作已经结束了,系统可以退出了。所以当系统只剩下守护进程的时候,java虚拟机会自动退出。
java类的加载过程(Class文件的加载过程)
加载
把类的class文件到内存中。将读取到.classs数据存储到运行时内存区的方法区。然后将其转换为一个与目标类型对应的java.lang.Class对象实例。这个Class对象在日后就会作为方法区中该类的各种数据的访问入口。
链接
验证
确保被加载的类(.class文件的字节流),是否按照java虚拟的规范。不会造成安全问题,主要要验证字节流是否符合 Class文件格式的规范, 井且能被当前版本的执行,保证其描述的信息符合Java语言规范的要求, 确定语义是合法的。符号逻辑的
准备
主要是为类变量(注意,不是实例变量)分配内存,并且赋予初值,此时的赋值是Java虚拟机根据不同变量类型的默认初始值:
如8种基本类型的初值,默认为0;引用类型的初值则为null;
解析
将类的二进制数据中的符号引用替换成直接引用(符号引用是用一组符号描述所引用的目标;直接引用是指向目标的指针)
初始化
初始化,则是为标记为常量值的字段赋值的过程。换句话说,只对static修饰的变量或语句块进行初始化。如果初始化一个类的时候,其父类尚未初始化,则优先初始化其父类。如果同时包含多个静态变量和静态代码块,则按照自上而下的顺序依次执行
类的加载方式之间的异同
类名.Class和ClassLoader.loadeClass(“全类名”)得到的class是还没有链接的,所以没有初始化,如果类中有静态代码块也不会执行
Class.forName(“全类名”)得到的class会初始化, 如果父类尚未初始化,则优先初始化其父类。如果同时包含多个静态变量和静态代码块,则按照自上而下的顺序依次执行
new一个类的实例,然后通过对象名.getClass得到是已经初始化过的
美团面试题:单例模式懒汉式和饿汉式有哪些区别?
单例模式:
1)建本类的对象,即私有化构造函数
2)在本类中定义一个静态的且公共的对象或者方法工其他的类调用.
饿汉式:就是在本类中定义一个静态的且公共的本类对象,即接创建出类的实例对象, 简单来说就是空间换时间,因为上来就实例化一个对象,占用了内存,(也不管你用还是不用)所以线程上是安全的
懒汉式: 就是在本类中定义一个静态的发方法,在方法中可以创建出类的实例对象 需要的时候调用静态方法创建类的实例,因为调用时才创建对象所以多个线程调用时会创建多个对象,导致单例失效,线程不安全.
JavaScript中双等号和三等号的区别
双等号(==) 只进行值的比较, 不比较类型, 值相同就可以, 类型可以不一样
而三等号(===)会对值和类型同时比较, 只有同时相同才是真的相同
内部类根据在类中的位置不同分为三种
1. 成员内部类: 在类的成员位置
2. 局部内部类: 在方法中
3. 匿名内部类: 在方法中,是一种简化的写法
Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
第一种是使用<resultMap>标签,逐一定义数据库列名和对象属性名之间的映射关系。
第二种是使用sql列的别名功能,将列的别名书写为对象属性名。
有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。
java中有哪些变量,这些变量中有哪些存在线程安全问题,为什么?
java中有三大变量,分别是实例变量,静态变量和局部变量.
局部变量在栈中,所以局部变量永远不会共享,不存在线程安全问题.
而实例变量和静态变量分别在堆和方法区中,它们是多线程共享的,所以存在安全问题.
map集合中,get()方法的实现原理
先调用hashcode()方法得出哈希值,通过哈希算法转换成数组下标,通过数组下标快速定位到某个位置上,如果这个位置上什么也没有,返回null,如果这个位置上有单向链表,那么就会拿着参数K和单向链表上的每个节点中的K进行equals比较,如果所有的equals方法返回false,那么get()方法返回null,只要有一个节点的K和参数K进行equals比较时返回true,那么此时这个节点的value就是我们要找的value,get()方法最终返回这个要找的value值.
GET请求和POST请求的区别
(1)GET请求:
请求参数会在浏览器的地址栏中显示,所以不安全;
请求参数长度限制长度在1K之内;
GET请求没有请求体,无法通过request.setCharacterEncoding()来设置参数的编码;
(2)POST请求:
请求参数不会显示浏览器的地址栏,相对安全;
请求参数长度没有限制;
JavaScript中有几种原始数据类型
共有六种,分别是boolean(布尔类型,true或false),null(声明null值的特殊关键字),undefined(代表变量未定义),number(整数或浮点数),string(字符串),bigint(大整数).
jQuery中使用什么方法对标签的文本内容进行操作?
主要有html()方法\text()方法\val()这三种方法.
调用html()方法并传递参数表示设置内容体html代码,不传参表示获取内容体html代码.
调用text()方法并传递参数表示设置内容纯文本,不传参表示获取内容体纯文本.
调用val()方法并传递参数表示设置输入框中的内容,不传参表示获取输入框中的内容.
简单描述一下JVM的内存结构
分为Java堆,方法区,程序计数器,Java栈,本地方法栈.
方法区和对是所有线程共享的内存区域;而java栈、本地方法栈和程序计数器是运行是线程私有的内存区域。
Java堆(Heap),是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。
方法区(Method Area),方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
程序计数器(Program Counter Register),程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。
JVM栈(JVM Stacks),与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stacks)也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
本地方法栈(Native Method Stacks),本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。
命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
本地方法栈(Native Method Stacks),本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。