sc面试问题

  1. 什么是jdk,jre,jvm?
    1.1 jdk称为java开发工具 包含了jre…并且jdk的api
    适合开发使用
    1.2 jre称为java运行环境 包含了jvm…jre用于运行java
    程序.
    1.3 jvm称为java虚拟机 java程序运行的编译,运行的内存
    分配…都是jvm来完成的
    jdk包含jre包含jvm


  2. == , equals区别?
    2.1 原生类的== 比较值,且没有equals方法. 强类型的== 比较的是地址值.
    2.2 equals方法默认为Object类的方法, 如果不重写, 其实现默认也为 == 判断.
    2.3 String类已经重写了Object类的equals方法, 其实现为逐个比较字符,
    也就是比较字符串的内容是否相等.
    2.4 java建议重写equals的时候, 也重写hashcode方法.
    因为jdk中带hash算法的对象, 底层会用到hashcode和equals来共同确认一个对象
    是否重复/相等.


  3. java程序的运行原理, 为什么能够跨平台?
    3.1 跨平台指程序可以在不同的操作系统上运行…
    3.2 java程序首先将.java文件编译为 .class字节码文件
    3.3 该字节码文件可以运行在不同的操作系统上
    3.4 因为不同的操作系统上有对应该操作系统的jvm,
    会去把.class翻译为对应平台能够识别执行的机器码…

    总结: 先把.java文件 编译 为.class文件,
    再把.class文件 翻译 成机器码,
    再执行机器码…


  4. 包装类和基本数据类型的区别?
    4.1 包装类可以为null ,原生类不可以为null.
    4.2 包装类默认实现了一些方法,方便使用. 原生类没有方法.
    4.3 包装类属于强类型, 引用传递. 原生类属于值传递.
    (PS:如果包装类要和原生类比较数据, 那么按原生类比较,因为原生类没有地址.)


  5. static关键字的作用
    5.1 static可以修饰内部类,方法,属性,代码块,静态导入.
    5.2 static修饰的属性和方法它们属于类的.不依赖对象.
    且只有一份空间. 多个地方调用会有数据共享安全的问题.
    一般在属性上面加上final使其只读.
    5.3 static会最先执行.不需要依赖实例.
    5.4 static不可以直接调用实例方法. 实例方法可以直接调用静态方法


  6. 重写和重载的区别?
    6.1 重载发生在同一个类中, 方法名相同, 参数类型/列表个数不同,
    和方法签名的其他任何关键字无关.
    6.2 重写发生在子类继承父类的关系中, 方法名相同, 参数类型/列表也要相同,
    权限访问修饰符不能比父类更严格(小);
    返回值类型必须和父类相同或是父类返回值类型的子类/实现类.
    声明的异常不能比父类更大


  7. final修饰类: 该类不允许被继承
    final修饰方法: 该方法不可以被重写,可以重载.
    final修饰属性: 该属性的值不能变. 如果是强类型,
    那么该地址值指向的对象里面的属性值是可变的.


  8. instanceof的作用?
    判断某个变量是否为某种类型.
    应用场景: 不同的子类拥有不同的行为方法.
    当使用父类作为变量引用子类对象的时候,要调用子类独有的方法,要先做
    instanceof判断, 再强转回对应的子类调用该子类的独有方法…
    如果不判断直接强转,可能会抛出ClassCastException(类型转换异常)


  9. try中有return, finally会不会执行
    9.1 必须执行
    9.2 在return的中间执行
    9.3 return的值会在临时空间, 然后去执行finally
    9.4 如果finally中没有新的return, 那么最终返回的还是try里面的值
    9.5 如果finally中有新的return, 那么会覆盖临时空间的值, 最终返回
    finally里面的值


  10. 异常的理解?

一. 结构:
java中异常的基类为
Throwable
Exception
RuntimeException运行时异常
Null,Index…
!Runtime…(CheckedException)检查性异常
Error
错误
指编译错误的代码,内存溢出,硬件故障…等不可抗力错误.
程序自身一般无法修复.

  1. 运行时异常RuntimeException
    2.1 该异常在程序运行的时候可能会抛出的异常,该异常jvm不要求一定处理.
    (程序员可以选择处理或不处理)
    3. 检查性异常"CheckedException"
    3.1 该异常要求程序员必须处理的异常. 否则编译不通过.

    番外: 什么是处理? 处理的意思trycatch或继续往外声明throws

二. throws和throw的含义?
throws声明异常: 告诉调用方,我这个方法可能会抛出(报错)一个这样的异常.
当抛出的异常为检查性异常,那么调用方必须处理,或继续往外声明.
throw抛出异常 程序本来不报错的,手动让它报一个我们指定的异常


  1. 数据结构之线性表:
    ArrayList顺序存储, 底层实现是数组,其内存地址空间是连续的,
    可以通过地址索引直接定位到节点,所以访问效率高.
    但是在靠前或中间的位置插入效率低, 因为被插入的后面所有的
    节点都要往后移动.

LinkedList链式存储 该数据结构为双向链表, 每一个节点保存了前后节点的地址值.
所以在插入的时候,影响的节点只有前后两个节点, 性能高效.
但是读取非头尾数据效率较低. 适合频繁插入数据使用.



  1. hashCode方法的理解?
    本地方法, 默认系统返回的逻辑地址. 该值可能重复.


  2. HashMap底层实现原理?
    1. HashMap底层采用数组加链表(单向)方式实现.
    2. 通过key的hashcode找到要存储的数组的具体位置.
    3. 判断该位置是否为null, 为null直接存储.
      不为null,那么调用key的equals方法判断和已经存在的对象的key是否相等,
      如果相等则覆盖,并且返回old值. 不相等则代表出现hash冲突,则接入到已存在节点的next的位置.(链表实现)
    4. 当hash冲突的节点到达8的时候, 链表转为红黑树(因为小于8的时候,链表的时间查找复杂度性能比红黑树的要高)
    5. get的时候通过hashcode找到要存储的位置, 如果该位置为null,则返回null.
      如果不为null,则调用equals和已经存在的节点的key判断是否相等, 相等则返回value.
      不等则遍历链表的.next, 和下一个节点的key判断,以此类推, 找到后返回value;




15.
1). 内部比较器Comparable是写在要被排序的类上,实现并重写compare方法.
该方式统一了排序策略, 即所有地方的排序, 都按该默认策略排序.

2). 外部比较器Comparator是在Collections.sort方法,传入的. 适用于单独的比较.
每个不同场景,可以使用不同的排序策略排序.



  1. 创建多线程 3三种.
    1). 继承Thread类
    2). 实现Runnable接口
    3). 实现Callable接口
    加线程池4种
    1. 单例线程池 SingleThreadExecutor
      应用场景: 任务量不大, 然后不能影响主线程的时候.
    2. 固定数量线程池 FixedThreadPool
      应用场景: 任务量较大的时候.
    3. 不限定数量/缓存线程池 CachedThreadPool
    4. 周期任务线程池(类似于setInterval)



  1. 线程状态
    新建, 就绪, 运行中, 等待/阻塞 , 死亡


  2. 解决线程安全问题?

  1. 多实例, 每个线程单独使用单独的实例(如果场景允许),
    缺点比较耗资源
  2. 使用局部变量, 局部变量没有线程安全的问题.
  3. 使用synchronized同步锁, 或Lock对象
  4. 本地线程


  1. synchronized
    在实例方法上的时候, 同步锁的对象为 this
    在静态方法上的时候, 同步锁的对象为 类.class


  2. 什么是死锁?
    一般发生在同步嵌套中, 多个线程相互等待对方释放同步对象.
    或使用Lock对象的时候忘记释放锁,导致其他线程无法获取.
    1.使用Lock对象的tryLock
    2.可能发生死锁的代码块都按同一顺序加锁


  3. synchronized和Lock区别?
    1.synchronized是java内置关键字,在jvm层面,Lock是个java API编程;
    2.synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁;
    3.synchronized会自动释放锁,Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁;
    4.synchronized获取不到锁会一直等待下去,而Lock可以尝试获取,如果获取不到锁,线程可以执行其他代码块或结束运行;
    5.synchronized为非公平锁, 可能导致线程饥饿现象. Lock对公平/非公平锁都支持.


  4. sleep,yield和wait的区别?
    1.sleep 属于 Thread类的静态本地方法. 需要指定睡眠的时间.
    在此时间内,不会释放对象锁. 时间到,进入就绪状态,等待CPU调度执行.
    2.wait 属于 Object类的实例本地方法. 可选择指定或不指定等待的时间.
    持有锁对象的线程调用此方法,会释放对象锁, 并进入等待状态.(否则无法释放对象锁的线程调用则会抛出非法监视器状态异常)
    需要被其他线程唤醒,才能进入就绪状态.
    (如果wait指定了时间, 那么到达指定时间后, 进入等待锁池队列,重新尝试获取锁对象,获取到后会进入就绪状态,被CPU调度后,
    ,然后执行)
    3.yield 代表退让, 意为让出cpu资源给同优先级的线程以执行机会
    属于Thread类的静态本地方法.
    效果和sleep类似, 只是时间由虚拟机来控制.
    不会释放对象锁. 调用后进入就绪状态.

总结: yield和sleep可以在普通和同步方法中. wait必须运行在同步中.


  1. join方法的作用?
    阻塞当前位置, 直到调用join的线程执行完毕才往下执行.


  2. interrupt
    打断, 逻辑上中断一个正在执行的线程(非暴力).
    给收到interrupt的线程设置一个boolean的标志为true,线程可以判断后手动结束.
    如果该线程正在阻塞/等待中, 那么会抛出一个interrupt的异常…并重置isInterrupt
    为false;


  3. volatile关键字的作用?能否保证线程安全?
    1.volatile只能修饰属性, 期保证多线程运行间, 线程获取的属性是最新的.
    不加的话,线程的独立空间会有缓存的值.
    2.防止指令的重排序
    3.不能保证安全,有…参考上面去.




25. 什么是IO? 什么是缓冲区?
1.IO 分为 输入流和输出流
输入流和输出流又细分为 字节流和字符流.
字节流一般用于操作文件, 对应的基类为InputStream和OutputStream
字符流一般用于操作文本, 对应的基类为Reader和Writer
2.缓冲区的作用是减少程序直接访问介质的次数,提升读写效率和性能.
缓冲区分为: 输入缓冲区和输出缓冲区. 使用输出流的缓冲区需要在结束前调用flush
方法把缓存中的数据写出去.




26.
什么是同步,异步? 阻塞,非阻塞?什么是BIO,NIO,AIO?
1.同步:客户端发送请求到服务器,假设服务器处理请求需要N秒时间,
那么客户端会一直等待.(无法做其他任务)
2.异步: 客户端发送请求到服务器, 假设服务器处理请求需要N秒时间,
那么客户端不会等待,可以先做其他任务.服务器响应后,会执行回调处理结果.
3.阻塞: 服务器只能处理一个客户端请求,处理完后接受第二个请求.
4.非阻塞: 服务器同时接受多个请求.
IO为分BIO, NIO, AIO
BIO 同步阻塞 客户端和服务器一对一交互. 效率较低.
NIO 同步非阻塞 客户端和服务器多对一交互. 服务器效率提升.
AIO 异步非阻塞 客户端和服务器多对多交互. 性能卓越.



  1. 什么是序列化? 怎么实现?
    1.序列化就是把程序中的对象写入到临时存储或持久化的过程.
    反序列化就是把临时存储和持久化的内容,反向写入程序中的过程.
    2.实现序列化需要实现Serializable接口. 反序列化需要对比版本号.
    每次修改版本号会变更.
    3.static变量和transient修饰的属性不会被序列化.
    4.通过Serializable接口实现的反序列化,
    不会执行自身的构造器.但是会执行父类无参构造.



  1. 创建对象有几种方式?
    1.new(执行构造) 2. 反序列化(Externalizable执行构造,seri…不执行)
    3.反射(执行构造) 4. 克隆.


  2. 什么是反射?
    1.在运行期间.
    给任意一个类(com.seecen.pack.className),反射可以获取到该类的属性和方法
    给任意一个对象,反射可以执行该对象的方法和获取该对象属性的值.
    给任意一个类的路径, 可以创建该类的实例
    2.有什么作用?应用场景?一般什么时候考虑使用反射呢?
    使用在通用的模块上.


  3. 什么是socket?
    套接字, 分为tcp和udp协议.
    客户端和服务器端的长连接的通信.

  4. 浅拷贝和深拷贝?
    1.浅拷贝只拷贝对象本身,对象里面的组合对象直接是引用,赋值,没有创建新的对象,属于引用传递
    2.深拷贝即拷贝对象本身,也拷贝对象里面的对象


  5. tcp和udp?
    1.tcp需要三次握手,四次挥手,需要建立连接,基于连接状态,udp无连接
    2.tcp的数据更安全,也有序 udp不安全,可能丢包
    3.tcp性能较低。udp性能更高
    4.udp比tcp更适合传输数据量较大的情况


  6. java内存区域(jvm内存模型)
    在这里插入图片描述

属于内存的共享内存部分:
1.方法区(永久代)(元空间jdk1.8,直接使用内存,高效,避免OutOfMemoryError)
类,元数据,静态资源,常量池。。。
2.heap堆
new出来的对象
属于线程独享的内存部分:
1.程序计数器 记录每个线程的运行的行号位置。。。该区域是唯一不会抛出内存溢出异常的地方
2.虚拟机栈
2.1 局部变量表 存储方法运行的局部变量 如:方法中的变量和形参
2.2 操作数栈 存储变量使用运算符运算的结果 如:int c =a+b
2.3 动态/静态链接 对于static或者普通没有重写的方法使用静态链接方式保存方法调用链
对于重写,在编译器无法确定的,需要在运行期才能确定的方法,采用动态链接方式保存
2.4 方法的返回地址 记录方法返回后执行的位置
3.本地方法栈
原理参考虚拟机栈,只是该区域保存的方法都是native方法

  1. java内存模型:
    在这里插入图片描述
    主内存:java虚拟机规定所有的变量(不是程序中的变量)都必须在主内存中产生,为了方便理解,可以认为是堆区。可以与前面说的物理机的主内存相比,只不过物理机的主内存是整个机器的内存,而虚拟机的主内存是虚拟机内存中的一部分。
    工作内存:java虚拟机中每个线程都有自己的工作内存,该内存是线程私有的为了方便理解,可以认为是虚拟机栈。可以与前面说的高速缓存相比。线程的工作内存保存了线程需要的变量在主内存中的副本。虚拟机规定,线程对主内存变量的修改必须在线程的工作内存中进行,不能直接读写主内存中的变量。不同的线程之间也不能相互访问对方的工作内存。如果线程之间需要传递变量的值,必须通过主内存来作为中介进行传递。
    这里需要说明一下:主内存、工作内存与java内存区域中的java堆、虚拟机栈、方法区并不是一个层次的内存划分。这两者是基本上是没有关系的,上文只是为了便于理解,做的类比



  1. 垃圾回收算法:
    jvm采用GC ROOT可达性算法确定要被回收的对象后,采用以下的算法进行回收如何判断对象是否存活/死活
    JVM之GC算法、垃圾收集算法——标记-清除算法、复制算法、标记-整理算法、分代收集算法
    1.标记-清除算法
    2.复制算法
    3.标记-整理算法
    4.分代收集算法---->新生代采用复制算法,老年代采用标记-整理算法
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述
关于JVM中Eden区、Survivor from区和Survivor to区的理解


  1. 什么是强引用,软引用,弱引用,虚引用
    1.平时直接=赋值的对象,对象不可达才会被回收
    2.软引用(SoftReference):内存不足,gc执行的时候会强制执行
    3.弱引用(WeakReference):只要GC执行就会被回收
    4.虚引用(PhantomReference):get始终返回null,虚拟的引用


  2. GC是什么?什么时候执行?
    1.GC为java中的一个守护线程,作用于垃圾回收
    2.GC不确定在什么时候运行
    3.程序员可以手动通知GC执行(system.gc()),但不保证一定执行(没人确定什么时候执行)


  3. final、finally、finalize区别?
    final:修饰类不可继承,方法不可重写 属性的值不可变(引用类型里面的属性可变)
    finally:表示一定会执行的代码块,除了执行exit方法
    finalize:GC在回收对象的时候,会先调用该被回收对象的finalize方法,但是只会被调用一次(我们通过在finalize中重新让对象可达,可第一次不被回收)


数据库篇
1.有哪些数据库类型:
1.1 关系型数据库:mysql、oracle、sqlsever、access、db2、postgresql
其中:mysql、access、postgresql开源免费
oracle和db2收费并且适用于大型商业应用项目
1.2nosql数据库:redis,memcached,mongodb

三大范式:
三大范式
第一范式(确保每列保持原子性)
第二范式(确保表中的每列都和主键相关)
第三范式(确保每列都和主键列直接相关,而不是间接相关)

2.关系型数据库使用的语言是什么
SQL:结构化查询语言
sql有分为:
1.DQL 数据查询语言 select
2.DDL 数据定义语言 create/alter/drop
3.DCL 数据控制语言 grant/revoke
4.DML 数据操纵语言 insert/update/delete

3.sql执行顺序:
from >where >group by>having>select>order by

4.IN,EXISTS,NOT IN,NOT EXISTS区别?
当主查询的结果集较大,子查询的结果较小,尝试使用in提升效率
反之,主查询结果较小,子查询的结果较大且含有索引,使用exists
not exists的子查询会用到索引,索引建议使用not exists代替not in

5.有哪些表连接的方式,区别是什么?
1.内连接:
主表和次表条件满足的,会显示,不满足/匹配的,都不显示
2.外连接:
左外连接:主表数据全部显示,次表数据满足/匹配的显示,不匹配的显示为null
右外连接:次表数据全部显示,主表数据满足/匹配的显示,不匹配的显示为null
全外连接:主次两张表数据全部显示,主次匹配的显示数据,不匹配的显示null
3.交叉连接:主表和次表产生笛卡尔积,即A*B的数据条数

6.union和union all的区别?
两个都是获取两个表的并集,union会默认去除重复行,而且排序。
union all的性能比union要高,不会去重,也不会排序,就是简单的直接合并

7.delete,truncate、drop的区别?
delete会记录日志,可回滚恢复;truncate截断表,不记录日志,不可恢复
delete删除速度慢,truncate删除速度快
delete可以加删除条件,truncate不能,只能全表删除
drop是连带表结构/定义和数据都删除,不可恢复
delete属于DML语句,truncate和drop属于DDL语句

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值