已学习知识点
待学习知识点
- java 注解:定义、解决什么问题、常用注解、元注解、自定义注解、注解运行原理、使用场景及案例
- Java泛型:定义、解决什么问题、使用场景、案例
- NIO:定义、与传统IO比较、IO模型(五种)、非阻塞IO/IO复用什么情况
- 反射和动态代理:定义、解决什么问题、使用场景及案例、cglib和jdk自带动态代理区别
- 多线程基础:进程和线程区别、如何解决线程安全问题、死锁及避免死锁方案、创建线程的方式有哪些
- CAS:定义说明、原理、ABA问题、如何解决ABA问题
- synchronized:定义说明、使用、实现原理、锁优化及原理、是否时公平锁and为什么
- AQS&ReentrantLock:公平锁与非公平锁、AQS作用/数据结构/实现细节/用在哪?
- 线程池:定义、参数说明、数据结构、实现逻辑、使用场景、使用案例
- ThreadLocal:定义、作用、使用场景、使用案例、数据结构、实现逻辑、如何避免内存泄露、为什么要使用虚引用
- 【CountDownLatch、CycleBarrier、Phaser 】、【ReentrantLock、ReentrantReadWriteLock、StampedLock】Semaphore、SynchronousQueue、ScheduledThreadPoolExecutor、PriorityBlockingQueue、LinkedBlockingQueue、ForkJoinPool、ConcurrentSkipListMap、ConcurrentHashMap、ArrayBlockingQueue实现原理
- List:为什么要用List、ArrayList 原理、扩容、线程安全、CopyOnWriteArrayList
- Map:1.7 和 1.8 HashMap 数据结构及各自存在哪些线程安全问题;1.7 和 1.8 ConcurrentHashMap数据结构;红黑二叉树结构及变化逻辑
- SpringMVC:干什么的?如何继承到tomcat中?入口类进入后都干了写什么?
- Spring基础:IOC和AOP、SpringBean的生命周期、了解什么周期的意义(了解生命周期后,项目中怎么去应用)、如何解决循环依赖问题
- Spring事务:Spring事务如何实现、事务的隔离级别与传递性
- SpringBoot:SpringBoot自动装载原理
- Mybatis:缓存、插件、如何集成到Spring、Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?
- Redis:数据类型及使用场景、分布式锁的实现、Redis为什么快、redis持久化、Redis主从复制、Redis 哨兵、Redis 分片集群、Codis、一致性hash、击穿、雪崩
- Mysql:执行Sql的过程、存储引擎、索引、InnoDB存储引擎结构、事务、事务安全问题、事务的四大特性及实现原理、隔离性如何实现、主从复制、调优
- JVM:为什么需要Java内存模型、Java从编译到执行发生了什么、双亲委派机制、Java内存模型、JVM内存结构、垃圾回收机制、CMS垃圾回收器、G1垃圾回收器、JVM调优
- 如何实现等幂和去重、HTTP、HTTPS协议原理,序列化与反序列化原理;
- 熟悉Mycat,Sharding-JDBC使用与基本原理
- RabbitMQ:基本特性、工作模型,以及确信机制,死信、延迟队列,服务端流控、消费端限流,可靠性投递与集群高可用原理;
- RocketMQ:基本原理,顺序消息、事物消息、延迟消息,存储设计理念与高可用架构设计;
- Kafka:架构与基本特性,消息传递原理(消息发送,存储与消费)
- 熟悉分布式理论:CAP、BASE,以及流控、负载均衡算法,熟悉分布式一致性协议:2PC、3PC、ZAB、Raft;
- Zookeeper: 数据结构、数据同步流程、以及选举机制,熟悉数据发布-订阅、分布式锁等使用场景;
- Apollo、Nocas、HBase、Hive、HDFS、Canal
- 熟悉分布式调度:任务调度Quartz与分布式任务调度Elastic-Job;
- 数据结构和算法:队列、堆、栈、树、哈希表、查找、排序、递归、动态规划等。
- presto、工作流任务调度系统:dolphinScheduler、可靠的分布式配置管理中心:Apollo Clickhouse
- 搜索引擎选择: Elasticsearch与Solr_carrots
- 开发工具:Git、maven、IDEA、chiner、EZDML、
2021.2.1 阿里一面
问题
- 实现一个线程池,没有代码提示,以下我当时的实现,一个字总结,“low”:
- 面试官点评:基本线程服用没有实现,线程是否能够多次start?
package test;
import java.util.concurrent.Executor;
public class FixedThreadPool extend Thread implements Executor {
// 线程列表
List<Thread> list;
//任务队列
ListedBlockedQueue<Runnable> queue = new ListedBlockedQueue();
private static final String LOCK = "lock";
public FixedThreadPool(int nThreads) {
list = new LinkedBlockedQueue(nThreads);
this.start();
}
public void run(){
while(true){
Runnable run = queue.take();
// 获取并从队列删除
Thread thread = list.getFirst();
thread.start(run);
}
}
public void execute(Runnable command) {
syncronized(LOCK){
if(list.size()<=0){
list.addLast(new AThread());
}
}
queue.put(command);
}
class AThread extend Thread{
private LinkedList list;
public AThread(LinkedList list){
this.list = list;
}
@Overwrite
public void run(){
super.run();
// 执行完任务,回收线程
list.addLast(this);
}
}
}
- 以下程序输出结果:
public class A {
public int a;
public A() {
a = 1;
test();
}
protected void test() {
System.out.println(a);
}
}
public class B extends A{
public int a;
public B() {
a = 2;
test();
}
public void test() {
System.out.println(a);
}
public static void main(String[] args) {
new B();
}
}
- 说一下最近做的项目
- 项目中的难点
- 项目中的技术栈,针对技术栈问问题
- redis哪些应用、缓存有效时间如何实现、雪崩
- PG数据库和MySql区别
- 项目中技术栈选型理由
- Spring中事物如何实现、事物隔离级别
- Spring 循环依赖如何解决
- 这一家公司和上一家公司
反思
- 阿里找的我,突如其来的面试,问的都是一些常见的问题,完全没有准备导致,需要时刻准备着。
- 让面试官有点无奈,技术东西问了一些就没有深问,业务上倒是聊了好一会儿。
- 让我也有些无奈,面试官属于可引导性的,根据我的回答问问题,无奈我舍技术东西都答不上来,都不知道往哪个方向引导,有一个条条大路通罗马,又偏偏选哪条都是死路的无奈。
- 二面1000%没戏
阿里2021.2.23
有点意外,不说阿里面试是有存档的么?面试两次阿里,感觉都发挥相当不理想,简历上也没有写太多东西,一个月被拉出来两次。上次面完后,准备了一下线程、Spring 事务及Mybatis的一些源码,感觉还不足以去面试,有点无奈,但是又不想放弃机会,所以只能硬着头皮上了,谁还没有一个阿里梦呢!
在面试前,给了一个在线测评题,如下:
线程题
有3个线程A/B/C,其中A、B个线程轮流打印1-100 中间如果是10的倍数,则由C线程打印;
要求在控制台输入如下内容:
线程A:1
线程B:2
线程A:3
……
线程C:10
……
线程?:99
线程C:100
package com.sy;
import java.util.Currency;
import java.util.function.Predicate;
/**
* 问题1:
* 评测题目: 有3个线程A/B/C,其中A、B个线程轮流打印1-100 中间如果是10的倍数,则由C线程打印;
* 要求在控制台输入如下内容:
* 线程A:1
* 线程B:2
* 线程A:3
* ……
* 线程C:10
* ……
* 线程?:99
* 线程C:100
*/
public class ExamOne {
/**
* 分析执行可能性:
* A -> B : A执行完,% 10 有余数
* A -> C :A执行完,% 10 无余数
* B -> A :B执行完,直接运行A
*/
public static void main(String[] args) {
AnswerOne.an swer ();
}
static class AnswerOne {
private static int count = 1;
private static final String CURRENT_THREAD = "";
public static void answer() {
}
class ThreadX extends Thread {
private Predicate<Void> canRun;
public ThreadX(String name, Predicate<Void> canRun) {
super(name);
this.canRun = canRun;
}
@Override
public void run() {
synchronized (CURRENT_THREAD) {
if (canRun.test(null)) {
System.out.println(getName() + ":" + count);
count++;
CURRENT_THREAD.notifyAll();
} else {
try {
CURRENT_THREAD.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}
算法题
输入一个字符串,输出该字符串中对称的子字符串的最大长度,比如输入字符串“12213”,由于该字符串里最长的对称子字符串是“1221”,因此输出为4.
package org.example;
/**
* 问题2:一、输入一个字符串,输出该字符串中对称的子字符串的最大长度,
* 比如输入字符串“12213”,由于该
* 字符串里最长的对称子字符串是“1221”,因此输出为4.
*/
public class ExamTwo {
public static void main(String[] args) {
String str = "89237171233211234561654321890";
int test = new ExamTwo().test(str);
System.out.println(test);
}
public int test(String str) {
int maxLength = 0;
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
int length = 0;
out: for (int j = 1; j < (chars.length - i) && i - j + 1 >= 0; j++) {
char left = chars[i - j + 1];
char right = chars[i + j];
if (left == right) {
length++;
if (maxLength < length) {
maxLength = length;
String substring = str.substring(i - j + 1, j + i + 1);
System.out.println(substring);
}
} else {
break out;
}
}
}
for (int i = 0; i < chars.length; i++) {
int length = 0;
out: for (int j = 1; j < (chars.length - i) && i - j >= 0; j++) {
char left = chars[i - j];
char right = chars[i + j];
if (left == right) {
length++;
if (maxLength < length) {
maxLength = length;
String substring = str.substring(i - j, j + i + 1);
System.out.println(substring);
}
} else {
break out;
}
}
}
return maxLength;
}
}