笔试 - 开科唯识

有点挫败,50 打车大老远跑一趟,笔试做了一个半小时,结果一句没通过连人都没见到。

客观来说题不算难但也算不上简单,面试体验真的差,特别讨厌在纸上写代码算法题

1. 根据年月日输出这是一年中的第几天(只能用 int,不能用 date)

    public static int calculateDays(int year, int month, int day) {
        int sumDays = 0;
        switch (month) {
            case 12:
                sumDays += 30;
            case 11:
                sumDays += 31;
            case 10:
                sumDays += 30;
            case 9:
                sumDays += 31;
            case 8:
                sumDays += 31;
            case 7:
                sumDays += 30;
            case 6:
                sumDays += 31;
            case 5:
                sumDays += 30;
            case 4:
                sumDays += 31;
            case 3:
                if (year % 400 == 0 || year % 4 == 0 && year % 100 != 0) sumDays += 29;
                else sumDays += 28;
            case 2:
                sumDays += 31;
            case 1:
                sumDays += day;
        }
        return sumDays;
    }

    public static void main(String[] args) throws ParseException {
        int year = 2024;
        int month = 7;
        int day = 22;

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = simpleDateFormat.parse(year + "-" + month + "-" + day);
        Calendar instance = Calendar.getInstance();
        instance.setTime(date);
        System.out.println(instance.get(Calendar.DAY_OF_YEAR));
        System.out.println(calculateDays(year, month, day));
    }

2. 在有序数组中查找指定元素

二分查找,唯一一个把代码写正确的题

3. 打印菱形

// 当 n = 1,2,3 时,分别打印出如下图案
*

 *
***
 * 

  *
 ***
*****
 *** 
  *

还以为有什么高深的巧妙地算法,结果只是拼凑,上半部分和下半部分,空白部分和*
如果就这样真的毫无技术含量

// 一个看起来没那么低级的写法
    public static void printDiamond(int n) {
        if (n <= 0) {
            System.out.println("n should be a positive integer");
            return;
        }

        int totalRows = 2 * n - 1; // Total number of rows in the diamond

        for (int i = 0; i < totalRows; i++) {
            int stars = i < n ? 2 * i + 1 : 2 * (totalRows - i - 1) + 1;
            int spaces = (totalRows - stars) / 2;

            StringBuilder sb = new StringBuilder();
            for (int j = 0; j < spaces; j++) {
                sb.append(" ");
            }
            for (int j = 0; j < stars; j++) {
                sb.append("*");
            }
            System.out.println(sb.toString());
        }
    }

如果是打印空心菱形的话,则是计算出中心点的坐标

// 关键是这句
if (Math.abs(i - center) + Math.abs(j - center) == center)
   System.out.print("* ");

4. 合并两个有序链表

合并有序链表

5. 数据库事务是什么?什么情况下使用?举例说明死锁的情况

死锁举例

6. SQL 题

  1. 卡片表 CARD:CNO 卡号,NAME 姓名,CLASS 班级
  2. 图书表 BOOKS:BNO 书号,BNAME 书名,BTYPE 书类别,AUTHOR 作者,PRICE 单价,QUANTITY 库存册数
  3. 借阅记录表 BORROW:CNO 借书卡号,BNO 书号,RDATE 还书日期

限定每人每种书只能借一本,库存册数随借书、还书而改变

  1. 找出借书超过 5 本的读者,输出 借书卡号 及 所借图书册数

    因为是对按照借书卡号分组后的结果做筛选,所以需要用到HAVING

    SELECT cno,count(bno) FROM borrow GROUP BY cno having count(bno) > 5;
    
  2. 查询当前借了《计算方法》但是没有借《计算方法习题集》的读者,输出其借书卡号,并按卡号降序排序输出

    为什么不能在同一个查询中直接对 bname 进行两次相互排斥的条件筛选?

    SELECT card.cno FROM `borrow` join `card` on card.cno = borrow.cno join books on borrow.bno=books.bno where bname ='计算方法' and bname not in ('计算方法习题集') ;
    

    因为WHERE作用于单条记录,对于单条记录而言,这两个条件是互斥的,同一条记录不可能同时满足两个条件,所以最终结果肯定是什么都查不到

    那我们只能比如先查出所有借了《计算方法》的结果集,然后再排除掉其中借了《计算方法习题集》的记录

    SELECT DISTINCT borrow.cno FROM	borrow JOIN books ON borrow.bno = books.bno 
    WHERE books.bname = '《计算方法》' 
    	AND cno NOT IN ( SELECT borrow.cno FROM borrow JOIN books ON borrow.bno = books.bno WHERE books.bname = '《计算方法习题集》' ) 
    ORDER BY cno DESC;
    
  3. 将‘C01’班同学所借图书的还款都延长一周

    关键是不知道操作日期的函数

    UPDATE borrow set return_date = DATE_ADD(return_date,INTERVAL '1' week)
    where cno in(SELECT cno FROM card WHERE class='C01');
    
  4. 从 BOOKS 表中删除当前无人借阅的图书记录

    DELETE FROM BOOKS WHERE BNO NOT IN (SELECT DISTINCT BNO FROM BORROW);
    
  5. 如果经常按照 书名、书类别 查询出图书的 作者、单价 信息,应该以哪些字段来建立索引

    考虑这里,假如 类别 字段重复度较高,可以拿极端情况下的 男女 来类比,这里是不是就不应该在类别上面建立索引

    所以我的想法是只在书名上建立索引

posted @ 2024-07-19 15:16  YaosGHC  阅读(43)  评论(0编辑  收藏  举报