前言:数据库和前端也是Java面试比较常见的两部分,这里就写在一篇文章里了。。本篇文章可能并不详尽,但也基本涵盖了面试中可能会问到的点。。
第一部分:数据库部分
1.数据三大范式
第一范式(1NF):字段具有原子性,不可再分。所有关系型数据库系统都满足第一范式)数据库表中的字段都是单一属性的,不可再分。例如,姓名字段,其中的姓和名必须作为一个整体,无法区分哪部分是姓,哪部分是名,如果要区分出姓和名,必须设计成两个独立的字段。
第二范式(2NF):是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。
要求数据库表中的每个实例或行必须可以被唯一地区分。通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键。
第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是非主属性非部分依赖于主关键字。
第三范式的要求如下:
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。
所以第三范式具有如下特征:
1,每一列只有一个值
2,每一行都能区分。
3,每一个表都不包含其他表已经包含的非主关键字信息。
2.数据库优化
答:因为我做的项目比较偏向互联网化,所以数据库sql写得不多,但是我知道有一些优化的规则,下面我就谈谈
1)用PreparedStatement(预编译) 一般来说比Statement性能高:一个sql 发给服务器去执行,涉及步骤:语法检查、语义分析, 编译,缓存
2)有外键约束会影响插入和删除性能,如果程序能够保证数据的完整性,那在设计数据库时就去掉外键。——尽量减少外键
3)索引
建立索引,提高效率
避免对索引字段进行计算操作
避免在索引字段上使用not,<>,!=
避免在索引列上使用IS NULL和IS NOT NULL
避免在索引列上出现数据类型转换
避免在索引字段上使用函数
避免建立索引的列中使用空值。
4)避免select *,因为select * 会在解析的过程中将通配符*转换成所有列名,是通过查询数据字典完成的。
5)用EXISTS替代IN、用NOT EXISTS替代NOT IN (因为in和not in都会对子查询的表进行全表遍历),eg:
(高效)SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND EXISTS (SELECT ‘X’ FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB’)
(低效)SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB’)
6)通常情况下, 用UNION替换WHERE子句中的OR将会起到较好的效果. 对索引列使用OR将造成全表扫描. 注意, 以上规则只针对多个索引列有效(没有索引反而是OR效率高).
7)union all替代union(如果可以的话,因为union会去重)
8)在where子句中应把最具限制性的条件放在最前面。
where子句中字段的顺序应和索引中字段顺序一致。
9)explain关键字可以解释复杂sql语句运行的过程。explain select ______________
10)数据库的优化,包括合理的事务隔离级别、SQL语句优化、索引优化;使用缓存、尽量减少数据库IO;分布式数据库、分布式缓存等
3.查询语句的关键字
语法顺序:select--from--where--group by--having--order by
执行顺序:from--where--group by--having--select--order by
其中select和from是必须的,其他则是可选的。having表示已经分组的数据进行过滤~ having可以使用聚合函数(sum, count等),而where不行。
4.表连接
left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录
right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录
inner join(等值连接) 只返回两个表中联结字段相等的行
举例如下:
--------------------------------------------
表A记录如下:
aID aNum
1 a20050111
2 a20050112
3 a20050113
4 a20050114
5 a20050115
表B记录如下:
bID bName
1 2006032401
2 2006032402
3 2006032403
4 2006032404
8 2006032408
--------------------------------------------
1.left join
sql语句如下:
select * from A
left join B
on A.aID = B.bID
结果如下:
aID aNum bID bName
1 a20050111 1 2006032401
2 a20050112 2 2006032402
3 a20050113 3 2006032403
4 a20050114 4 2006032404
5 a20050115 NULL NULL
(所影响的行数为 5 行)
结果说明:
left join是以A表的记录为基础的,A可以看成左表,B可以看成右表,left join是以左表为准的.
换句话说,左表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录(例子中为: A.aID = B.bID).
B表记录不足的地方均为NULL.
--------------------------------------------
2.right join
sql语句如下:
select * from A
right join B
on A.aID = B.bID
结果如下:
aID aNum bID bName
1 a20050111 1 2006032401
2 a20050112 2 2006032402
3 a20050113 3 2006032403
4 a20050114 4 2006032404
NULL NULL 8 2006032408
(所影响的行数为 5 行)
结果说明:
仔细观察一下,就会发现,和left join的结果刚好相反,这次是以右表(B)为基础的,A表不足的地方用NULL填充.
--------------------------------------------
3.inner join
sql语句如下:
select * from A
innerjoin B
on A.aID = B.bID
结果如下:
aID aNum bID bName
1 a20050111 1 2006032401
2 a20050112 2 2006032402
3 a20050113 3 2006032403
4 a20050114 4 2006032404
结果说明:
很明显,这里只显示出了 A.aID = B.bID的记录.这说明inner join并不以谁为基础,它只显示符合条件的记录.
5.分页、去重的sql
MySql: "QUERY_SQL limit ?,?" 使用limit关键字,第一个"?"是起始行号, 第二个"?"是返回条目数 (注意第二个并非结束行号,这里容易答错。。)
Oracle:SELECT * FROM
( SELECT A.*, ROWNUM RN FROM
(QUERY_SQL ) A WHERE ROWNUM
<= ?) WHERE RN >= ? 结合rownum关键字,利用嵌套三层select 语句实现。第一个"?"表示终止行号,第二个"?"表示起始行号
去重:
mysql: distinct, group by
6.数据库事务
数据库事务transanction正确执行的四个基本要素。ACID,原子性(Atomicity)、一致性(Correspondence)、隔离性(Isolation)、持久性(Durability)。
原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。 是指事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行 相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请 求,使得在同一时间仅有一个请求用于同一数据。
持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
第二部分:前端
其实对于搞Java的孩子来说,前端问得并不会太多,但是还是会问。以下是我遇到的几个比较生僻的点,仅供参考~
1. undefined和null的区别
在JavaScript中存在这样两种原始类型:Null与Undefined。这两种类型常常会使人困惑……
Undefined类型只有一个值,即undefined。当声明的变量还未被初始化时,变量的默认值为undefined。
Null类型也只有一个值,即null。null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。
var val; alert(val == undefined); // "true"
这段代码显示为true,代表val的值即为undefined,因为我们没有初始化它。
alert(null == document.getElementById('notExistElement'));
当页面上不存在id为"notExistElement"的DOM节点时,这段代码显示为"true",因为我们尝试获取一个不存在的对象。
alert(typeof undefined); // "undefined" alert(typeof null); // "object"
第一行代码很容易理解,undefined的类型为Undefined;第二行代码却让人疑惑,为什么null的类型又是Object了呢?
在今天我们可以解释为,null即是一个不存在的对象的占位符,但是在实际编码时还是要注意这一特性。
alert(null == undefined); // "true"
ECMAScript认为undefined是从null派生出来的,所以把它们定义为相等的。但是,如果在一些情况下,我们一定要区分这两个值,那应该怎么办呢?可以使用下面的两种方法。
alert(null === undefined); // "false" alert(typeof null == typeof undefined); // "false"
使用typeof方法在前面已经讲过,null与undefined的类型是不一样的,所以输出"false"。而===代表绝对等于,在这里null === undefined输出false。
2.如何给动态生成的元素绑定事件?
答:用delegate
delegate() 方法为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。
使用 delegate() 方法的事件处理程序适用于当前或未来的元素(比如由脚本创建的新元素)。
$(parentSelector).delegate(childSelector,event,data,function) //其中data是可选的,表示执行function时传入的一些额外参数,其他都是必选的。关于delegate,之前我的博客文章有提过。
3.如何用jquery判断某个dom是否存在?
if($(selector).length>0)而不是简单的if($selector)~
var c = 3;
var a;
var b =null;
alert(c + a);//NaN
alert(c + b);//3