学习目标:
每天2-3到简单sql(刷完即止),每天复习代码随想录上的题目3道算法(时间充足可以继续),背诵的八股的问题也在这里记录了
今日碎碎念:
1)偶尔还是贪玩游戏,但是进度有在往前,八股计划准备这些,计网,JVM,JUC,Java基础与集合,MySQL,Redis,Spring和Spring Boot,整体下来,热门的能准备到70%就开投。
2)昨天周日,休息一天。
3)哎还有科三科四没考,只能约到3月15号的,刚好一边准备面试。
4)简历修改完毕
力扣刷题
SQL
力扣1280:1280. 学生们参加各科测试的次数
解答思路:
1)这道题其实有点难度
2)首先我们得清楚,科目表跟考试表不一定是对应的,也就是说,可能我有四个科目,但是我只有三门考试,因此我们得先按照学生表和科目表,将所有的可能的组合结果查询出来,这里就得使用Cross join交叉查询
3)其次,我们得找到考试表里面每位学生参与的考试科目以及该科目的考试次数,以学生id和科目来分组,才方便计算每位学生参与当前科目考试的次数,count(*)即可
4)然后,我们要展示所有的科目,将前面交叉查询出来的结果要和考试表进行连接查询,而如果某些科目不在考试科目表中的话,说明查询结果是NULL,因此此时我们要使用一个函数IFNULL来检测是否为空,为空我们需要将结果置为0
5)最后,根据学生id和科目名进行排序
select
s.student_id,s.student_name,sub.subject_name,IFNULL(g.attended_exams,0) as attended_exams
from
Students as s
cross join
Subjects as sub
left join (
select student_id,subject_name,count(*) as attended_exams
from Examinations
group by student_id,subject_name
) as g
ON s.student_id = g.student_id AND sub.subject_name = g.subject_name
ORDER BY s.student_id, sub.subject_name;
力扣570:570. 至少有5名直接下属的经理
解答思路:
1)这题要做出来是简单的,自连接加having即可
# 很明显这是一个自连接的查询
select e1.name
from
Employee as e1
inner join Employee as e2
on e1.id != e2.id and e1.id = e2.managerId
group by e1.id
having count(*) >= 5
另一个做法
1)首先查询每个人的下属员工数。将两份 Employee 表用 join 操作连接。Manager 表代表经理,Report 表代表下属,每对 Manager.Id=Report.ManagerId 的情况代表此经理的一名下属。再根据 Manager.Id 分组,对 Report.Id 求和得到每个经理对应的下属数量。
2)然后where筛选即可
select Name
from (
select Manager.Name as Name, count(Report.Id) as cnt
from
Employee as Manager join Employee as Report
on Manager.Id = Report.ManagerId
group by Manager.Id
) as ReportCount
where cnt >= 5
作者:力扣官方题解
链接:https://leetcode.cn/problems/managers-with-at-least-5-direct-reports/solutions/2366332/zhi-shao-you-5ming-zhi-jie-xia-shu-de-ji-syvu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
力扣1934:1934. 确认率
解答思路:
1)这道题我认为对我很有价值,训练到了之前提到的几点:
1.1)函数:round,sum,count
1.2)左连接
1.3)子查询
1.4)分组
1.5)行列转换
2)解释一下我做这道题的思路:
2.1)首先要求确认率,那么得先清楚某个用户发消息的总数是多少,确认到的消息有多少
2.2)题目中给了两个表,一张用户注册表,一张用户确认信息的表,我们得搞清楚一个点,用户注册,不一定会接受信息,因此极有可能,用户表里面的id可能不一定会出现在信息确认表里面,即如果用户表id有12345,而确认信息表里面可能只会出现id为123的用户的消息确认情况
2.3)那么我们得使用连接才能解决,我这里使用左连接,将用户id查询出来,这里我们按照用户id分组,便于统计每个用户的消息确认情况
2.4)接下来如何查询到某个用户发消息的总数是多少,确认到的消息有多少呢?
2.4.1)行列转换里面,前两天的博客里面道1661. 每台机器的进程平均运行时间,这道题就有用到这样的思路,case 列名 when 内容是什么 then 显示的结果 end
2.4.2)然后使用IFNULL判断是否为空,为空我们就置为0
2.4.3)使用sum和count来得到结果即可
2.5)将2.4的查询出来的作为结果,然后我们就可以去计算确认率了
2.5.1)直接使用round函数来限制精度即可
select
res.user_id,
round(res.confirmed / res.sum,2) as confirmation_rate
from(
select
s.user_id,
sum(IFNULL(case action when 'confirmed' then 1 end,0)) as confirmed,
count(IFNULL(case action when 'confirmed' then 1 end,0)) as sum
from Signups as s
left join Confirmations as c
on s.user_id = c.user_id
group by s.user_id
)as res
力扣1251:1251. 平均售价
解答思路:
1)这道题其实也不难,左连接右连接都是可以的,这里注意一点就是,不要把日期判断放到where里面,否则会展示不出来左连接的部分内容
select
p.product_id,
IFNULL(round(sum(p.price * u.units) / sum(units),2),0) as average_price
from Prices as p
left join UnitsSold as u
on
u.product_id = p.product_id
and
p.start_date <= u.purchase_date and u.purchase_date <= p.end_date
group by p.product_id
算法
力扣242:242. 有效的字母异位词
解答思路:
1)看注释即可
class Solution {
public boolean isAnagram(String s, String t) {
int[] record = new int[26];
for (int i = 0; i < s.length(); i++) {
record[s.charAt(i) - 'a']++; // 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了
}
for (int i = 0; i < t.length(); i++) {
record[t.charAt(i) - 'a']--;
}
for (int count: record) {
if (count != 0) { // record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。
return false;
}
}
return true; // record数组所有元素都为零0,说明字符串s和t是字母异位词
}
}
力扣349:349. 两个数组的交集
解答思路:
哈希表解决即可,用下标来代表元素也是很常见的操作
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
//简单点的做法就是使用哈希表,我们定义两个哈希表,然后去分别统计每个数组的元素有啥
int[] hash1 = new int[1002];
int[] hash2 = new int[1002];
for(int i : nums1)
hash1[i]++;
for(int i : nums2)
hash2[i]++;
//新建立一个数组用来返回最终数据
List<Integer> resList = new ArrayList<>();
for(int i = 0;i < 1002;i++){
//当两个表中有的元素就填入链表中
if(hash1[i] > 0 && hash2[i] > 0){
resList.add(i);
}
}
int index = 0;
//将链表里面的数据填入即可
int res[] = new int[resList.size()];
for(int i : resList)
res[index++] = i;
return res;
}
}
力扣202:202. 快乐数
解答思路:
1)如注释
class Solution {
//我们要想到如何才能取出一个数的每一位?
//基本上离不开取模以及×和÷
public boolean isHappy(int n) {
//同时题目提到可能会无限循环,即结果可能会一直重复出现,因此我们使用哈希来做
Set<Integer> set = new HashSet();
//因此,如果我们发现n不为1,并且n不在结果里面,就一直去判断
while(n != 1 && !set.contains(n)){
set.add(n);
n = count(n);
}
return n == 1;
}
public int count(int n){
//这个函数的作用就是取出每一位来平方
int res = 0;
while (n > 0) {
int temp = n % 10;
res += temp * temp;
n = n / 10;
}
return res;
}
}
八股
计算机网络
Java基础
1.说一下Java的面向对象,对面向对象的理解
2.JDK,JRE,JVM三者区别和联系
3.深拷贝和浅拷贝区别了解吗,什么是深拷贝和浅拷贝?什么是引用拷贝?
4.sleep和wait区别
5.JAVA中几种基本数据类型是什么,各自占用多少字节?
MySQL
1.执行一条select语句期间发生了什么
2.如何处理慢查询
3.MySQL的隔离级别有哪些?
Redis
1.为什么要用Redis?
2.Redis为什么快?
3.Redis与memcached相对有哪些优势?
4.Redis常用的数据类型