java面试(十二)

1、Java的堆和栈区别

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

2、 Java的GC垃圾回收机制

GC (Garbage Collection)的基本原理:将内存中不再被使用的对象进行回收,GC中用于回收的方法称为收集器,由于GC需要消耗一些资源和时间,Java在对对象的生命周期特征进行分析后,按照新生代、旧生代的方式来对对象进行收集,以尽可能的缩短GC对应用造成的暂停。

(1)对新生代的对象的收集称为minor GC;

(2)对旧生代的对象的收集称为Full GC;

(3)程序中主动调用System.gc()强制执行的GC为Full GC。

不同的对象引用类型, GC会采用不同的方法进行回收,JVM对象的引用分为了四种类型:

(1)强引用:默认情况下,对象采用的均为强引用(这个对象的实例没有其他对象引用,GC时才会被回收)

(2)软引用:软引用是Java中提供的一种比较适合于缓存场景的应用(只有在内存不够用的情况下才会被GC)

(3)弱引用:在GC时一定会被GC回收

(4)虚引用:由于虚引用只是用来得知对象是否被GC

垃圾收集算法

标记和清除、复制算法、标记-整理算法、分代收集算法

3、 什么是多态?

父类型的引用指向子类型的对象。用一句比较通俗的话:同一操作作用于不同的对象,可以产生不同的效果。这就是多态。

这句话很好理解:Person person = new Student("张三");但是这个多态有什么作用呢?而我们又为什么要是有多态呢?

首先讲下封装和继承:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面,他把实现的细节影藏起来了,比如你在java中去实现一个类,这个类中提供了一些功能方法,你只需要知道你需要传递什么样的参数,会达到什么样的效果,实现细节在类中定义好了。从而使得代码模块化;而继承可以扩展已存在的代码模块,而目的就是为了代码重用。

那么多态除了代码的复用,还可以解耦。然而为什么要解耦?耦合度讲的是模块模块之间,代码代码之间的关联度,通过对系统的分析把他分解成一个一个子模块,子模块提供稳定的接口,达到降低系统耦合度的的目的,模块模块之间尽量使用模块接口访问,而不是随意引用其他模块的成员变量。

4、你在项目中做过哪些性能优化

  • 减少 HTTP 请求数
  • 使用 CDN
  • 使用外部 JavaScript 和 CSS
  • 避免重定向
  •  图片懒加载
  • 尽量减少 iframe 使用
  • 减少 DOM 元素数量
  • 减少 DOM 操作
  • 减少 DNS 查询
  • js放在页面底部
  • 去除重复的js
  • 避免图片src为空

从架构设计的角度

上图web服务器一般以集群的形式,用lvs,Nginx等开源工具做反向代理和API层的负载均衡。业务层service可以用Dubbo等RPC框架实现分布式调用,达到多节点同时处理计算,现在又有一种新的趋势,以springboot框架做微服务进行服务间以restful接口调用,两种形式各有千秋,前者较后都就目前来说更流行一些,在此只关注对性能相关的话题。

    另外,使用redis,memcache等开源工具做缓存对性能也有较大的提高,当然也会有一些管理难的代价,管理不好经常出现数据不一致。

从数据库的角度

关系形数据库在数据量达到一定规模查询效果较差,像一些操作纪录等数据可以用elasticsearch,redis,mongodb等nosql非关系形数据库来存储,查询性能比关系形数据库好很多,但是比如金钱,订单,用户信息等“贵重”信息只能用关系形数据库来存储。关系形数据库性能提高常的方法一般包括建立索引,视图等。


从代码的角度:

  • 异步处理,future模式,可以先返回一个Future给调用者,主线程可以立即得到返回,往下运行,等需要得到结果时调用future.get()方法获取结果,此方法会阻塞,当然可以设置一个超时时间, 防止程序死在这里。java8中有CompletableFuture增强Future,自带forkJorkPool线程池
  • countDownLatch
  • java8并行流

5、如何优化页面卡顿

场景1
页面展示一个列表,每行代表一名员工,员工可以展开,代表一个项目,项目还可以展开,代表一个任务。这个页面还是双tab页面,也就是说1号tab,2号tab分别展示两个多级列表。

总条数很多的时候,卡了。

场景2
页面左右两部分,左侧部分是一堆项目列表,当作一排导航,每点击一个项目,右侧展示项目的所有任务列表。

当任务列表几千条,左侧项目列表也很多的时候,鼠标滑动左侧项目列表,卡了。

chrome 性能测试

chrome dev tools的 performance 可以测出页面的卡顿来自什么部分。非常好用。

解决方案
场景1就是这样的结果。scripting占比很大。
当时的解决思路是:

背景: nej+ regular全家桶,发现前端不断组合后端数据的时候,由于数据一直在变,可变数据会导致出发regular框架的自动view层更新,导致view层一直在更新。

解决办法:保证view层对应的那个model数据是不可变的,等前端所有数据计算完毕,再去修改model。才去触发view。

进阶:其实计算量巨大的时候,(如果后面业务量很大),直接开一个worker单独计算那几千条数据(没办法,后端懒,给的数据是棵无法直接展示的树,需要遍历计算,后面数据量会很大,当时就几千条了),计算完更新一波model去刷新view层即可。

场景2的rendering占比比较大。
由于我在滚动的时候,有一些圆角的元素,浏览器在渲染的时候计算量大,所以,我最后开启了硬件加速。

transform: translateZ(0); 
 

6、 Handler消息机制

Handler,来帮助我们将子线程的数据传递给主线程,其实,当熟悉了Handler的原理之后我们知道,Handler不仅仅能将子线程的数据传递给主线程,它能实现任意两个线程的数据传递。

在使用handler的时候,在handler所创建的线程需要维护一个唯一的Looper对象, 每个线程对应一个Looper,每个线程的Looper通过ThreadLocal来保证。
Looper对象的内部又维护有唯一的一个MessageQueue,所以一个线程可以有多个handler,但是只能有一个Looper和一个MessageQueue。
Message在MessageQueue不是通过一个列表来存储的,而是将传入的Message存入到了上一个Message的next中,在取出的时候通过顶部的Message就能按放入的顺序依次取出Message。
Looper对象通过loop()方法开启了一个死循环,不断地从looper内的MessageQueue中取出Message,
然后通过handler将消息分发传回handler所在的线程。

7、MVC模式与MVP模式

MVC模式:

    

  •  MVC的所有通信都是单向的。
  • view传送指令到controller(用户也可以直接将指令传到controller)。
  • controller完成业务逻辑后要求model改变状态。
  • model将新的数据发送到view,用户得到反馈。

MVP模式:

    MVP模式将Controller改名为Presenter,同时改变了通信方向。

    

  • 各部分之间的通信都是双向的。
  • View与Model不发生联系,都通过Presenter传递
  • View非常薄,不部署任何业务逻辑,称为“被动视图”,即没有任何主动性,而Presenter非常厚,所有逻辑都部署在这里。

把Controller和View混在一起,有什么问题?

  • 难以测试。
  • 必须手动点击,使用各种自动化的测试工具。
  • 代码难以重用。
  • UI是很难重用,因为要求总是不同。所以,导致重复的代码四处都是,维护麻烦。

什么是MVC(Model View Presenter)模式?

  • 为了使得视图接口可以与模型和控制器进行交互,控制器执行一些初始化事件
  • 用户通过视图(用户接口)执行一些操作
  • 控制器处理用户行为(可以用观察着模式实现)并通知模型进行更新
  • 模型引发一些事件,以便将改变发告知视图
  • 视图处理模型变更的事件,然后显示新的模型数据
  • 用户接口等待用户的进一步操作

MVP模式

与“被动—MVC模式”很接近,区别在于“视图并不使用模型”。在MVP模式中视图和模型是完全分离的,他们通过Presenter进行交互。
Presenter与控制器非常相似,但是它们也有一些的区别:

  • Presenter处理视图发送过来的用户操作(在MVC中视图自己处理了这些操作)
  • 它用更新过的数据去更新模型(在被动MVC中控制器只是通知视图去更新过的模型中去取新的数据,而主动MVC中模型通知视图去更新显示,控制器不需要做工作)
  • 检查模型的更新(与被动MVC一样)
  • (与MVC的主要区别)从模型中取数据然后将它们发送到视图中
  • (与MVC的主要区别)将所做的更新告知视图
  • (与MVC的区别)用Presenter渲染视图


MVP的优势

  • 模型与视图完全分离,我们可以修改视图而不影响模型
  • 可以更高效地使用模型,因为所以的交互都发生在一个地方——Presenter内部
  • 我们可以将一个Presener用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
  • 如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)

8、HTTP和HTTPS的区别

  • https协议需要到CA  (Certificate Authority,证书颁发机构)申请证书,一般免费证书较少,因而需要一定费用。(原来网易官网是http,而网易邮箱是https。)
  • http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
  • http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
  • http的连接很简单,是无状态的。Https协议是由SSL+Http协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。(无状态的意思是其数据包的发送、传输和接收都是相互独立的。无连接的意思是指通信双方都不长久的维持对方的任何信息。)

Https的优点

  • 使用Https协议可认证用户和服务器,确保数据发送到正确的客户机和服务器。
  • Https协议是由SSL+Http协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全,可防止数据在传输过程中不被窃取、修改,确保数据的完整性。
  • Https是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。

9、你用到过的加密算法

MD5算法

MD5 用的是 哈希函数,它的典型应用是对一段信息产生 信息摘要,以 防止被篡改。严格来说,MD5不是一种 加密算法 而是 摘要算法。无论是多长的输入,MD5 都会输出长度为 128bits 的一个串 (通常用 16 进制 表示为 32 个字符)。

发布了56 篇原创文章 · 获赞 12 · 访问量 9977

猜你喜欢

转载自blog.csdn.net/doubicheng/article/details/103766477