冒泡排序
【基本思想】在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
【示例】
【算法实现】
/** 冒泡排序*/public class BubbleSort{ public static void main(String [] args){ int [] arr = {6,3,8,2,9,1}; for(int i=0; iarr[j+1]){ int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } }}复制代码
数据库常见问题
1.数据库查询常用SQL
查询每个班里成绩最高的学生:
分析: 先使用group by对表按照班级切分,然后使用max得出成绩最高的数据!
SELECT s.`name`,s.`stuId`,s.`sex`,c.`className`,r.`course`,MAX(r.`core`) AS core FROM
student s
INNER JOIN class c ON s.`classId` = c.`classId`
INNER JOIN score r ON s.`stuId` = r.`stuId`
GROUP BY c.`classId`
查询每个班里成绩第二的学生:
分析: 先查出每个班成绩第一的学生,然后使用Not in 查出除去每个班成绩第一的学生,最后查出剩下的学生中每个班成绩最高的学生。
SELECT NAME,stuId,sex,className,course,MAX(core) AS two FROM (
SELECT s.`name`,s.`stuId`,s.`sex`,c.`className`,r.`course`,r.`core` FROM
student s
INNER JOIN class c ON s.`classId` = c.`classId`
INNER JOIN score r ON s.`stuId` = r.`stuId`
) a WHERE core NOT IN (
SELECT MAX(r.`core`) AS core FROM
student s
INNER JOIN class c ON s.`classId` = c.`classId`
INNER JOIN score r ON s.`stuId` = r.`stuId`
GROUP BY c.`classId`
)
GROUP BY a.className
按照班级查询每个班上总分前三的学生:
SELECT * FROM(
SELECT s.`name`,s.`stuId`,s.`sex`,c.`className`,r.`course`,r.`core` FROM
student s
INNER JOIN class c ON s.`classId` = c.`classId`
INNER JOIN score r ON s.`stuId` = r.`stuId`
) a WHERE (
SELECT COUNT(*) FROM (
SELECT s.`name`,s.`stuId`,s.`sex`,c.`className`,r.`course`,r.`core` FROM
student s
INNER JOIN class c ON s.`classId` = c.`classId`
INNER JOIN score r ON s.`stuId` = r.`stuId`
) b WHERE a.className = b.className AND a.core < b.core
) <3
ORDER BY a.className,a.core DESC;
分数排序后排名在2-8的学生
SELECT * FROM score
ORDER BY core DESC LIMIT 1,7
按分数进行排名,排名从1开始,分数相同排名相同
//查询去重后分数的,条件:当前行分数大于等于同表的分数的count数量,去重显示,然后降序输出
SELECT core,
(SELECT COUNT(DISTINCT core)
FROM score
WHERE core>=s.core) AS Rank
FROM score AS s
ORDER BY core DESC;
用一条sql语句取出所有姓名重复的学生姓名和重复的记录数
SELECT NAME,COUNT(1) AS rnum FROM student
GROUP BY NAME
HAVING COUNT(1)>=2
ORDER BY rnum DESC
2.发现sql查询很慢,发现哪里出了问题,该怎么优化?
开启慢查询,查找哪些sql语句执行得慢。使用explain查看语句的执行计划,比如有没有使用到索引,是否启用了全表扫描等。查询慢,很大可能是因为没有使用索引或者索引没有被命中。还有其他的原因,比如发生了死锁,硬件、网速等原因。
优化手段:为相关列添加索引,并且确保索引可以被命中。优化sql语句的编写。
3.MySQL中的Join和UNion有什么区别?
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相同的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。默认情况下,UNION会过滤掉重复的值。使用 UNION ALL则会包含重复的值。
JOIN用于连接两个有关联的表,筛选两个表中满足条件(ON后的条件)的行记录得到一个结果集。从结果集中SELECT的字段可以是表A或者表B中的任意列。
JOIN常用的有LEFT JOIN、RIGHT JOIN、INNER JOIN。
LEFT JOIN会以左表为基础,包含左表的所有记录,以及右表中匹配ON条件的记录,对于未匹配的列,会以NULL表示。
LEFT JOIN会以右表为基础,包含左表的所有记录,以及右表匹配ON条件的记录,对于未匹配的列,会以NULL表示。
INNER JOIN,产生两个表的交集(只包含满足ON条件的记录)
INNER JOIN
FULL OUTER JOIN
LEFT JOIN
RIGHT JOIN和LEFT JOIN类似。
4.where和having的区别
WHERE过滤的是行,HAVING过滤分组。
WHERE能完成的,都可以用HAVING(只是有时候没必要)
WHERE在分组前对数据进行过滤,HAVING在分组后对数据进行过滤
WHERE后不能接聚合函数,HAVING后面通常都有聚合函数
5.SQL注入是什么?如何防止?
所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令。
比如在登录界面,如果用户名填入 'xxx'OR1=1--
就能构造下面的SQL语句,因为OR 1=1,password被注释掉,因此无论name和password填入什么都能登录成功。
select * from user name = 'xxx' or 1=1 -- and password = 'xxx'复制代码
使用PrepareStatement,可以防止sql注入攻击,sql的执行需要编译,注入问题之所以出现,是因为用户填写 sql语句参与了编译。使用PrepareStatement对象在执行sql语句时,会分为两步,第一步将sql语句 "运送" 到mysql上预编译,再回到java端拿到参数运送到mysql端。预先编译好,也就是SQL引擎会预先进行语法分析,产生语法树,生成执行计划,也就是说,后面你输入的参数,无论你输入的是什么,都不会影响该sql语句的语法结构了。用户填写的 sql语句,就不会参与编译,只会当做参数来看。从而避免了sql注入问题。
作者:junxia
如果您认为阅读这篇博客让您有些收获,欢迎扫描下方二维码关注我们,与我们交流互动。
本公众号专注Java面试题目的收集和解析以及【Web项目】源码的分享。
以下为公众号截图,欢迎小伙伴们的鼓励!