个人的一些面试题

3 篇文章 0 订阅
1 篇文章 0 订阅

jdk和jre区别

jre是运行Java程序时的环境,jdk时编译Java代码的工具,包括一些简单的库

Oracle jdk和 open jdk的区别

前者更新慢后者更新快,前者是被收购后的,后者是被收购前的

Java 和javax区别

javax是拓展的,后来两个合在一起了

线程的启动方式

实现 Runnable 接口,继承 Thread 类

如果一个类继承 Thread类,则不适合于多个线程共享资源,而实现了 Runnable 接口,就可以方便的实现资源的共享。

集合的类型,哪些有序无序

list,set,map,queue,
list有序,set和map无序
set底层是map,map是key和value
set的值唯一,list的值可以不唯一,map下标唯一,值不唯一

hashmap底层

底层就是一个哈希表
jdk1.8之前,使用数组+链表的形式
jdk1.8之后,冲突小于8用数组+链表的形式,>=8使用红黑树
为什么不用平衡二叉树?因为平衡二叉树在特定情况下还是线性树
然后设置容量的话,就是幂指的形式了

MySQL调优

emmm

事务的特性

4个特性,acid
ACID,指数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)

GC垃圾回收算法

常用的有标记清除复制标记整理分代收集算法

标记清除

标记清除算法就是分为“标记”和“清除”两个阶段。标记出所有需要回收的对象,标记结束后统一回收。这个套路很简单,也存在不足,后续的算法都是根据这个基础来加以改进的。

其实它就是把已死亡的对象标记为空闲内存,然后记录在一个空闲列表中,当我们需要new一个对象时,内存管理模块会从空闲列表中寻找空闲的内存来分给新的对象。

人话:把已经死亡,已经没用的对象标记,然后记录在一个空闲列表中,当要new一个对象时,从空闲的内存中拿。
在这里插入图片描述

复制算法

将内存平均划分为2边,一边空,一边用。用的一边就平常使用,垃圾的,未用的,还在用的,都放一起,然后满的时候,就清除垃圾,把还在用的放在另一边,自己这一边就全部清空
在这里插入图片描述

标记整理算法

复制算法在对象存活率高的时候会有一定的效率问题,标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉边界以外的内存
在这里插入图片描述

分代收集算法

这种算法并没有什么新的思想,只是根据对象存活周期的不同将内存划分为几块。一般是把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记-清理”或者“标记-整理”算法来进行回收。

人话:就是把内存划分出来,没批空间放不同的类型,然后哪些空间就按照上面的算法去清除

三范式

第一范式:即表的列的具有原子性,不可再分解,即列的信息,不能分解。
人话:每个字段分得不能再分下去了,已经是最小元素了

第二范式:满足第一范式得情况下,有主键就是第二范式

第三范式:满足第二范式得情况下,非主键字段不能相互依赖

MySQL用了什么引擎

Innodb:默认、支持事务安全,支持行级锁,用于增改,

默认的,
支持事务,是事务安全的,提供行级锁与外键约束,有缓冲池,用于缓冲数据和索引

适用场景:用于事务处理,具有ACID事物支持,应用于执行大量的insert和update操作的表

MyISAM:不支持事务、外键、锁,用于查

不支持事务,不支持外键约束,不支持行级锁,操作时需要锁定整张表,不过会保存表的行数,所以当执行select count(*) from tablename时执行特别快

适用场景:用于管理非事务表,提供高速检索及全文检索能力,适用于有大量的select操作的表,如 日志表

MEMORY:用于精准查找

使用存在于内存中的内容创建表,每一个memory只实际对应一个磁盘文件。因为是存在内存中的,所以memory访问速度非常快,而且该引擎使用hash索引,可以一次定位,不需要像B树一样从根节点查找到支节点,所以精确查询时访问速度特别快,但是非精确查找时,比如like,这种范围查找,hash就起不到作用了。另外一旦服务关闭,表中的数据就会丢失,因为没有存到磁盘中。

适用场景:主要用于内容变化不频繁的表,或者作为中间的查找表。对表的更新要谨慎因为数据没有被写入到磁盘中,服务关闭前要考虑好数据的存储

==和equals的区别

基本类型(int ,float)中,==和equals没有区别

引用类型中(String),==比较两者的地址,equals比较地址中的值

String 、Stringbuffer 、Stringbuilder

3者的原理,区别

String 的存储char数组中,有final限制,就是不会被其他类继承
比如修改String中的东西,其本质不是修改,而是新建一个char[]数组,赋值进去,然后将char [] 赋值给String

Stringbuffer 没有final限制,有同步锁
Stringbuilder 没有final限制,没同步锁

哪些安全哪些不安全

String 、Stringbuffer 是安全的,因为String有final,Stringbuffer 有同步锁
Stringbuilder是不安全的,因为没有final和同步锁

各自的应用范围

单线程数据量大,用Stringbuilder
多线程数据量大,用Stringbuffer

怎么记?

String 有final都知道对吧
Stringbuffer 嘛,有buff,所以有处理多线程
Stringbuilder 还在build中,啥也没有,所以不安全,只能处理单线程大的东西

MySQL的数据类型

数值类型

tinyint smallint mediumint int bigint float double mecimal
其中精度mecimal>double>float

时间类型

date time datetime timestamp

字符类型

char varchar BLOB text

Java基本类型

布尔、byte、short、int、long、float、double、char

tcp和udp协议的区别

在这里插入图片描述
UDP用于网络通话这方面,TCP用于短信发送

速度上

udp比tcp快

个数上

udp:一对一、一对多
tcp:一对一、点对点

可靠性

tcp可靠,因为3次握手
udp不可靠,就发送,没有握手

3次握手

在这里插入图片描述
在这里插入图片描述

客户端–发送带有 SYN 标志的数据包–一次握手–服务端
服务端–发送带有 SYN/ACK 标志的数据包–二次握手–客户端
客户端–发送带有带有 ACK 标志的数据包–三次握手–服务端

为什么要三次握手

三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。

第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常

第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常

第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常

所以三次握手就能确认双发收发功能都正常,缺一不可。

HashMap 和 TreeMap 区别

在这里插入图片描述
实现 NavigableMap 接口让 TreeMap 有了对集合内元素的搜索的能力。

实现SortMap接口让 TreeMap 有了对集合中的元素根据键排序的能力。默认是按 key 的升序排序

抽象类和接口类的异同

魅族1面

//通过抽象类定义
  public abstract class Dog {
      public abstract void eat();
      public abstract void sleep();  
  }
  
  //通过接口定义
  public interface Dog {
      public abstract void eat();
      public abstract void sleep();
  }

上面一个抽象一个接口,众所周知继承只能一个,接口能有很多个。继承父类(抽象类)的话必须要写具体方法,而实现接口可以实现无数个。

人话:继承抽象类是爸爸,实现接口类是干爸。爸爸只有一个,干爸可以认好几个

线程池

魅族1面
优点:

  • 提高线程利用率
  • 提高程序响应速度
  • 便于控制
  • 控制最大并发数

一个线程池有几个线程,来一个任务执行一个线程,任务完了释放线程,让线程回到线程池。
比如线程池有3个线程,来了5个任务,那么3个就执行,2个在等待区域等待。
如果等待区域也放不下了,那么线程池开启紧急状态,开过几个线程来跑,但是紧急状态的线程池数量也是有上限的。如果紧急状态还超过了,只能跑出异常丢掉了。

public class pool {
    public static void main(String[] args) {
//        默认长度,最大长度,时间,时间单位,等待队列(队列类),线程工厂,拒绝策略(默认抛异常)
        ExecutorService executorService = new ThreadPoolExecutor(3, 5, 1L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3), Executors.defaultThreadFactory());

        for (int i = 0; i < 6; i++) {
            executorService.execute(()->{
                System.out.println(Thread.currentThread().getName()+"==>正在执行任务");
            });
        }

        //关闭线程池
        executorService.shutdown();
    }
}

3线程大小,最多5个线程大小,等待区域最多3个。
就是说,来3个,执行3个;来6个,执行3个等待6个;来7个,等待和执行都超过了,启动紧急状态,开启多一个线程池,就是5个执行,2个等待;来9个,5个执行,3个等待,还有一个没办法只能报异常了。

深拷贝与浅拷贝

  • 浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。
  • 深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。

人话:浅拷贝是都是引用一个对象。深拷贝是引用了而且还创建了一个新对象
不管什么时代,不管过去多少年,Java8永远都是新版本,新特性。

— 我说的

Java8新特性

interface(接口)的默认方法
//这是一个接口类,但是里面可以写方法了
interface Formula{

    double calculate(int a);

    default double sqrt(int a) {
        return Math.sqrt(a);
    }

}

旧版本的接口和抽象类都不可写方法内容的呢

匿名类
public class Main {

  public static void main(String[] args) {
    // 通过匿名内部类方式访问接口
    Formula formula = new Formula() {
        @Override
        public double calculate(int a) {
            return sqrt(a * 100);
        }
    };

    System.out.println(formula.calculate(100));     // 100.0
    System.out.println(formula.sqrt(16));           // 4.0

  }

}

不看资料都不知道原来是8的特性,以为自古就有。。。

Lambda表达式

我听过,实际上我没用过呢

就是一个匿名类的简写方式


        List<String> names = Arrays.asList("jack","wither","json","kiki");

        Collections.sort(names, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o2.compareTo(o1);
            }
        });

        System.out.println(names);
 

[wither, kiki, json, jack]

sort方法中有一个参数是新创建一个类,但是类也只用重载一个方法,要写很多东西,lambda只用写一点就好了

	List<String> names = Arrays.asList("jack","wither","json","kiki");
	
	Collections.sort(names, (String a, String b) -> {
	    return b.compareTo(a);
	});
	
	System.out.println(names);

进阶版

Collections.sort(names, (String a, String b) -> b.compareTo(a));

终极版

names.sort((a, b) -> b.compareTo(a));
内置函数式接口

太多不想看不想学。。。
就是一个与或非可以用在方法名同级的地方

Streams(流)

原本流只是单纯读取,8以后可以根据条件过滤,条件排序,模糊匹配,就和MySQL类似一样。

时间

在原有的基础类型加了很多库
时区、本地时间、本地日期、本地日期时间

注解

支持多重注解,比如

@Hint("hint1")
@Hint("hint2")
class Person {}

前提是加一个@Repeatable就可以

JVM

在这里插入图片描述
记得这张图就行

  • 程序计数器:代码的流程控制,如循环、异常等
  • 虚拟机栈:存放各种基本数据类型
  • 本地方法栈:存储局部变量
  • 堆:很大的一块,所有对象都是在堆中创建的

常用算法的八股文

在这里插入图片描述
详情看我博客有一篇算法的

Spring IOC & AOP

魅族、深圳萨摩耶一面

IOC

IoC(Inverse of Control:控制反转)是一种设计思想,就是 将原本在程序中手动创建对象的控制权,交由Spring框架来管理。IoC 容器实际上就是个Map(key,value),Map 中存放的是各种对象。

在这里说下什么是控制反转,比如造车子,一个设计图,先造轮子,然后根据轮子大小造底盘,根据底盘造车身,根据车身造汽车。看起来没毛病,但是如果老板突然说改轮子大小,那底盘根据轮子大小改的,底盘也要改,这样车身也要改,整个都要改了,玩几把蛋。这就是典型的下层控制上层(上层依赖下层)。IOC就是控制反转,下层依赖上层,就是把底层类作为参数传入上层类,实现上层类对下层类的“控制”。就形成了控制反转这一词。决定权在上层而不是下层,改一个东西而不会牵全身

完成这些就是bean和xml等各个配置来搞的了

AOP

AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。

Bean

将一个类声明为Spring的 bean 的注解有哪些?
我们一般使用 @Autowired 注解自动装配 bean,要想把类标识成可用于 @Autowired 注解自动装配的 bean 的类,采用以下注解可实现:

  • @Component :通用的注解,可标注任意类为 Spring 组件。如果一个Bean不知道属于哪个层,可以使用@Component 注解标注。
  • @Repository : 对应持久层即 Dao 层,主要用于数据库相关操作。
  • @Service : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao层。
  • @Controller : 对应 Spring MVC 控制层,主要用于接受用户请求并调用 Service 层返回数据给前端页面。

spring MVC

model view controller,按照平时的知识就是了

spring boot自动装配原理

一切都要从@SpringBootApplication说起,其里面包含了3个主要的东西:

  • @EnableAutoConfiguration:启用 SpringBoot 的自动配置机制
  • @Configuration:允许在上下文中注册额外的 bean 或导入其他配置类
  • @ComponentScan:扫描被@Component (@Service,@Controller)注解的 bean
  1. 判断自动装配开关是否打开。默认spring.boot.enableautoconfiguration=true,可在 application.properties 或 application.yml 中设置
  2. 用于获取EnableAutoConfiguration注解中的 exclude 和 excludeName。
  3. 获取需要自动装配的所有配置类

3步进行自动配置。
人话就是,先自动配置一些东西,再检查你自定义配置的。就这样

mybatis #{}和${}的区别是什么?

  • $ {}是 Properties 文件中的变量占位符,它可以用于标签属性值和 sql 内部,属于静态文本替换,比如${driver}会被静态替换为com.mysql.jdbc.Driver。
  • #{}是 sql 的参数占位符,MyBatis 会将 sql 中的#{}替换为?号,在 sql 执行前会使用 PreparedStatement 的参数设置方法,按序给 sql 的?号占位符设置参数值,比如 ps.setInt(0, parameterValue),#{item.name} 的取值方式为使用反射从参数对象中获取 item 对象的 name 属性值,相当于 param.getItem().getName()。

MySQL中各个类型的默认值

广州百家医道
在这里插入图片描述

vue的生命周期

广州百家医道、东莞通 一面

方法的生命周期

其实不难理解,就分为几个顺序:

  1. beforeCreate
  2. created
  3. mounted
  4. beforeUpdate
  5. updated
  6. beforeDestroy
  7. destroyed
属性的生命周期

props => methods =>data => computed => watch

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值