爱奇艺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,得多刷题呀。
#爱奇艺笔试##笔经##秋招##爱奇艺#
