每天十道面试题-20200327

题目

  • 1、JDK动态代理与cglib实现的区别
  • 2、说说Ioc容器的加载过程
  • 3、如何保存会话状态,有哪些方式、区别如何
  • 4、分布式session如何管理,你有哪些方案
  • 5、JVM中类加载机制,类加载过程,什么是双亲委派模型?,类加载器有哪些
  • 6、OOM的场景?堆和栈的一些区别?
  • 7、Linux的top指令可以查看什么信息?top中的load指的是什么?网络相关的指令用过哪些?查端口号用哪一个?
  • 8、Jenkins自动化部署的流程?
  • 9、浏览器输入 www.xxx.com 最终展现网页,整个过程
  • 10、说一下zookeeper和ES

解答

题目一
  • 题干:JDK动态代理与cglib实现的区别
  • 分析:
  • 这个问题一般是在问Spring的AOP原理的时候会问道,AOP底层个使用代理模式来实现,有两种实现方式,一种是JDK的动态代理、一种是CGLIB的代理实现,JDK的动态代理是默认的实现,而且只能用来代理接口,所以对于被代理对象是一个类的时候就束手无策了,而CGLIB实现的动态代理正是来解决这个问题的,JDK动态代理底层使用的是反射技术,通过反射技术创建被代理对象的实例,然后实现Invoke Handler接口在里面调用被代理对象的方法,并进行增强,然后InvokeHandler的实现类对象作为参数传入Proxy的静态方法newProxyInstance中作为第三个参数,前两个参数一个是被代理对象的类加载器、一个是被代理对象的接口;对于CGLIB也是来实现动态代理的只不过底层的原理不一样它是使用底层的字节码技术,直接堆字节码进行增强,使用的asm开源包,讲代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

  • 回答:
  • 如果目标对象实现了接口,那么JDK的动态代理和CGLIB都可以使用,Spring默认使用JDK的动态代理来作为接口动态代理的实现,对于没有实现接口的代理类,一般使用CGLIB来实现动态代理,JDK动态代理使用反射技术,CGLIB使用的是字节码技术。

题目二
  • 题干:说说Ioc容器的加载过程
  • 分析:
  • 在问到SpringIOC时必问的问题,无论是通过注解还是XML文件形式指定的Bean对象在Spring中都是用BeanDefinition类来对应的,BeanDefinition中的对应的Bean的作用域只有singleton和prototype两种至于request session等都是基于web的也就是WebApplactionContext中的,扫描到所有Bean后 然后将Bean注册到BeanDefinitionRegistry中,Spring中的Bean有两种一种普通的Bean一种工厂Bean也就是Factory Bean的实例对象[普通Bean使用反射生成实例,而对于有些复杂的Bean在配置的时候相对复杂所以用工厂Bean来生成,比如数据库连接的Bean,在生成的时候需要进行一些属性的配置]。然后初始化Bean最终生成Bean实例,然后对于单例的Bean放在Spring的Bean缓存池里,用一个Map维护,对于多例的Bean直接返回给调用者.最终销毁,在初始化和实例化的前后都会进行相应的一些方法调用.

  • 回答:
  • .BeanDefinition的Resource定位
    BeanDefinition的载入和解析
    BeanDefinition在容器中的注册
    BeanDefinition的创建以及销毁
    根据分析部分进行展开.

题目三
  • 题干:如何保存会话状态,有哪些方式、区别如何
  • 分析:
  • Cookie Session Token 都可以保存会话状态,Cookie是实现Session的一种方式,服务端生成,因为Cookie存储在客户端 ,其中包含sessionid为服务器不做存储,所以为了防止cookie被篡改,所以浏览器会对cookie有一些限制包括存储的cookie的大小,如果浏览器禁用cookie我们也可以将cookie放在url的后面;Session保存会话,由服务端生成,保存在服务端,Session在集群下如果使用Session Sticky 会出现问题,如果Sticky的服务崩了,那么就需要重新登陆,所以就需要在集群之间复制Session,所以就需要持久化Session[用数据库持久化或者作为缓存 都可以],这样就很麻烦;使用Token的方式保存会话,就不需要保存Token了[就不需要像保存Session一样保存Token],根据用户信息生成Token[需要加密]每次用户发起请求,都对用户信息重新计算看看Token是否一样如果一样说明验证通过客户端存储Token每次发起请求都需要在请求头带上Token,Token是无状态的 可扩展的.我们可以使用JWT生成的Token来做验证保存会话信息Header.Payload.Signature。
    Header 部分是一个 JSON 对象,描述 JWT 的元数据
    {
    “alg”: “HS256”,
    “typ”: “JWT”
    }
    Payload部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段
    iss (issuer):签发人
    exp (expiration time):过期时间
    sub (subject):主题
    aud (audience):受众
    nbf (Not Before):生效时间
    iat (Issued At):签发时间
    jti (JWT ID):编号
    Signature 部分是对前两部分的签名,防止数据篡改。
    HMACSHA256(
    base64UrlEncode(header) + “.” +
    base64UrlEncode(payload),
    secret)
    算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户。

  • 回答:
  • 参考分析部分。

题目四
  • 题干:分布式session如何管理,你有哪些方案
  • 分析:
  • 第一种使用Cookie来保存Session,每次请求服务端客户端都带上Cookie。使用Cookie保存Session有弊端,浏览器对Cookie的大小有限制,Cookie保存在客户端会被挟持篡改,但是贵在简单易用.第二种使用Session Sticky 在集群环境下让客户端访问和某一台服务器绑定,这个可以避免在集群中复制Session,也是由服务端存储Session的,弊端就是如果绑定的那台服务器崩了,那么用户就需要重新登陆;第三种就是Session复制,就是在集群的环境下在各个服务器之间复制所有Session,这样就算崩了一台也没问题,弊端就是需要在集群很小的情况下,如果量大Session很多,在各个服务器之间进行复制开销很大第四种使用单独的Session服务器,将Session持久化比如使用MySQL数据库存储Session,或者使用Redis集群来保存Session;

  • 回答:
  • 分布式环境下参考第三种和第四种。

题目五
  • 题干:JVM中类加载机制,类加载过程,什么是双亲委派模型?,类加载器有哪些
  • 分析:
  • 考察JVM类加载的相关只是,类加载机制:加载-连接[验证-准备-解析]-初始化-使用-卸载,对于类的加载为了确保类的唯一性,所有推荐使用双亲委派模型,就是说在BootsTrapClassLoader ExtClassLoader AppClassLoader 进行类加载的时候,子加载器都会委托给父加载器进行加载.

  • 回答:
  • 使用双亲委派模型进行类的加载,自底向上检查类是否已经加载,自顶向下加载类。
    加载过程包括加载-连接【验证-准备-解析】-初始化-使用-卸载。
    加载:主要是从各种jar或者其他zip文件加载,或者通过动态代理字节码工具动态生成。
    连接分为三步:
    验证:验证格式【魔数-版本-长度】、语义验证、字节码验证、符号引用。
    准备:对方法区中类数据信息的类变量,执行初始化,仅仅是为类中的所有静态变量分配内存空间,并为其设置一个初始值。【jvm不支持boolean所以 0 false 1 true】
    解析:将字节码常量池中的符号引用全部转换为直接引用。
    初始化:将所有static标识的代码统统执行一遍,有值就赋值没有的话就使用准备阶段的初值。
    破坏类加载器的是SPI
    启动类加载器
    扩展类加载器
    应用类加载器

题目六
  • 题干:OOM的场景?堆和栈的一些区别?
  • 分析:
  • OutOfMemoryError内存溢出错误,如果堆的空间分配过小,长生的对象过多,无法分配就会产生这个错误,对于栈内存,也是一个内存空间,常见的场景就是我们使用递归时,方法不停调用,栈帧将栈内存空间耗尽,也会产生OOM;
    堆和栈的区别,堆和栈都是JVM运行时的内存空间,堆是所有线程共享的,栈是线程私有的,存放的是8中基本类型变量[都是局部变量],非基本类型的对象在JVM栈上仅存放一个指向堆上的地址。部分返回结果以及栈帧,因为存储栈帧以及方法局部变量,所以栈上局部变量生命周期很短,方法结束就释放.堆上存储实际的对象实例,需要等待垃圾回收才会释放,堆是所有线程共享的.

  • 回答:
  • 一般就是堆上的内存溢出,栈上的内存溢出; 1.栈内存存储的是局部变量而堆内存存储的是实体;
    2.栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;
    3.栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的回收。

题目七
  • 题干:Linux的top指令可以查看什么信息?top中的load指的是什么?网络相关的指令用过哪些?查端口号用哪一个?
  • 分析:
  • 第一行,任务队列信息,同 uptime 命令的执行结果
    第二行,Tasks — 任务(进程)
    第三行,cpu状态信息第四行,内存状态
    第五行,swap交换分区信息
    第七行以下:各进程(任务)的状态监控
    PID — 进程id
    USER — 进程所有者
    PR — 进程优先级
    NI — nice值。负值表示高优先级,正值表示低优先级
    VIRT — 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
    RES — 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
    SHR — 共享内存大小,单位kb
    S —进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程
    %CPU — 上次更新到现在的CPU时间占用百分比
    %MEM — 进程使用的物理内存百分比
    TIME+ — 进程使用的CPU时间总计,单位1/100秒
    COMMAND — 进程名称(命令名/命令行
    top命令 会有load average信息。有三个值,分别代表:当前,最新5分钟,最新15分钟的cpu负载。例如:
    top - 14:42:45 up 1189 days, 15:29, 6 users, load average: 0.15, 0.83, 6.08
    那cpu负载。又是什么呢?代表当前cpu处理的任务个数。
    这个值为多少为好呢?理想状态为:cpu的数量 即双核的cpu这个值在2比较理想。代表当前cpu处理饱和。正常情况应保持在70%左右为好。太小浪费机器,太大会有系统反应慢的情况。
    如果数量大于理想数量。则会出现线程等待的情况。代表该机器的cpu已经不够用了,取决于CPU的核数。
    常用命令:ping ifconfig netstat sudo 允许一个已授权用户以超级用户或者其它用户的角色运行一个命令
    ps -ef | grep java 查看指定服务的进程id netstat -nap | grep 端口号/进程id根据进程id或者端口号查看端口号和进程id

  • 回答:
  • 参考分析

题目八
  • 题干:Jenkins自动化部署的流程?
  • 分析:
  • Jenkins自动部署流程:首先是git 同步更新代码然后maven打包并体制Tomcat,然后部署应用之后启动Tomcat最终验证结果

  • 回答:
  • 参看分析部分

题目九
  • 题干:浏览器输入 www.xxx.com 最终展现网页,整个过程
  • 分析:
  • 浏览器进行DNS域名解析,得到对应的IP地址
    根据这个IP,找到对应的服务器建立连接(三次握手)
    建立TCP连接后发起HTTP请求(一个完整的http请求报文)
    服务器响应HTTP请求,浏览器得到html代码(服务器如何响应)
    浏览器解析html代码,并请求html代码中的资源(如js、css、图片等)
    浏览器对页面进行渲染呈现给用户
    服务器关闭TCP连接(四次挥手)
    更详细的过程:
    首先会搜索浏览器自身的DNS缓存(缓存时间比较短,大概只有1分钟,且只能容纳1000条缓存)
    如果浏览器自身的缓存里面没有找到,那么浏览器会搜索系统自身的DNS缓存
    如果还没有找到,那么尝试从 hosts文件里面去找
    在前面三个过程都没获取到的情况下,浏览器就会发起一个DNS的系统调用,就会向本地配置的首选DNS服务器(一般是电信运营商提供的,也可以使用像Google提供的DNS服务器)发起域名解析请求(通过的是UDP协议向DNS的53端口发起请求,这个请求是递归的请求,也就是运营商的DNS服务器必须得提供给我们该域名的IP地址)
    三次握手完成之后这个TCP连接就进入Established状态,就可以发起http请求了。

  • 回答:
  • 浏览器进行DNS域名解析,得到对应的IP地址
    根据这个IP,找到对应的服务器建立连接(三次握手)
    建立TCP连接后发起HTTP请求(一个完整的http请求报文)
    服务器响应HTTP请求,浏览器得到html代码(服务器如何响应)
    浏览器解析html代码,并请求html代码中的资源(如js、css、图片等)
    浏览器对页面进行渲染呈现给用户
    服务器关闭TCP连接(四次挥手)

题目十
  • 题干:说一下zookeeper和ES
  • 分析:
  • 主要考察两者选举时的一些差别

  • 回答:
  • ES集群在启动时,选取集群master,按照nodeId进行排序。同时为防止分裂,需一半以上节点同意zookeeper集群在启动时,根据节点id和事务id进行比较。在集群初始化时,事务id都为空,按照节点id进行排序当zookeeper集群leader故障时,会重新选取leader。在选举过程中,如果原leader复活,则继续担任leader角色当zookeeper集群leader故障时,会重新选取leader。先比较事务id,如果事务id相同,再根据节点id排序

发布了122 篇原创文章 · 获赞 32 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/YangzaiLeHeHe/article/details/105121200