爱奇艺8.22Java后端笔经
1.选择题
数据结构、java、python、Spring、微服务等相关
2.SQL
题目如下:
* 现有如下MySQL数据表,请写出合适的SQL语句,查询出女生数量最多的前三个专业名称和对应的女生人数?(gender字段说明:1为男,2为女)。要求查询结果的表头如subject_name, girl_count。 * * 大学学生基本信息表Student_Info * * id name gender * 1 Kate 2 * 2 Mary 2 * 3 Tom 1 * 4 Jim 1 * 5 Lily 2 * 6 Rose 2 * 7 Lucy 2 * 8 Meimei 2 * 专业信息登记表Subject_Register * * student_id subject_id * 1 1 * 2 2 * 3 3 * 4 3 * 5 2 * 6 4 * 7 4 * 8 4 * 专业基本信息表Subject_Info * * id name * 1 Math * 2 English * 3 Computer * 4 News
我自己写的...
select Subject_Info.name as subject_name,count(gender) as girl_count from Student_Info,Subject_Register,Subject_Info where Subject_Info.id=Subject_Register.subject_id and Subject_Register.student_id=Student_Info.id and gender=2 group by Subject_Info.name order by girl_count limit 0,3
写的时候忘了排序,卧槽!0ac(下面这个应该也许大概是对的吧)
select Subject_Info.name as subject_name,count(gender) as girl_count from Student_Info,Subject_Register,Subject_Info where Subject_Info.id=Subject_Register.subject_id and Subject_Register.student_id=Student_Info.id and gender=2 group by Subject_Info.name order by girl_count desc limit 0,3
3. 算法题1
在监控与BI报表系统中,我们经常会采集数据指标进行分析,这里的数据往往都是时序数据,对于时序数据,我们可以用一个数组来表示,例如数组下标表示时间顺序,数组的值表示采集的指标数据大小。现在作为分析师的你,得到如下一个任务:在给定一个整数形式的时序数据,求出这个时序里最大的振幅(“落差”)(振幅 = 时序里相邻的“波峰”与“波谷”相差绝对值) 输入描述 一个数组,下标代表x轴的时间顺序,数组里的每个数值代表y轴的具体值 输出描述 整个曲线的相邻波峰与波谷的最大振幅落差
只AC了75%,剩下的不知道问题在哪...
public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String line = scanner.nextLine(); String[] stringList = line.split(","); int[] arr = new int[stringList.length]; for (int i = 0; i < arr.length; i++) { arr[i] = Integer.parseInt(stringList[i]); } //这里arr就是输入源... process(arr); } /** * 输入... * 2,2,3,8,8,6,5,10,7,6 * 1,2,3,8,5,3,6 * 1,2,3,4,5,6 * * @param arr */ public static void process(int[] arr) { int left = 0, right = 1; int max = Integer.MIN_VALUE; for (; left < arr.length && right < arr.length; ) { //符号,是正数还是负数呢? int sign = (arr[right] - arr[right - 1]) >= 0 ? 1 : -1; for (; right < arr.length; ) { int sign0 = (arr[right] - arr[right - 1]) >= 0 ? 1 : -1; if (sign0 == sign) { //更新... max = Math.max(Math.abs(arr[right] - arr[left]), max); right++; } else { left = right - 1; break; } } } System.out.println(max); }
4. 算法题2-n皇后问题
AC100%,DFS搜索就行...
/** * n皇后问题... */ public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String str = scanner.next(); int n = Integer.parseInt(str.substring(2)); List<List<String>> list = new ArrayList<>(); List<char[]> charsList = new ArrayList<>(); //初始化Chars列表为. for (int i = 0; i < n; i++) { char[] rowVal = new char[n]; Arrays.fill(rowVal, '.'); charsList.add(rowVal); } process(0, charsList, list, n); System.out.println(list); } public static void process(int row, List<char[]> charList, List<List<String>> res, int n) { if (row == n) { List<String> strings = new ArrayList<>(); for (char[] chars : charList) { String str = new String(chars); strings.add(str); } res.add(strings); return; } //对应行的...遍历每一列... for (int col = 0; col < n; col++) { //如果row,col位置不合法,那么continue... if (!isValid(charList, row, col, n)) { continue; } //做选择... (charList.get(row))[col] = 'Q'; process(row + 1, charList, res, n); //取消选择... (charList.get(row))[col] = '.'; } } public static boolean isValid(List<char[]> charsList, int row, int col, int n) { for (int i = col; i >= 0; i--) { //如果当前这一行已经出现了Q,那么return false if ((charsList.get(row))[i] == 'Q') { return false; } } for (int i = row; i >= 0; i--) { //如果当前列出现了Q,return false if ((charsList.get(i))[col] == 'Q') { return false; } } //检验左上角 int i = row, j = col; for (; i >= 0 && j >= 0; i--, j--) { if ((charsList.get(i))[j] == 'Q') { return false; } } //检验右上角... i = row; j = col; for (; i >= 0 && j < n; i--, j++) { if ((charsList.get(i))[j] == 'Q') { return false; } } return true; }
5.多线程
/** * 假设有这么一个类: * <p> * class ZeroAndEvenOdd { * public ZeroAndEvenOdd(int n) { ... } // 构造函数 * public void printZero(printNumber) { ... } // 仅打印出 0 * public void printEven(printNumber) { ... } // 仅打印出 偶数 * public void printOdd(printNumber) { ... } // 仅打印出 奇数 * } * 相同的一个 ZeroAndEvenOdd类实例将会传递给三个不同的线程: * <p> * 线程 A 将调用 printZero(),它只输出 0 。 * <p> * 线程 B 将调用 printEven(),它只输出偶数。 * <p> * 线程 C 将调用 printOdd(),它只输出奇数。 * <p> * 每个线程都有一个 printNumber 方法来输出一个整数。请修改给出的代码以输出整数序列 010203040506... ,其中序列的长度必须为 2n。 * <p> * 输入描述 * 整数n * <p> * 输出描述 * 输出整数序列 010203040506... ,输出整数序列 010203040506... ,其中序列的长度必须为 2n * <p> * <p> * 样例输入 * 5 * 样例输出 * 0102030405 * * @author wanna * @version v1.0 */
用一个volatile变量current标识当前的到达的数字,用一个volatile变量who表示去唤醒别的线程去打印奇数/偶数,who=1打印0,who=2打印偶数,who=3打印奇数,who=1时打印0并且根据current是奇数还是偶数去唤醒who=2或者who=3的线程。(其实不是唤醒,for循环等着current到达n,有点耗费CPU,应该也可以使用ReentrantLock.Condition去解决)
AC100%...
public class Main { public static void main(String[] args) { final Scanner reader = new Scanner(System.in); int n = reader.nextInt(); ZeroEvenOdd zeroEvenOdd = new ZeroEvenOdd(n); new Thread(() -> { try { zeroEvenOdd.printZero(System.out::print); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); new Thread(() -> { try { zeroEvenOdd.printEven(System.out::print); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); new Thread(() -> { try { zeroEvenOdd.printOdd(System.out::print); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } } class ZeroEvenOdd { private int n; private volatile int current = 1; private volatile int who = 1; public ZeroEvenOdd(int n) { this.n = n; } // printNumber.accept(x) outputs "x", where x is an integer. //打印0,accept(x)输出x...x是个int类型... public void printZero(IntConsumer printNumber) throws InterruptedException { for (; current <= n; ) { if (who == 1) { printNumber.accept(0); //如果是奇数,那么唤醒...condition3 if ((current & 1) == 0) { who = 3; } else { who = 2; } } } } //打印偶数 public void printEven(IntConsumer printNumber) throws InterruptedException { for (; current <= n; ) { if (who == 2) { printNumber.accept(current++); who = 1; } } } //打印奇数 public void printOdd(IntConsumer printNumber) throws InterruptedException { for (; current <= n; ) { if (who == 3) { printNumber.accept(current++); who = 1; } } } }
下面补充使用Condition去解决
public class Main { public static void main(String[] args) { final Scanner reader = new Scanner(System.in); int n = reader.nextInt(); ZeroEvenOdd zeroEvenOdd = new ZeroEvenOdd(n); Thread t1 = new Thread(() -> { try { zeroEvenOdd.printZero(System.out::print); } catch (InterruptedException e) { e.printStackTrace(); } }); new Thread(() -> { try { zeroEvenOdd.printEven(System.out::print); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); new Thread(() -> { try { zeroEvenOdd.printOdd(System.out::print); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); //需要等待t2和t3已经被挂起了才启动t1... try { TimeUnit.MILLISECONDS.sleep(10); t1.start(); } catch (InterruptedException e) { e.printStackTrace(); } } } class ZeroEvenOdd { private final int n; private volatile int current = 1; ReentrantLock lock = new ReentrantLock(); Condition condition1 = lock.newCondition(); //控制打印0的线程 Condition condition2 = lock.newCondition(); //控制打印2的线程 Condition condition3 = lock.newCondition(); //控制打印1的线程 public ZeroEvenOdd(int n) { this.n = n; } // printNumber.accept(x) outputs "x", where x is an integer. //打印0,accept(x)输出x...x是个int类型... public void printZero(IntConsumer printNumber) throws InterruptedException { lock.lock(); try { //current即使到达了n,也得唤醒,因为即将打印的就是n,必须得唤醒啊... for (; current <= n; ) { printNumber.accept(0); //如果是偶数,唤醒condition2,如果是奇数,唤醒condition3 ((current & 1) == 0 ? condition2 : condition3).signal(); condition1.await(); } } finally { lock.unlock(); } } //打印偶数 public void printEven(IntConsumer printNumber) throws InterruptedException { lock.lock(); try { //current到达n就得break掉,已经结束了... for (; current < n; ) { //等着... condition2.await(); //如果当前是偶数,打印并且唤醒condition1 printNumber.accept(current++); condition1.signal(); } } finally { lock.unlock(); } } //打印奇数 public void printOdd(IntConsumer printNumber) throws InterruptedException { lock.lock(); try { //current到达n就得break掉,已经结束了... for (; current < n; ) { //等着... condition3.await(); //如果当前是奇数,那么打印并唤醒condition1 printNumber.accept(current++); condition1.signal(); } } finally { lock.unlock(); } } }
需要注意的是,需要保证线程t1要等线程t2和t3都启动了才去唤醒,不然t2和t3出现后先唤醒后阻塞可唤醒不了...
总结:我是fw,得多刷题呀。
#爱奇艺笔试##笔经##秋招##爱奇艺#