面试
文章目录
- 面试
- 自我介绍
- 基础
-
- int类型的取值范围
- String底层为什么是final修饰的
- final关键字
- 面向对象
- 向上转型和向下转型
- Java自动类型转换
- Java数据类型自动提升(注意以下讨论的是二元操作符)
- 抽象类和接口的区别
- 静态代码块,构造代码块和构造函数的执行顺序
- 反射
-
- Java中利用反射获取对象的方式有:
- 异常
- 集合
-
- ArrayList动态数组扩容机制
- HashMap的结构
- hashTable, hashMap, concerrentHashMap
- HashMap的遍历
- HashMap的动态删除
- 理解和使用Java8中的时间API
- JVM
-
- 可达性分析
- 双亲委派模型
- Java对象的创建过程
- Java类的生命周期
- 垃圾回收算法与垃圾回收器
- 调优命令
- 逃逸分析和栈上分配
-
- 栈上分配
- 逃逸分析
- 什么是Stop The World什么是OopMap什么是安全点/li>
- 什么是指针碰撞么是空闲列表么是TLAB/li>
- 多线程
-
- Java中实现多线程有几种方法
- 线程池
- 线程死锁
- wait()和notify()
- wait()和sleep()区别
- sychronized关键字
- volitle关键字
- ThreadLocal关键字
- Lock
- countDownLatch
- 框架
-
- JDBC
- Mybatis
- Servlet
- SpringMVC
- Spring
-
- Bean的生命周期
- IOC
- 循环依赖
- AOP
- 数据库
-
- 数据库引擎 Innodb 和 myisam 区别
- InnoDB的B+树结构(mysq数据库中的索引结构)
- 深入了解MySQL数据库的索引及底层结构
-
- 导致SQL执行慢的原因/li>
- 慢sql问题解决入口:
- 什么是索引/li>
- 索引类型:
- 索引的种类:
- MySQL聚集索引和非聚集索引的区别/li>
- 哈希索引:
- B+TREE索引:
- 联合索引以及联合索引的失效问题
- 数据库连接池只有100个连接,有3000个连接请求
- 数据库锁
-
- MySQL锁概述
- 数据库的三种锁特性
- 什么是锁/li>
- 什么是死锁
- 数据库死锁出现的案列
- 如何处理死锁/li>
- 如何避免死锁/li>
- innodb默认是如何对待死锁的/li>
- 如何开启死锁检测/li>
- 什么是全局锁的应用场景有哪些/li>
- 使用全局锁会导致的问题/li>
- 如何处理逻辑备份时,整个数据库不能插入的情况/li>
- innodb如何实现行锁/li>
- 什么是共享锁/li>
- 什么是排他锁/li>
- 悲观锁和乐观锁的区别/li>
- 乐观锁有什么优点和缺点/li>
- innodb存储引擎有几种算法/li>
- 优化锁方面的意见/li>
- mysql数据库读写分离原理
- mysql主从复制机制
- redis中的数据类型和数据结构
- redis主从复制机制
- 并发
-
- redis和数据库双写一致性问题
-
- 1.先更新数据库,再更新缓存(有脏数据,不采用)
- 2.先删缓存,再更新数据库(有脏数据,不采用,可用延时双删策略解决)
- 3.延时双删策略(可以采用)
- 4.先更新数据库,再删缓存(可以采用)
- 高并发情况下如何保证数据安全
- 高并发情况下如何保证系统安全
- 高并发情况下如何解决redis雪崩和穿透
- 事务
-
- ACID
- Spring 和 数据库 事务的隔离级别
- 传播行为
- Spring事务什么时候会失效/li>
- 分布式事务控制
-
- TPC
- TCC
- 幂等性
- 工具
-
- Nginx
- rabbitMQ
-
- rabbitmq生产
- rabbitmq消费
- kafka
-
- kafka生产
- kafka消费
- kafka如何确保数据不丢失
- kafka怎么保证消息的消费顺序/li>
-
- kafka保证消息顺序有2种方法。
- RabbitMQ和Kafka的区别
- kafka的优势
- Zookeeper
-
- 什么是ZooKeeper
- zookeeper 都有哪些功能/li>
- zookeeper 有三种部署模式:
- zookeeper 怎么保证主从节点的状态同步/li>
- 设计模式
- 络
-
- HTTP和HTTPS的区别
- HTTP和TCP的区别和联系
-
- TCP连接
- HTTP连接
- 相互联系和区别
自我介绍
At first, Thank you so much for giving me this opportunity for this interview.
My name is XXX, and you can call me Alex Leon which is my English name.
I graduated from Shanghai Maritime University with bachelor’s degree at 2016, I have worked for two companies, have been engaged in Java development for about five years
I passed CET4 during my college years,and I got Java Software Development Special Skill Certificate at 2019 , which is issued by the (MIIT)Ministry of industry and information technology, Now I am studying and preparing for the exam of software designer.
I have good foundation and coding practice of Java, and also I know the skills of Groovy, Mysql and Oracle, Im familiar with popular framework such as Spring, SpringBoot, SpringMVC, SpringCloud, Mybatis, and Grails, and I often use the tools like Kafka, RabbitMq, Redis and Nginx
The latest project I participated is SPDB(Shanghai Pudong Development Bank) ecosystem marketing project, with framework springBoot, springCloud and grails. it is distributed and microserviced.
Im good at learning new technologies, I love coding, I love programming, and I always keep a good self-drive for learning.
CitiBank is a large and international company, on the other hand, I have similar project experience of bank, so I really hope to join Citibank
Thank you so much
各位面试官好, 我叫XXX,16年毕业于上海海事大学毕业, 毕业之后一直在上海发展,一共呆过两家公司,从事java开发工作5年左右
我的大概情况是: 参加工作前两年从事企业传统项目,主要是ERPCRM这些生产管理系统,用到的技术点主要是传统的单体框架,SSM框架,数据库是mysql。
后来这两年参与浦发银行生态圈项目,涉及分布式和微服务的架构
我近期参与的项目是浦发银行生态圈营销系统
主要功能是为浦发银行所有生态产品,比如手机银行app、浦惠到家app、浦慧app、甜橘app等,为这些产品提供制券和活动页面配置的管理端系统,以及这些h5活动页面的运行时服务支持
采用微服务分布式架构,开发语言采用的是groovy, 框架使用的是grails框架,包管理工具使用的是gradle, 同时集成了springCloud的相关组件
平时我喜欢看一些源码,会去github或者gitee逛一些开源项目, 也租了服务器购买和备案域名并搭建了一些个人项目,比如主页,在线简历,浏览器搜索页等
19年通过了工信部专项技能认证java开发工程师的考试, 21年去年我参加了国家软考软件设计师考试, 下午题目考了62发挥不错,上午题目就差5分就能通过
所以今年第一个目标就是换个工作,第二个目标就是能通过软考
基础
int类型的取值范围
-2^31 ~ 2^31 – 1
String底层为什么是final修饰的
- 1.为了实现字符串池
只有字符串是不可变的,才有可能实现。,节省heap空间。但如果字符串是可变的,如果变量改变了它的值,那么其它指向这个值的变量的值也会一起改变。
- 2.为了线程安全
只有字符串是不可变的,,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步,字符串本身就是线程安全的。
- 3.为了实现String可以创建HashCode不可变性
只有字符串是不可变的,则在它,并且不会在每次调用 String 的 hashcode 方法时重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。
- 4.为了系统安全
而且String类中的很多方法的实现不是Java代码,而是调用完成的,如果String类不被final修饰,被继承重写方法的话,系统会很不安全。
虽然final修饰代表了不可变,但仅仅是不可变,并不代表了数组本身不会变
final关键字
final关键字可以修饰类,方法和变量:
- 被final修饰的类不能被继承,即它不能拥有自己的子类;
- 被final修饰的方法不能被重写;
- final修饰的变量,无论是类变量、实例变量、参数变量(形参)还是局部变量,都需要进行初始化操作。
面向对象
重视对象思维,关注每个对象需要做什么,而不是关注过程和步骤
-
封装:
明确标识出允许外部使用的所有成员函数和数据项
内部细节对外部调用者透明,外部调用无需修改或者关心内部实现的细节
-
继承
继承基类的方法,并作出自己的改变和扩展
子类共性的方法或者属性(抽取出来)直接使用继承的父类的,不需要自己再定义,只需扩展自己个性化的
-
多态
基于对象所属类的不同,外部对同一个方法的调用,实际执行的逻辑不同,使得程序更易扩展
多态有个条件就是继承,多态和继承是一脉相承的
多态的条件:继承,方法重写,父类引用指向子类对象
使用引用变量调用的方法实际上是子类重写的方法,而不是父类的
弊端:多态调用方法不能是子类特有/独有的方法,因为能调用的方法必须是重写父类的方法,所以父类中没有的方法不能调用。
向上转型和向下转型
所以我们常说的向上转型,其实就是多态,即父类引用指向子类对象,此时调用方法实际上使用的是子类的实现, 而子类独有的方法是无法调用的
但如果将该变量强制类型转换成子类(向下转型)后,就可以使用子类特有的方法
Java自动类型转换
- 两种类型是彼此兼容的
- 转换的目的类型占得空间范围一定要大于转化的源类型
正向过程:由低字节向高字节自动转换
byte->short->int->long->float->double
逆向过程:使用强制转换,可能丢失精度。
int a=(int)3.14;
Java数据类型自动提升(注意以下讨论的是二元操作符)
Java定义了若干使用于表达式的类型提升规则:
- 所有的byte型. short型和char型运算后将被提升到int型(例外: final修饰的short, char变量相加后不会被自动提升。)
- 如果一个操作数是long形 计算结果就是long型;
- 如果一个操作数是float型,计算结果就是float型;
- 如果一个操作数是double型,计算结果就是double型;
另一种归纳方式(《Java核心技术卷I》P43):
- 如果两个操作数其中有一个是double类型,另一个操作就会转换为double类型。
- 否则,如果其中一个操作数是float类型,另一个将会转换为float类型。
- 否则,如果其中一个操作数是long类型,另一个会转换为long类型。
- 否则,两个操作数都转换为int类型。
抽象类和接口的区别
区别 | 抽象类 | 接口 |
---|---|---|
默认的方法实现 | 它可以有默认的方法实现 | 接口完全是抽象的,所有方法都必须是抽象的,java1.8之后允许接口有默认实现 |
实现方式 | 子类使用extends关键字来继承一个抽象类,如果子类不是抽象类的话,那么子类必须实现父类所有的抽象方法的具体实现 | 实现类使用implements关键字来实现接口,它需要提供接口中所有声明的方法的具体实现 |
构造器 | 抽象类可以有构造器 | 接口不能有构造器 |
与正常Java类的区别 | 除了你不能实例化抽象类之外,它几乎和正常的类没有任何区别 | 接口是完全不同的类型 |
访问修饰符 | 抽象方法可以是public、protected和default这些修饰符 | 接口里的方法默认修饰符是public,也只能是public |
普通变量 | 抽象类可以对变量没有限制,和正常类一样 | 接口中的变量必须是public static final的 |
多继承性 | 由于java单继承局限,当继承了抽象类,就不能继承其他的类了 | 一个类可以实现多个接口,并且对你继承另一个类时,没有限制 |
添加新的方法 | 你可以往抽象类中添加新的正常方法,并且你不需要改变你现在的代码 | 如果你往接口中添加新的方法,那么你必须在实现了该接口的类中实现接口的新方法 |
静态代码块,构造代码块和构造函数的执行顺序
静态代码块:最早执行,类被载入内存时执行,只执行一次。没有名字、参数和返回值,有关键字static。
构造代码块:执行时间比静态代码块晚,比构造函数早,和构造函数一样,只在对象初始化的时候运行。没有名字、参数和返回值。
构造函数:执行时间比构造代码块时间晚,也是在对象初始化的时候运行。没有返回值,构造函数名称和类名一致。
注意:静态代码块在类加载的时候就执行,所以的它优先级高于main()方法。
下面我们看一下有继承时的情况:
可以看出:父类始终先调用(继承先调用父类),并且这三者之间的相对顺序始终保持不变。
到此貌似没什么问题,但是请看如下变形:
因为b1、b2、b3用static修饰,与静态块处于同一优先级,同一优先级就按先后顺序来执行。
反射
在运行时动态获取调用或修改类信息,属性,方法。
Java中利用反射获取对象的方式有:
- a)类名.class,不会加执行态代码块
- b)Class.forName(“包名.类名”) ,会执行静态代码块
- c)类的实例对象.getClass(),会执行静态代码块
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!