Java面向对象以及优缺点-秋招面试--使用线程池的好处--拒绝策略

⾯向对象是⼀种基于⾯向过程的编程思想,是向现实世界模型的⾃然延伸,这是⼀种“万物皆对象”的编程思想。由执⾏者变为指者,在现实⽣活中的任何物体都可以归为⼀类事物,⽽每⼀个个体都是⼀类事物的实例。⾯向对象的编程是以对象为中⼼,以消息为驱动。
区别: (1)编程思路不同:⾯向过程以实现功能的函数开发为主,⽽⾯向对象要⾸先抽象出类、属性及其⽅法,然后通过实例化类、执⾏⽅法来完成功能。
(2)封装性:都具有封装性,但是⾯向过程是封装的是功能,⽽⾯向对象封装的是数据和功能。
(3)⾯向对象具有继承性和多态性,⽽⾯向过程没有继承性和多态性,所以⾯向对象优势很明显

方法重写规则

重写遵循“两同两小一大”规则:
两同: 方法名、形参列表相同
两小:
子类方法返回值类型应比父类方法返回值类型更小或相等
子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等
一大:
子类方法的访问权限应比父类方法访问权限更大或相等

在这里插入图片描述

7.合成复用原则

又叫==组合/聚合复用原则.他要求在软件复用时,要尽量使用组合或聚合等关联关系来实现,其次才烤炉使用继承关系来实现

如果要使用继承关系,则必须严格遵循里氏替换原则,合成复用原则同里氏替换原则相辅相成的,两者都是开闭原则的具体实现规范。

通常类的复用分为两种:继承复用和合成复用两种,

继承复用虽然有简单和易实现的优点,但是他也存在一下的缺点:

  • 继承复用破坏了类的封装性,因为继承会将父类的实现细节暴露给子类,父类对子类是透明的,所以这种复用又称为“白箱”复用。
  • 子类与父类的耦合度高,父类的实现的任何改变都会导致子类的实现发生改变,这不利于类的维护与扩展
  • 他限制了复用的灵活性,从父类继承而来的实现是静态的,在编译时已经定义,所以运行时不可能发生变化

采用组合或者聚合复用可以将已有的对象纳入新对象中,使之称为新对象的一部分,新对象可以调用以有对象的功能,

优点:

  • 他维持了类的封装性,因为成分对象的内部细节时新对象看不见的,所以这种复用又称为“黑箱”复用。
  • 新旧类之间的耦合度低,这种复用所需的依赖较少,新对象存取成分对象的唯一方式时通过成分对象的接
  • 复用的灵活性高,这种复用可以在运行时动态进行,新对象可以动态的引用与成分对象类型相同的对象

在这里插入图片描述

⾯向对象是⼀种基于⾯向过程的编程思想,是向现实世界模型的⾃然延伸,这是⼀种“万物皆对象”的编程思想。由执⾏者变为指ഀ者,在现实⽣活中的任何物体都可以归为⼀类事物,⽽每⼀个个体都是⼀类事物的实例。⾯向对象
的编程是以对象为中⼼,以消息为驱动。
区别: (1)编程思路不同:⾯向过程以实现功能的函数开发为主,⽽⾯向对象要⾸先抽象出类、属性及其⽅法,然后通过实例化类、执⾏⽅法来完成功能。
(2)封装性:都具有封装性,但是⾯向过程是封装的是功能,⽽⾯向对象封装的是数据和功能。
(3)⾯向对象具有继承性和多态性,⽽⾯向过程没有继承性和多态性,所以⾯向对象优势很明显

封装

  • 方法,继承都是封装的一种体现,private(私有的)也是封装的一个体现。被private修饰的成员变量只能在本类中使用,外部不能直接通过对象属性改变。获取和改变需要提供设置器(访问接口|访问方法)和访问器来进行操作。

特点:

  • 可以隐藏内部细节,对外提供公共访问的方法

  • 提高了安全性,提高了代码的复用

  • 这种多个封装的模板类统称之为javabean,模板类需要满足的一些规则

    类是公共的

    属性是私有的

    提供公有的访问方式 setget

    最好定义一个空构造

    四种权限的修饰关键字

  1. private:只能被本类访问

  2. default: 默认属性,并且不能写出来 只要你没有用其他修饰默认就是default

    能被同包目录下访问

  3. protected:除了能被同包访问,还可以给不同包下的字类访问

  4. public:公共的 可以被其他包访问

注意:类名只能被 publicdefault修饰

继承的优缺点

优点:
功能复用:直接将已有的属性和行为继承过来,实现了功能的复用,节省了大量的工作
便于扩展新功能:在已有功能的基础上,更容易建立,扩充新的功能
结构清晰,简化认识:同属于一个继承体系的相关类,他们之间结构层次清晰,简化了人们对代码结构的认识
易维护性:不同类之间的继承关系,让这些事务之间保持一定程度的一致性,大大降低了维护成本

缺点:
打破了封装性:父类向子类暴露了实现细节,打破了父类对象的封装性
高耦合性:类与类之间紧密的结合在一起,相互依赖性高

静态方法不能被重写

程序设计的追求:高内聚,低耦合
耦合:两个(或更多)模块相互依赖于对方 (像齿轮接触点一样,比较小)

继承:

方法重写规则

重写遵循“两同两小一大”规则:
两同: 方法名、形参列表相同

两小:

子类方法返回值类型应比父类方法返回值类型更小或相等
子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等

一大:

子类方法的访问权限应比父类方法访问权限更大或相等 里氏替换原则

里氏替换原则: 不要破环继承体系,子类重写方法 功能,不应该影响父类的含义 防止继承滥用

合成复用原则: 尽可能使用聚合关系实现代码的复用,少用继承,减低了代码的耦合在这里插入图片描述

多态:

同一事物在不同时候的不同状态

继承 重写 父类引用变量可以指向子类对象

优点:
  提高了代码的维护性(继承保证)
  提高了代码的扩展性(多态保证)
缺点:
  不能使用子类的特有功能—向下转型 向下转型instanceof判断

使用线程池的好处

使用线程池比手动创建线程主要有三点好处。

  • 第一点,线程池可以解决线程生命周期的系统开销问题,同时还可以加快响应速度。因为线程池中的线程是可以复用的,我们只用少量的线程去执行大量的任务,这就大大减小了线程生命周期的开销。而且线程通常不是等接到任务后再临时创建,而是已经创建好时刻准备执行任务,这样就消除了线程创建所带来的延迟,提升了响应速度,增强了用户体验。
  • 第二点,线程池可以统筹内存和 CPU 的使用,避免资源使用不当。线程池会根据配置和任务数量灵活地控制线程数量,不够的时候就创建,太多的时候就回收,避免线程过多导致内存溢出,或线程太少导致 CPU 资源浪费,达到了一个完美的平衡。
  • 第三点,线程池可以统一管理资源。比如线程池可以统一管理任务队列和线程,可以统一开始或结束任务,比单个线程逐一处理任务要更方便、更易于管理,同时也有利于数据统计,比如我们可以很方便地统计出已经执行过的任务的数量。

拒绝策略

  • 第一种拒绝策略是 AbortPolicy,这种拒绝策略在拒绝任务时,会直接抛出一个类型为 RejectedExecutionException 的 RuntimeException,让你感知到任务被拒绝了,于是你便可以根据业务逻辑选择重试或者放弃提交等策略。
  • 第二种拒绝策略是 DiscardPolicy,这种拒绝策略正如它的名字所描述的一样,当新任务被提交后直接被丢弃掉,也不会给你任何的通知,相对而言存在一定的风险,因为我们提交的时候根本不知道这个任务会被丢弃,可能造成数据丢失。
  • 第三种拒绝策略是 DiscardOldestPolicy,如果线程池没被关闭且没有能力执行,则会丢弃任务队列中的头结点,通常是存活时间最长的任务,这种策略与第二种不同之处在于它丢弃的不是最新提交的,而是队列中存活时间最长的,这样就可以腾出空间给新提交的任务,但同理它也存在一定的数据丢失风险。
  • 第四种拒绝策略是 CallerRunsPolicy,相对而言它就比较完善了,当有新任务提交后,如果线程池没被关闭且没有能力执行,则把这个任务交于提交任务的线程执行,也就是谁提交任务,谁就负责执行任务。这样做主要有两点好处。

第一点新提交的任务不会被丢弃,这样也就不会造成业务损失。第二点好处是,由于谁提交任务谁就要负责执行任务,这样提交任务的线程就得负责执行任务,而执行任务又是比较耗时的,在这段期间,提交任务的线程被占用,也就不会再提交新的任务,减缓了任务提交的速度,相当于是一个负反馈。在此期间,线程池中的线程也可以充分利用这段时间来执行掉一部分任务,腾出一定的空间,相当于是给了线程池一定的缓冲期。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值