总目录展示
该笔记共八个节点(由浅入深),分为三大模块。
高性能。 秒杀涉及大量的并发读和并发写,因此支持高并发访问这点非常关键。该笔记将从设计数据的动静分离方案、热点的发现与隔离、请求的削峰与分层过滤、服务端的极致优化这4个方面重点介绍。
一致性。 秒杀中商品减库存的实现方式同样关键。可想而知,有限数量的商品在同一时刻被很多倍的请求同时来减库存,减库存又分为“拍下减库存”“付款减库存”以及预扣等几种,在大并发更新的过程中都要保证数据的准确性,其难度可想而知。因此,将用一个节点来专门讲解如何设计秒杀减库存方案。
高可用。 虽然介绍了很多极致的优化思路,但现实中总难免出现一些我们考虑不到的情况,所以要保证系统的高可用和正确性,还要设计一个PlanB来兜底,以便在最坏情况发生时仍然能够从容应对。笔记的最后,将带你思考可以从哪些环节来设计兜底方案。
篇幅有限,无法一个模块一个模块详细的展示(这些要点都收集在了这份《高并发秒杀顶级教程》里),麻烦各位转发一下(可以帮助更多的人看到哟!)
由于内容太多,这里只截取部分的内容。
这里简单描述了从买脐橙到吃脐橙的一个过程,面向过程就是把上面每个步骤用不同的方法来实现。
面向对象举例:
面向对象的设计则是从另外的思路来解决问题,如下:
我要吃脐橙–>女朋友把脐橙拿到你面前–>吃。 完事
分析一下,女朋友要做哪些事情:
出门–>坐车–>超市–>挑选脐橙–>付钱–>坐车回家–>拿出脐橙–>剥脐橙–>喂你–>洗手。
这是肯定会有小伙伴说了,你这跟面向过程并没有区别呀,这是动作只是分成了2个人去完成而已,并没有减少或者优化什么。
表面上看起来确实是这样的,但我们可以透过问题看本质:
- 对于“你”,这个角色来说,是不是只需要说我要吃橙子(调用方法),然后张开嘴巴吃就行了,这是毫无疑问的优化,如果没有女朋友(对象),你有这个福利吗?
- 对于“女朋友”这个角色来说,她是不是只可以给你发这福利?当然不是,如果哪天她不是你的对象,而是别人的对象了,别人说“我要吃橙子”,他是不是也可以使用到这个福利? 也就是说“女朋友”这个对象,有个方法叫“给男朋友吃橙子”,是不是她的男朋友就可以调用了呢。
- 如果你还是面向过程(单身),你想吃脐橙,那你只能重复如下过程:
出门–>坐车–>超市–>挑选脐橙–>付钱–>坐车回家–>拿出脐橙–>剥脐橙–>吃脐橙–>洗手,周而复始。
- 同理面向对象,只要调用“我想吃脐橙”方法,重复利用,不需要关心方法里面具体在做什么,当然这个“女朋友”对象也是可以重复利用的,要是对象切换了,”吃脐橙“方法也是封装好的,不会消失,别人也可以调用。
于是明哥我就问你,你听懂了吗?如果没听懂,那我就没辙了。
对象的定义
对象就是存在的具体实体,具有明确定义的状态和行为,是面向对象编程的核心,用来描述现实世界中的实体,为计算机应用程序提供实体基础,也是完成特定任务一个封装。
面向对象的三大特性
封装
封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。
封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
通俗来说,你的女朋友你调用”我要吃脐橙“方法,你可以吃到脐橙,别人也可以调用他的女朋友对象的”我要吃脐橙“方法,而你能否调用”别人“女朋友”的 “我要吃脐橙”方法?答案显然是不可以的。
也就是说类是一个抽象的集合,在这里“女朋友”抽象成类。
而对象是一个独立的个体,比如你的女朋友,他的女朋友;她们都是“女朋友”,但她们又是相互独立没有关系的。
代码举例
- 创建一个“女朋友”类
public class GirlFriend {
String name;//名字
int age;//年龄
}
测试一下:
public class Test {
public static void main(String[] args) {
GirlFriend girlFriend = new GirlFriend();
girlFriend.name="蔡文姬";
System.out.println("我的女朋友:"+girlFriend.name);
}
}
运行结果:
我的女朋友:蔡文姬
- 对成员属性的封装
上例中2个成员属性,name、age没有做限制,所以可以直接在测试类中使用(赋值、取值),但实际上一般来说成员属性是要做限制的,给成员属性加上private。
public class GirlFriend {
private String name;//名字
private int age;//年龄
}
此时我们再看测试类,是报错的
于是我们可以将赋值和取值封装成方法。
- 取值方法、 赋值方法
成员属性是private私有的,而方法是public公开的。
public class GirlFriend {
private String name;//名字
private int age;//年龄
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
测试调用:
public class Test {
public static void main(String[] args) {
GirlFriend girlFriend = new GirlFriend();
//girlFriend.name="蔡文姬";
//System.out.println("我的女朋友:"+girlFriend.name);
girlFriend.setName("蔡文姬");
girlFriend.setAge(18);;
System.out.println("我的女朋友:"+girlFriend.getName()+","+girlFriend.getAge()+"岁");
}
}
调用:
我的女朋友:蔡文姬,18岁
- 构造方法赋值
public GirlFriend(String name,int age){
this.name=name;
this.age=age;
}
测试代码
public class Test {
public static void main(String[] args) {
GirlFriend girlFriend = new GirlFriend("蔡文姬",18);
// girlFriend.setName("蔡文姬");
// girlFriend.setAge(18);
System.out.println("我的女朋友:"+girlFriend.getName()+","+girlFriend.getAge()+"岁");
}
}
运行结果:
我的女朋友:蔡文姬,18岁
- 加入对象的归属
为什么要加入对象的归属呢,因为类是抽象的,而对象是一个个的独立的,总不能人人“女朋友”都是蔡文姬吧,这不是乱了套吗?而且java中一旦使用 new 创建一个对象后,这个对象就是独立的个体。
GirlFriend girlFriend = new GirlFriend(“蔡文姬”,18);
都使用了上述代码来创建了一个 girlFriend ,但是每次都其实不是同一个“女朋友”。
代码验证一下:
public class Test {
public static void main(String[] args) {
/\* GirlFriend girlFriend = new GirlFriend("蔡文姬",18);
// girlFriend.setName("蔡文姬");
// girlFriend.setAge(18);
System.out.println("我的女朋友:"+girlFriend.getName()+","+girlFriend.getAge()+"岁");
\*/
GirlFriend girlFriend = new GirlFriend("蔡文姬",18);
GirlFriend girlFriend1 = new GirlFriend("蔡文姬",18);
System.out.println(girlFriend.hashCode());
System.out.println(girlFriend1.hashCode());
}
}
运行结果:
366712642
1829164700
从输出可以看到,不是同一个对象,我可以这样改:
public class GirlFriend {
private String name;// 名字
private int age;// 年龄
private String manName;// 男人的名字
public String getManName() {
return manName;
}
public void setManName(String manName) {
this.manName = manName;
}
public GirlFriend(String name, int age,String manName) {
this.name = name;
this.age = age;
this.manName = manName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
测试代码:
public class Test {
public static void main(String[] args) {
GirlFriend girlFriend = new GirlFriend("蔡文姬",18,"我");
GirlFriend girlFriend1 = new GirlFriend("瑶",19,"你");
System.out.println(girlFriend.getManName()+"的女朋友:"+girlFriend.getName()+","+girlFriend.getAge()+"岁");
System.out.println(girlFriend1.getManName()+"的女朋友:"+girlFriend1.getName()+","+girlFriend1.getAge()+"岁");
}
}
运行结果:
我的女朋友:蔡文姬,18岁
你的女朋友:瑶,19岁
封装的好处
- 提高了数据的安全性
对于私有的成员属性:别人无法通过 变量名.属性名 的方式来修改。 - 使用变得更加简单
封装后,多个调用者在使用的时候,获得此对象,然后调用相对应的方法即可。 - 实现了隐藏
实现过程对调用者是不可见的,调用者只需调用方法即可,不知道具体实现过程。
就如之前举例中,你无需关心你“女朋友”是怎么给你弄到橙子的,你只要告诉“她”我要吃橙子,然后等她拿橙子喂你即可。
继承
概述
继承机制是面向对象程序设计不可缺少的关键概念,是实现软件可重用的根基,是调高软件系统的可扩展性与可维护性的主要途径。
在Java中,被继承的类我们称之为父类,也叫基类;继承的类叫子类,也称为派生类或超类;继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能继承已有类的数据属性和行为,当然子类也可以扩展属于自己的新能力。
通俗来说,我们每个人都从父母那里继承来了不少能力,比如:吃饭、喝水、说话、走路、思考等等,也可以扩展自己的能力,比如:学编程、打王者(跑题了)。
在Java中,使用如下的语法实现继承的关系:
class 子类 extends 父类{}
代码讲解
- 继承成员变量
public class Test {
public static void main(String[] args) {
Student student = new Student();
System.out.println(student.age);
}
}
class Human {
int age = 20;//年龄
}
class Student extends Human{
}
运行结果:
20
可以看到 age属性被继承下来了,但是如果 age声明为private的,则无法被继承了。
- 继承成员方法
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.study();
}
}
class Human {
int age = 20;//年龄
void study(){
System.out.println("学习技能");
}
}
class Student extends Human{
}
运行结果:
学习技能
当然也是不能继承父类声明为 private 的成员方法的。
- 重写
重写,是让子类拥有自己的实现,当然形参和返回值不能够改变,可以修改子类中的实现代码。
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.study();
}
}
class Human {
int age = 20;//年龄
void study(){
System.out.println("学习技能");
}
}
class Student extends Human{
@Override
void study(){
System.out.println("在学校学习知识");
}
}
运行结果:
在学校学习知识
- super关键字
最后
看完上述知识点如果你深感Java基础不够扎实,或者刷题刷的不够、知识不全面
小编专门为你量身定制了一套<Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法>
针对知识面不够,也莫慌!还有一整套的<Java核心进阶手册>,可以瞬间查漏补缺
全都是一丢一丢的收集整理纯手打出来的
更有纯手绘的各大知识体系大纲,可供梳理:Java筑基、MySQL、Redis、并发编程、Spring、分布式高性能架构知识、微服务架构知识、开源框架知识点等等的xmind手绘图~
一套<Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法>
[外链图片转存中…(img-79t22o7k-1714863638076)]
针对知识面不够,也莫慌!还有一整套的<Java核心进阶手册>,可以瞬间查漏补缺
[外链图片转存中…(img-KWXz1i55-1714863638077)]
全都是一丢一丢的收集整理纯手打出来的
更有纯手绘的各大知识体系大纲,可供梳理:Java筑基、MySQL、Redis、并发编程、Spring、分布式高性能架构知识、微服务架构知识、开源框架知识点等等的xmind手绘图~
[外链图片转存中…(img-AMT14Bc3-1714863638077)]
[外链图片转存中…(img-vS9h7VV7-1714863638078)]