2021-01-31

万字长文详细总结!关于继承、重写与重载、封装、接口的硬核干货

在这里插入图片描述


Java语言在面向对象方面的知识点复杂繁琐,但是几乎是每个小伙伴学习编程必须踩的坑,其实,面向对象的底层都是一些计算机底层知识的结合,所以,不注重基础的程序猿,一定不是一个可以走的远的程序猿。那么,今天,我们先逐一地深入了解继承、重载、接口和构造器的知识。

在学习这篇文章之前,如果有小伙伴对new过程发生了什么很感兴趣的话,可以先用几分钟看完这篇文章。

new的过程发生了什么?看完这一篇就懂了

好了,正题开始。

类的继承

类的继承是指从已经定义好存在的类中派生出一个新的类,我们在定义新类时,可以基于一个已经设计好的类,从已存在的类中继承有用的功能(属性和方法),这时已经存在的类便称为父类,而这个继承的新类则称为子类。在类的继承中,父类一般会具有所有子类的共有特性,而子类则可以增加一些个性化的方法。而子类还可以继续派生出新的子类因此位于上层的类在概念上会更抽象,而位于下层的类就会更具体。

假设一个场景,你有一个朋友,家里超级有钱,你为了能够继承他的家产,认他做了爸爸,这个时候,假如他去了美国,感染了新冠肺炎,你以为你可以顺理成章地继承他的百万油田,千万矿山了,但是有一句话说得好,[你是想笑死我,然后继承我的支付宝花呗借呗吗😂],原来,他平时消费都用花呗,借呗,京东白条,光信用卡就几十张了[少年,你渴望力量吗],这个时候你只好认栽,好的坏的都继承了。

所以,这个例子就说明了,继承就是不好的好的都继承了,所以父类的全局属性,方法都可以在子类中轻松的访问到

  • 父类和子类

在Java中实现继承十分地简单,具体语法如下:


<修饰符> class <子类名字> extends <父类名字> {

      [<成员变量定义>]
      [<方法的定义>]

}

当然,通常所说的子类一般指的是某个父类地直接子类,所以父类也可称为该子类的直接超类。如果存在多层继承关系的话,那么,就得按情况具体分析。

在Java程序中,一个类只能有一个父类,也就是说在extends关键字后面只能有一个类,它不支持多重继承而接口是允许的

来看一个例子


public class Test {                                               
 public static void main(String[] args) {
  SubClass sc = new SubClass("valdcode","codevald",21);

 }

}

class SuperClass {

 //父类
 
 String name;
 int age;

 //构造方法
 SuperClass(String name,int age) {
 
  System.out.println("大家好,我是" + name);
  System.out.println("今年" + age + "岁");
 }
}

class SubClass extends SuperClass {

 //定义子类
 
 SubClass(String wechat,String name,int age) {
 
  super(name,age);
  System.out.println(1 > 0 ? "目前专注于研究计算机底层知识的研究" : "否");
  System.out.println("我的微信号是" + wechat + ",有问题欢迎添加一起交流");
 
 }

}

}

在上面的代码中,类SubClass是一个子类,继承了父类SuperClass的属性和方法。在子类的构造方法中,通过Super()调用了父类的构造方法。这充分地说明子类是可以适用父类的属性和方法。在main()函数里面,调用子类SubClass的构造方法,子类调用父类的构造方法Super(),设置对应的参数值

来看下控制台会输出什么。

那么,在刚才的例子中,涉及到一个概念,构造方法,构造方法是Java类中比较重要的特殊方法,一个子类可以访问父类的构造方法。在Java中调用父类构造方法会使用super(参数)这个方法。

再来看下一段代码


public class JavaEnginer extends Enginer {
 //super和this
 //定义子类
 JavaEnginer() {
  super(); //调用父类无参数构造器
  prt("A Java Enginer."); //调用父类中的方法prt()
 }
 JavaEnginer(String name) {
  super(name);
  prt("A Java Enginer: " + name);
 }
  
 JavaEnginer(String name,String official_Accounts) {
  this(name); //调用有参数的构造器
  prt(name + "'s Official Accounts: " + official_Accounts); //调用父类中的方法
 }
 
 public static void main(String[] args) {
  JavaEnginer je = new JavaEnginer(); 
  je = new JavaEnginer("codevald"); 
  je = new JavaEnginer("codevald","@CodeVald");
 }
}

class Enginer {
 public static void  prt(String s) {

  //定义静态方法prt()
  System.out.println(s); //输出
 }

 //没有参数的构造器
 Enginer() {
  prt("A Enginer"); //输出文本
 }
 Enginer(String name) {
  prt("A enginer: " + name); //输出文本
 }
}

调用父类的构造方法

在上面的代码中,在子类中使用了super和this两个不同的关键字表示不同的意思。在super后面加参数调用的是父类中具有相同形参的构造函数。

比如这个

JavaEnginer(String name) {
  super(name);
  prt("A Java Enginer: " + name);
 }

而在this后面加参数调用的是当前类中具有另一个形参的构造函数。比如这段

JavaEnginer(String name,String official_Accounts) {
  this(name); //调用有参数的构造器
  prt(name + "'s Official Accounts: " + official_Accounts); //调用父类中的方法
 }
 }

而在子类中,可以随意调用父类中的方法,当然了,也可以加上this表示调用当前类继承父类中的方法或者加上super的形式,也是可以正常编译的。

比如下面这段

JavaEnginer() {
  super(); //调用父类无参数构造器
  prt("A Java Enginer."); //调用父类中的方法prt()
    /**
    *this.prt("A Java Enginer.") or 
    *super.prt("A Java Enginer.")都可以
    **
 }

来看下最终的运行结果

访问父类的属性和方法

在Java中,子类可以轻松的访问父类的属性和方法,当然还是用刚才提过的super()了。具体语法格式 就是 super.[方法或全局变量]

来新建一个Demo

//子类
public class AccessSuperClassProperty extends SuperClass {
 public String name = "CodeVald";
 //输出子类的name
 public void printOwner() {
  System.out.println(name);
 }

 public void printSuper() {
  System.out.println(super.name);
 }

 public static void main(String[] args) {
  AccessSuperClassProperty scp = new AccessSuperClassProperty();
  System.out.println(scp.name); //直接输出子类的name
  scp.printOwner(); //直接输出子类的name
  scp.printSuper(); //直接输出父类的name
 }
}

//父类
class SuperClass {
 public String name = "codevald"; 
}

在上面的代码中,分别在子类和父类中创建了同一个名字的变量属性name,name的初始值不同。

然后,通过super来访问与方法调用者对应的父类的对象

当系统创建AccessSuperClassProperty对象时,会对应创建一个父类对象SuperClass,不过父类对象的属性只有通过super作为调用者才可以访问到而已。

来看下代码执行后的结果

在上述的代码中,覆盖的是父类的属性,那么在子类的方法中可以通过父类名作为调用者来访问被覆盖的类属性,如果子类中没有包含和父类同名的属性,则子类可以继承父类属性,那么在子类实例方法中就无需显式地适用super作为调用者。所以,如果在某个方法中访问一个同名的属性,且没有显式地指定调用者,那么系统查找地顺序为

  • 查找方法中是否有名为x的局部变量
  • 查找当前类中是否包含名为x的属性
  • 查找x的直接父类中是否包含名为x的属性,依次上溯到x的父类,直到java.lang.object类。如果最终没有找到,就提示编译错误

多重继承

在Java中,多重继承指的是A继承了B,而C继承了A,那么,这种就叫做多重继承

来看个Demo

public class TestDemo {

 public static void main(String[] args) {
 
  Singer s1 = new Singer();
  Singer s2 = new Singer(s1);
  s1.print();
  s2.print();
  
  FolkSinger fs1 = new FolkSinger();
  FolkSinger fs2 = new FolkSinger("沈以城","《绿洲》");
  FolkSinger fs3 = new FolkSinger(fs2);
  
  fs1.print();
  fs2.print();
  fs3.print();
    
  FavoriteFolkSinger ffs1 = new FavoriteFolkSinger();  
  FavoriteFolkSinger ffs2 = new FavoriteFolkSinger("沈以城","《绿洲》");
  FavoriteFolkSinger ffs3 = new FavoriteFolkSinger(ffs2);
    
  ffs1.print();
  ffs2.print();
  ffs3.print();
 
 }
}

class FavoriteFolkSinger extends FolkSinger {

 FavoriteFolkSinger() {
  super();
 }
 
 FavoriteFolkSinger(FavoriteFolkSinger fs) {
  super(fs);
 }

 FavoriteFolkSinger(String name,String songTitle) {
 
  super(name,songTitle);

 }
 
 @Override 
 
 void print() {
  
  System.out.println("codevald最喜欢的" + "歌手为: " + super.name + " 代表作为: " + super.songTitle);
 }
}

class FolkSinger extends Singer {

 FolkSinger() {
 
  super("徐秉龙","《迂回》");
 
 }

 FolkSinger(FolkSinger fs) {
 
  super(fs);

 }
 
 FolkSinger(String name,String songTitle) {
 
  super(name,songTitle);
 }
 
 @Override 
 
 void print() {
  
  System.out.println("歌手为: " + super.name + " 代表作为: " + super.songTitle);
  
 }
}

class Singer {

 String name;//歌手名字
 String songTitle;  //歌曲名字
  
 Singer() {
 
 //构造方法用于初始化
 
  name = "民谣歌手,流行音乐歌手,嘻哈歌手";
  songTitle = "民谣歌曲,流行音乐,嘻哈音乐";

 }
 
 //定义参数为引用类型的构造方法

 Singer(Singer s) {
  name = s.name;
  songTitle = s.songTitle;
 }
 
 //定义构造方法,并且有参数
 
 Singer(String name,String songTitle) {
 
  this.name = name;
  this.songTitle = songTitle;

 }
  
 void print() {
 
  //输出
  
  System.out.println("歌手类型为: " +this.name + " 歌曲类型为: " + this.songTitle);
 
 
 }

}

代码执行后结果如下图所示

重写和重载

- 重写

在面向对象编程中,经常会听到重写重载两个词。这两个都是十分重要的概念,虽然两者的名字十分接近,但是实际上却相差的很远,并不是一个概念。

重写是建立在继承关系之上的,在子类中重新编写来自父类的方法以达到自己的需求的目的

那么在重写的时候,有一些规则需要遵守

  • 重写方法的访问权限应该与父类中的方法的访问权限相同或者可以进一步扩大,但是绝不能缩小
  • 表示为final的方法不能进行重写,静态的方法不能重写
  • 重写方法的返回值类型必须与被重写方法的返回值类型相同
  • 重写方法的参数列表必须与被重写方法的参数列表相同
  • 抽象方法必须在具体类中重写
  • 无论被重写方法是否抛出异常,重写的方法都可以抛出任何非强制异常,但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以成立

在编写Java程序的时候,有时候经常需要子类重写父类,新定义的类具有新的功能,下面给出一个实例文件,感受下重写的重要性

public class TestOverride {

 public static void main(String[] args) {
  SubClass s = new SubClass("计科1班",21,52,"广州市");
  s.print(); //调用子类的print()
 }
}

class SubClass extends SuperClass {

 String saddr; 
 SubClass(String name,int id,int number,String address) {
  
 super(name,id,number);
 saddr = address;
 
  
 }
 @Override
 void print() {
  System.out.println("codevald" + "所在的班级为" + sname + ",学号为" + sid + 
     ",总人数为" + snumber + " 学校所在地址为: " + saddr);
 }
}

class SuperClass {

 String sname; //名字
 int sid; //工号
 int snumber; //人数
  
 SuperClass(String sname,int sid,int snumber) {
 
  this.sname = sname;
  this.sid = sid;
  this.snumber = snumber;
 }
  
 void print() {
  System.out.println("组织名为: " + sname + " 工号为: " + sid + " 组织人数为:" + snumber);
 }

}

运行结果

但是,在编写重写方法的时候,要注意权限问题,如果把上面的子类中print()方法权限改写为private,编译时将会报错。

- 重载

在Java中,重载大大减少了程序猿的变成负担,开发者不需要记住那些复杂而难记的方法名称或者参数即可实现项目的开发需求。

那么,在Java的程序中,同一类中可以有两个或者多个方法具有相同的方法名,只要他们的参数不同即可,这就是方法重载。

重载的规则十分简单,参数决定重载方法的调用。当调用重载方法时,要确定调用哪个参数是基于其参数的。

来看下具体的实例,感受下重载的魅力。

public class TestOverload {

 public void test() {
  System.out.println("无参数的方法");
 }
 
 public void test(String message) {
  System.out.println("重载的test方法" + message);
 }

 public static void main(String[] args) {
   TestOverload o = new TestOverload();
   int i = 0;
   do {
    System.out.print(args[i]);
    i++;

   } while (i < args.length);
   System.out.println("");
   o.test();
   o.test("@CodeVald");
 
 }
}

上面分别定义了两个同名方法test(),但是其方法的形参列表不同,系统可以自动区分这两个方法,这两种类型的方法称为方法重载。

在上面的例子中,我编写了一段代码,利用do {} while ()语句输出了运行时自定义的字符串,在运行时在文件的后面假如自定义的字符串即可输出,其实这里是利用了main()函数后面的字符串数组args[],它可以检测输入的字符串并存储起来

来看下运行结果

重写和重载其实十分容易,我写了一段话来区分它们

重写发生在具有继承关系的类之间,而重载则是在同一个类中有多个同名的方法,主要通过参数来区别。[继承可重写,方法可重载]。

那么,在重写中还需要注意:

在重写了父类中的方法,按正常的办法子类对象是无法访问到父类中被覆盖的方法的,但是也是可以在子类中调用父类的被覆盖的方法。如果需要访问到被覆盖的方法,则可以适用super[被覆盖的是实例方法]或者父类名[被覆盖的是类方法]作为调用者来调用父类中被覆盖的方法。

如果父类方法具有私有访问权限,则该方法对其子类是隐藏的,其子类无法重写该方法。那么要是在子类中定义了一个与父类私有方法相同的名字,相同的形参列表,相同的返回值类型的方法,这时候并不是重写,只是重新定义了一个新方法。

封装

封装(encapsulation)是面向对象的特征之一,是指将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象的内部信息,通过该类对外所暴露的方法实现对内部信息的操作和访问。在Java中封装类或对象的目的如下所示:

  • 隐藏类的实现细节
  • 让调用者只能通过实现预定的方法访问数据,在访问代码中加入控制逻辑,限制对属性的不合理访问
  • 进行数据检查
  • 需求更改时,便于修改,提高代码的可维护性

使用封装特性时,访问控制符的知识也需要先了解一下

在Java中,提供了3个访问控制符,分别是private、protected、public,分别代表了3个访问控制级别,如果不适用,会使用默认的default,具体说明如下:

private: 如果类里的一个成员(包括属性和方法)使用private访问修饰符时,那么这个成员只能在类的内部被访问。所以,使用private修饰属性可以把属性隐藏在类的内部。

default:如果类里的一个成员(包括属性和方法)或者一个顶级类不适用任何访问控制符来修饰,则称它为默认访问控制,由default访问控制符修饰的成员或者顶级类可以被相同包下其他类访问。

protected 如果一个成员(包括属性和方法)使用protected访问控制符修饰,那么这个成员既可以被同一个包中的其他类访问,也可以被不同个包中的其他子类访问,通常情况下,如果使用protected修饰一个办法,那么通常是希望子类重写这个方法。

public 这是一个最宽松的访问控制级别,如果一个成员(包括属性和方法)或者一个顶级类使用了public来修饰,那么这个成员或者顶级类就可以被所有类访问,这时不管访问类和被访问类是否处于同一个包中,他们是否具有父子继承关系。

访问控制控制一个类的成员是否可以被其他类访问。对于局部变量来说,其作用域就是他所在的方法,不可能被其它类来访问,因此他们不能使用访问控制符来修饰

Java中的顶级类可以使用访问控制符来修饰,但是顶级类只能有两种访问控制级别,分别是public和default(默认的)。顶级类不能使用private和protected修饰。由于顶级类既不处于任何类的内部,也没有外部类的子类,因此private和protected访问控制符对顶级类没有意义。

来看个例子

public class Person {

 //定义类Person
 
 private String name; //定义私有属性变量
 private int age;
 
 public Person() {
  //定义没有参数的公有构造方法
 
 
 }

 public Person(String name,int age) {
  //定义有参数的公有构造方法
  
  this.name = name;
  this.age = age;
 
 
 }

 public void setName(String name) {
 
  //执行校验,要求用户名长度必须在1-10位之间
 
  if (name.length() > 10 || name.length() < 1) {
  
   System.out.println("您设置的人名不符合要求.");
   return;
  
  } else {
  
   this.name = name;
  
  }
  
 }
  
  
  public String getName() {
  
   //返回属性name
   return this.name;
  
  
  }
  
  
  public void setAge(int age) {
  
   //执行校验,要求用户年龄必须在0-100之间
   
   if (age > 100 || age < 0) {
   
    System.out.println("您设置的年龄不合法.");
   
   } else {
   
    this.age = age;
   
   }
  
  
  
  }
  
  
  public int getAge() {
  
   return this.age;
  
  }
  

 
}
 }
}

上面编写的类的name和age属性只能在类内才可以操作和访问,在Person类之外只能通过各自的对应的setter和getter方法来操作和访问。

编写测试代码如下

public class TestPerson {
 
 public static void main(String[] args) {
 
  Person p = new Person();
  
  //属性已被隐藏,所以下面的语句将出现编译错误
  
  //p.age = 100;
  
  //下面的语句编译时不会出现错位,但运行时会提示age属性不合法
  
  p.setAge(200);
 
  //如果想要获取属性,必须通过暴漏的getter方法去访问p的age属性
  //如果没有设置属性的值,int类型的成员变量默认初始化为0,String类型的成员变量默认初始化为Null
  
  System.out.println("未设置属性变量age时: " + p.getAge());
 
  p.setAge(50);
  
  System.out.println("成功设置属性变量age后: " + p.getAge());
 
  //同样要用setter()方法来设置p的name属性
  p.setName("codevald");
  System.out.println("成功设置属性变量 name 后:" + p.getName());
  

 }

}

执行结果为

那么,总结一下,在使用Java的访问控制符时,应该遵循以下原则:

  • 类里的绝大部分属性都应该使用private来修饰,除了静态变量(用static修饰的),才考虑用public来修饰,除此之外,有一些方法是辅助所在的该类的一些其他方法,这些方法被其他方法调用实现功能,也应该使用private修饰
  • 如果一个类是其他类的父类,该类所包含的大部分方法仅仅希望被其他子类重写,而不想被外界直接调用的话,最好使用protected修饰这些方法。还有一些作为父类的抽象类,有时候希望使用多态操作,那么父类的方法则必须用public修饰
  • 暴露出来给其他类自由调用的方法应该使用public修饰,因此,类的构造器应该用public修饰,暴露出来给其他类创建该类的对象。

接口

在Java语言中,接口是一种和类十分相似的东西,定义接口的方法和定义类的方法差不多,在接口里面也可以包含方法,在接口里可以派生新的类。

- 接口的定义

接口里的方法和抽象类中的方法一样,它的方法也是抽象的,所以接口是不能具体化成对象的,他只是规定应该怎么做,而不管具体怎么做。定义完接口,任何类都可以实现这个接口。而且类不支持多继承类,但是类可以实现多个接口,在Java中创建接口的语法如下

[public] interface <接口名> {

    常量;
    抽象方法;
}



  • 接口的修饰符只能是public,因为这样接口才能被任何包中的接口或者类访问
  • interface:Java中接口的关键字
  • 接口名: 规则在Java中和类名一样
  • 常量: 在接口中不能声明变量,因为i接口具备三个特性:公有(public)、静态(static)、常量(final)

那么,在接口里,是使用implement用于接口的继承的,这和类不一样,类的继承是使用extends的,只要一个类没有声明为final或者这个类是abstract就能继承。Java不支持多重继承,但是可以使用接口来实现,就用到了implements,使用implements可以实现多个接口,只需要用逗号分开来。接口的多继承语法如下:

class A extends B implements C,D,E {


}

- 接口里的方法

在接口里,所有的方法都是公有的,抽象的,因此在方法声明的时候,可以省略关键字public、abstract,来看个Demo,看下是不是这样子。


class TestJieKou {

 //测试类
 
 public static void main(String[] args) {
 
  JieKou1 jiekou = new JieKou1();
  
  jiekou.fun1();
  jiekou.fun2();
  jiekou.fun3();
  jiekou.fun4();
  jiekou.fun5();

 
 }

}


interface JieKou {
 //定义接口
 
 void fun1(); //在接口中定义方法fun1()
 
 public void fun2(); //在接口中定义方法fun2()
 
 abstract void fun3(); //在接口中定义方法fun3()
 
 public abstract void fun4(); //在接口中定义方法fun4()
 
 abstract public void fun5(); //在接口中定义方法fun5()



}


class JieKou1 implements JieKou {

 //继承接口JieKou
 
 public void fun1() {
 
  System.out.println("接口里第一种方法没有修饰符");
 
 }

 public void fun2() {
  
  System.out.println("接口里第二种方法有修饰符public"); 
 
 }
 
 public void fun3() {
  
  System.out.println("接口里第三种方法有修饰符abstract"); 
 
 }

 public void fun4() {
  
  System.out.println("接口里第四种方法有修饰符public、abstract"); 
 
 }


 public void fun5() {
  
  System.out.println("接口里第五种方法有修饰符abstract、public"); 
 
 }

}



编译运行程序后的结果

- 引用接口

在引用接口前需要先实现这个接口,在Java中实现接口的格式如下


<修饰符> class <类名> implements <接口名> {

  ...
  ...
  ...


}




下面这个Demo实现计算器的基本功能加减乘除

class JiekouShiXian {

 public static void main(String[] args) {
 
  Calculator cal = new Calculator();
  System.out.println("1200 + 1200 = " + cal.add(1200,1200));
  System.out.println("2400 - 1100 = " + cal.subtract(2400,1100));
  System.out.println("1100 * 1100 = " + cal.multiply(1100,1100));
  System.out.println("5200 / 2  = " + cal.divide(5200,2));
 
 }

}

interface Add {

 int add(int a,int b);

}

interface Subtract {

 int subtract(int a,int b);

}

interface Multiply {

 int multiply(int a,int b);

}

interface Divide {

 int divide(int a,int b);


}

class Calculator implements Add,Subtract,Multiply,Divide {

 public int add(int a,int b) {
  
  return a + b;
 
 }
 
 public int subtract(int a,int b) {
 
  return a - b;
 
 }
 
 public int multiply(int a,int b) {
 
  return a * b;
 
 }
 
 public int divide(int a,int b) {
 
  return a / b;
 
 }

}

运行结果

在上面的代码中,分别定义了四个接口,分别表示实现加、减、乘、除的功能,然后定义了一个类实现四个接口,重写四个接口的内置方法,并编写测试类测试功能

来看下运行结果

在编写程序的时候,用户可以建立接口类型的引用变量,接口的引用变量能够存储一个 指向对象的引用值,这个对象可以实现任何任何该接口类的实例,用户可以通过接口都熬用该对象的方法。下面的代码演示了使用引用接口的过程


class JiekouYinYong {

 public static void main(String[] args) {
 
  

  Calculator cal = new Calculator();
  
  Add add = cal;
  Subtract subtract = cal;
  Multiply multiply = cal;
  Divide divide = cal;
  
  //调用cal的方法
  System.out.println("1200 + 1200 = " + cal.add(1200,1200));
  System.out.println("2400 - 1100 = " + cal.subtract(2400,1100));
  System.out.println("1100 * 1100 = " + cal.multiply(1100,1100));
  System.out.println("5200 / 2  = " + cal.divide(5200,2));
  
  
  //调用接口Add中的add方法
  
  System.out.println("1200 + 1200 = " + add.add(1200,1200));

  //调用接口Subtract中的subtract方法

  System.out.println("2400 - 1100 = " + subtract.subtract(2400,1100));

  //调用接口Multiply中的multiply方法

  System.out.println("1100 * 1100 = " + multiply.multiply(1100,1100));

  //调用接口Divide中的divide方法

  System.out.println("5200 / 2 =  " + divide.divide(5200,2));

 
 }



}




interface Add {

 int add(int a,int b);

}

interface Subtract {

 int subtract(int a,int b);

}

interface Multiply {

 int multiply(int a,int b);


}

interface Divide {

 int divide(int a,int b);


}

class Calculator implements Add,Subtract,Multiply,Divide {

 public int add(int a,int b) {
  
  return a + b;
 
 }
 
 public int subtract(int a,int b) {
 
  return a - b;
 
 }
 
 public int multiply(int a,int b) {
 
  return a * b;
 
 }
 
 public int divide(int a,int b) {
 
  return a / b;
 
 }



}

- 接口间的继承

接口间是完全支持多继承的,这和类不一样,即一个接口可以有多个直接父接口。和类的继承相似,子接口扩展某个父接口,并获得父接口里定义的所有抽象方法、常量属性、内部类和枚举类定义。

通过个具体的例子来看下


public class JiCheng {
 
 public static void main(String[] args) {

  System.out.println(interfaceC.name_A);
  System.out.println(interfaceC.name_B);
  System.out.println(interfaceC.name_C);

 }


}



interface interfaceA {

 String name_A = "codevald";

 void printA();

}


interface interfaceB {

 String name_B = new String("codevald");
 
 void printB();

}

interface interfaceC extends interfaceA,interfaceB {

 String name_C = "code" + new String("vald");
 
 void printC();


}

在上面的代码中,接口interfaceC继承了interfaceA和interfaceB,所以interfaceC获得了他们的常量。

看下运行结果

- 接口的私有方法

  • 在Java7或者更早的版本中,在一个接口里只能定义常量或者抽象方法这两种元素,不能再接口中提供方法的实现。如果要提供抽象方法和非抽象方法(方法与实现)的组合,只能使用抽象类
  • 在Java8版本中,在接口里引入了默认方法和静态方法这两个新功能。所以,在Java8版本的接口中,可以定义的成员有常量、抽象方法、默认方法和静态方法
  • 在Java9版本中,一个接口可以定义的成员有常量、抽象方法、默认方法、静态方法、私有方法和私有静态方法

来看下我编写的在Java7、Java8、Java9中接口方法的用法

在7版本或者更早的版本的接口中可能只包含抽象方法,这些接口方法必须由实现接口的类来实现

先定义Interface7


public interface Interface7 {
 public abstract void method();
}

然后定义一个类实现接口


public class Class7 implements Interface7 {

 public void method() {
 
 
  System.out.println("Hello,I am codevald.");
 
 
 }

 public static void main(String[] args) {
 
  Interface7 instance = new Class7();
  instance.method();

 }

}

执行结果

在Java8版本中,在接口中除了可以定义公共抽象方法外,还可以包含公共静态方法和公共默认方法

定义一个接口



public interface Interface8 {

 public abstract void method1();
 public default void method2() {
 
  System.out.println("Hello,I am default method.");
 
 }
 
 public static void method3() {
  
  System.out.println("Hello,I am static method.");
 
 }

}

再定义一个类实现方法


public class Class8 implements Interface8 {

 @Override 
 
 public void method1() {
 
  System.out.println("public abstract method.");
 
 }


 public static void main(String[] args) {
 
 
  Interface8 instance = new Class8();
  instance.method1();
  instance.method2(); 
  Interface8.method3();

 
 }

}

看下运行结果

从Java9版本开始,就可以在接口中添加私有方法和私有静态方法了,这些私有方法可以提高代码的可重用性。方法之间需要共享代码,私有接口方法就允许这样做,但不能将私有方法暴露到它的实现类中。

先定义一个接口


public interface Interface9 {


 public abstract void method1();
 
 public default void method2() {
 
  method4();
  method5();
  
  System.out.println("Hello,I am default method.");

 }
 
 public static void method3() {
 
  method5();
  System.out.println("Hello,I am static method.");
 
 
 }
 
 
 private void method4() {
 
  System.out.println("Hello,I am private method.");
 
 
 }
 
 private static void method5() {
 
  System.out.println("Hello,I am private static method.");
 
 
 }


}

再定义一个类


public class Class9 implements Interface9 {

 public void method1() {
 
  System.out.println("Hello,I am abstract method.");
 
 }
 
 public static void main(String[] args) {
 
  Interface9 instance = new Class9();
  instance.method1();
  instance.method2();
  Interface9.method3();
 
 }


}

看下运行结果

-接口和抽象类的区别联系

相同之处

  • 接口和抽象类都不能实例化
  • 接口和抽象类都可以包含抽象方法,实现接口或者继承抽象类的子类都必须实现这些抽象方法

不同之处

  • 接口中不包含构造器,抽象类可以包含构造器。抽象类里的构造器并不能创建对象,而是让子类调用这些构造器完成属于抽象类的初始化

  • 接口里不能包含初始化块,但抽象类可以包含初始化块

  • 一个类最多只能有一个父类,包含抽象类,但一个类可以实现多个接口


写到这里就结束啦,这些虽然是很基础的东西,不过后面设计模式,包括实际的项目实操,很多都会用到这些很基础的东西,如果基础不牢,很容易就半途而废,"泰山不让土壤,故能成其大;河海不择细流,故能就其深.",一个想要走的更远的程序猿,更要注意平时底层基础的积累,这样子,遇到问题,才能不慌不忙的提出解决问题的方案。

如果觉得这篇文章不错的话,记得帮我@codevald点个赞哟,感谢您的支持!









原文转载:http://www.shaoqun.com/a/521236.html

跨境电商:https://www.ikjzd.com/

乐一番:https://www.ikjzd.com/w/1562

家得宝:https://www.ikjzd.com/w/1570


Java语言在面向对象方面的知识点复杂繁琐,但是几乎是每个小伙伴学习编程必须踩的坑,其实,面向对象的底层都是一些计算机底层知识的结合,所以,不注重基础的程序猿,一定不是一个可以走的远的程序猿。那么,今天,我们先逐一地深入了解继承、重载、接口和构造器的知识。在学习这篇文章之前,如果有小伙伴对new过程发生了什么很感兴趣的话,可以先用几分钟看完这篇文章。new的过程发生了什么?看完这一篇就懂了好了,正
海带宝:海带宝
photobucket:photobucket
口述:爱上小我9岁的男生好纠结:口述:爱上小我9岁的男生好纠结
俄罗斯新平台今秋或将对中国卖家开放 / PayPal在加拿大推行即时转账服务:俄罗斯新平台今秋或将对中国卖家开放 / PayPal在加拿大推行即时转账服务
蔺云峰:蔺云峰

AOF写入和AOF重写对redis的阻塞以及解决方案

AOF写入和AOF重写对redis的阻塞以及解决方案。

目录
  • AOF写入策略
  • AOF重写
  • 阻塞
  • 解决阻塞

AOF写入策略

由appendfsync参数控制:

可配置的值说明
always命令写入buf后调用系统调用fsync同步AOF文件,fsync完成后线程返回。
no命令写入buf后调用系统调用write操作,后续fsync同步操作由操作系统来完成,一般为30秒一次。
everysec命令写入buf后调用系统调用write操作,后续fsync同步操作专门线程每一秒调用一次。

everysec是always和no的折中,是性能和安全性的这种,是redis默认的配置,也是比较推荐的配置。

当使用everysec配置时,redis会使用后台子线程完成完成fsync同步。

AOF重写

AOF重写是由后台子线程完成,但是AOF会有大量的IO操作,最终会和AOF的fsync进行磁盘的竞争。

阻塞

虽然在everysec配置下aof的fsync是由子线程进行操作的,但是主线程会监控fsync的执行进度。

主线程在执行时候如果发现上一次的fsync操作还没有返回,那么主线程就会阻塞。

解决阻塞

  1. 减少IO竞争

    redis有一个配置:

    no-appendfsync-on-rewrite yes/no
    • 配置就是设置为yes时候,在aof重写期间会停止aof的fsync操作(io竞争没有了)。这种配置有一个潜在的风险:如果在aof重写期间redis宕机了,那么aof的数据便会丢失,可靠性下降
    • 配置就是设置为no时候,aof重写期间还是会执行fsync,这个时候就会产生IO竞争,有可能阻塞主线程。
  2. 使用ssd

    如果既需要性能,有需要可靠性。

    • 将配置设为no
    • 硬盘采用高速固态硬盘SSD








原文转载:http://www.shaoqun.com/a/521231.html

跨境电商:https://www.ikjzd.com/

打折网:https://www.ikjzd.com/w/74

netporter:https://www.ikjzd.com/w/2132


AOF写入和AOF重写对redis的阻塞以及解决方案。目录AOF写入策略AOF重写阻塞解决阻塞AOF写入策略由appendfsync参数控制:可配置的值说明always命令写入buf后调用系统调用fsync同步AOF文件,fsync完成后线程返回。no命令写入buf后调用系统调用write操作,后续fsync同步操作由操作系统来完成,一般为30秒一次。everysec命令写入buf后调用系统调用w
agora:agora
weebly:weebly
新手入门亚马逊必备知识点:新手入门亚马逊必备知识点
5招有效提高亚马逊产品的转化率和成交率!:5招有效提高亚马逊产品的转化率和成交率!
收到小红旗小卖家新账号如何申诉?成功解封邮件模板分享:收到小红旗小卖家新账号如何申诉?成功解封邮件模板分享

5连胜!62+17+16,WOW组合再度发威,火箭真要成为西部搅局者啊_比赛

原标题:5连胜!62+17+16,WOW组合再度发威,火箭真要成为西部搅局者啊

北京时间1月31日NBA常规赛火箭以126-112大胜鹈鹕,全场比赛火箭方面:伍德27分9篮板,奥拉迪波20分6篮板7助攻,沃尔15分2篮板9助攻,戈登14分,豪斯8分。鹈鹕方面:锡安26分7篮板4助攻,莺哥15分5篮板4助攻,布莱德索15分5助攻,鲍尔7分8篮板4助攻3抢断。

在今天的比赛之前火箭已经取得了一波4连胜,球队势头正佳。鹈鹕昨天虽然赢球,但是消耗很大,今天背靠背作战火箭还是要占据一定的优势。但是首节比赛鹈鹕展现出了自己良好的势头,他们很快的就取得了10分的优势,但是随着比赛的进行,火箭的"三巨头"开始逐渐的找回了状态。

在第二节比赛伍德单节砍下了16分5篮板,奥拉迪波同样单节贡献了16分,沃尔也拿下了7分,凭借着第二节火箭单节48-22的超强攻击波,火箭很快的完成了反超,在半场他们已经取得了18分的优势。这就是现在这支火箭所呈现出来的比赛方式。在比赛下半场火箭再没有给鹈鹕机会,最终轻松地拿下了这场比赛的胜利。

在今天的比赛之后火箭凭借着这波5连胜,距离西部的位置已经是近在咫尺。相信谁都没有想到没有哈登的火箭会打出如此出色的比赛,值得一提的是哈登离开之后,火箭的防守效率排在了联盟第一,在上一场比赛结束之后沃尔就公开暗讽哈登,当时火箭队中有不愿意效力的球员,如今不同了,他们每个人之间彼此互相信任,他们更加的团结,更像一个整体了。

凭借着最近超强的表现,球迷给火箭三巨头起了WOW的组合,沃尔、伍德和奥拉迪波的组合真的非常值得期待,沃尔和奥拉迪波风格有几分相似之处,他们的突破能力极强,再加上逐渐复出的外线投篮,他们的未来真得可期。还有本赛季的伍德真是火箭的一大发现,3年4000万,场均可以贡献24+10,他已经打出了全明星的水准。

如果火箭能够将这样的胜利延续下去,那么他们晋级季后赛也是指日可待。不得不说是哈登的离开让火箭这些球员放开了手脚,他们不再有任何顾虑,尤其是奥拉迪波和沃尔都是急需要证明自己的过气球星,他们需要这样的胜利来激励自己,引领球队,同样非常期待他们接下来的表现,火箭还没有死,他们也没有重建,而这一切只是新的开始。至于最终他们会达到怎样的位置,一切我们拭目以待吧!返回搜狐,查看更多

责任编辑:

原文转载:http://sport.shaoqun.com/a/389645.html

跨境电商:https://www.ikjzd.com/

usps国际快递查询:https://www.ikjzd.com/w/513

易趣:https://www.ikjzd.com/w/210


原标题:5连胜!62+17+16,WOW组合再度发威,火箭真要成为西部搅局者啊北京时间1月31日NBA常规赛火箭以126-112大胜鹈鹕,全场比赛火箭方面:伍德27分9篮板,奥拉迪波20分6篮板7助攻,沃尔15分2篮板9助攻,戈登14分,豪斯8分。鹈鹕方面:锡安26分7篮板4助攻,莺哥15分5篮板4助攻,布莱德索15分5助攻,鲍尔7分8篮板4助攻3抢断。在今天的比赛之前火箭已经取得了一波4连胜,球
tm商标:tm商标
imgur:imgur
口述:我撞破丈夫和弟媳的隐秘欢乐(4/4):口述:我撞破丈夫和弟媳的隐秘欢乐(4/4)
首发!深诺集团发布2018年全球电商行业"最全蓝皮书":首发!深诺集团发布2018年全球电商行业"最全蓝皮书"
刷屏的RCEP,蕴含哪些跨境电商行业机遇?:刷屏的RCEP,蕴含哪些跨境电商行业机遇?

我国胃食管反流患者超1亿!长期不愈会增加患癌风险,你可别大意

核心提示:"老李有十多年的饮酒史,近段时间总是觉得烧心,反酸, 有时一低头,嘴里就会冒酸水,去医院做了好几次检查,呼吸内科、耳鼻喉科、胸外科、骨外科……都找不到病因,症状也一直没得到缓解,老李很受折磨。 后来与

"老李有十多年的饮酒史,近段时间总是觉得烧心,反酸, 有时一低头,嘴里就会冒酸水,去医院做了好几次检查,呼吸内科、耳鼻喉科、胸外科、骨外科……都找不到病因,症状也一直没得到缓解,老李很受折磨。

后来与朋友无疑交谈,朋友也出现过类似情况,介绍他去某三甲医院检查,结果诊断是胃食管反流。

胃食管反流的发病情况

胃食管反流,目前我国的发病人数高达1.65亿,在这其中,又有1600多万患者,会发展成为更加严重的反流性食管炎。

反流性食管炎相比胃食管反流会更加严重,而且还伴随着食管狭窄、溃疡和消化道出血等多种并发症。所以,临床上如果患者的病情持续加重的话,平常的工作和生活将会受到很大的困扰。


胃食管反流易与其他疾病混淆

胃食管反流的主要症状是反酸和烧心,有的时候会误认为是呼吸系统和心血管方面的疾病。由于反流物的刺激,患者还会出现胸痛、气喘、喉咙痛以及咳嗽等多种症状。如果症状典型的话,患者往往能够直接到消化科去找医生治疗。

但有的时候患者会出现咳嗽、胸痛、哮喘、慢性咽炎等非典型的症状,患者本身也无法判断是哪种病情。有时候在医院各个科室里转了好多圈,也不能确定最终病因,导致错过最佳治疗时机。所以胃食管反流的患者,平时既要关注反流导致的典型症状,也要关注其延伸出来的其他症状。

胃食管反流的原因

正常情况下,我们吃饭之后,食物顺着食管进入胃部,它是由上往下去的。而胃食管反流,就是胃部和十二指肠里的食物、胃液等物质往上跑,而且还能顺着食管往上跑到咽喉部位甚至口腔里。

这种明显违反了地心引力的方式让人有点不解。我们都知道,胃和食管之间有一个部位叫贲门,贲门就像一个很特殊的阀门,食物往下走它不阻拦,食物一级胃液如果往上走的话,它就会屏蔽阻拦住。这就好比马路上的单行道,只能往下,不能往上。

而胃食管反流患者,就是这道阀门出现差错了。一旦失去了原有的正常功能,食物虽然可以继续往下走,但是胃里的胃酸也能够往上跑了。胃酸本来就是有腐蚀性的,只能呆在胃部,如果跑到食管甚至咽喉部位,人自然就感到反酸和烧心了。

长期不治会诱发癌症吗?

胃食管反流如果长期不治疗的话,诱发癌变的风险则会非常大。由于最初病变的部位就在贲门,所以发生癌变最大可能的地方也是贲门。

贲门癌在我国的发病率在逐渐上升,而在美国,贲门癌的发病率则提高了7倍之多。贲门癌并非单纯的胃癌,它处于食管和胃的中间,所以严格来说贲门癌是食管下段的腺癌。贲门癌的治疗不但需要全部切除胃部,手术创伤大,所以预后效果很差。

除了贲门癌之外,胃食管反流还会诱发食管癌。食管癌最常见的风险就是巴雷特食管现象。所谓巴雷特食管,指的是食管接触了太多的胃酸,导致食管黏膜细胞发生了变化。而胃食管反流如果长期不治疗,胃酸液体对食管的刺激也将是长期的。巴雷特食管跟胃部的肠化生现象类似,都是黏膜细胞的异性增生,接下来的阶段就是肿瘤和癌变的开始。

如何治疗胃食管反流?

目前针对胃食管反流的治疗,没有根治性的疗法,主要治疗的药物有两类。

一种是抑制胃酸分泌的药物,比如奥美拉唑和雷贝拉唑等,通过降低胃液的酸度,进而减少反流液体对食管的刺激。

另一种是促进食管蠕动的药物,比如潘立酮和莫沙必利等,这类药物增强了食管的蠕动性,使反流的胃液尽快回到胃里,从而降低对食管部位的刺激。


轻症患者单独用药就行,而重症患者需要联合用药治疗。如果是反复发作,发作时用药,好转后停药,这样可以有效减少服药量。

防范胃食管反流,生活习惯要调整

防范胃食管反流,首先每顿饭不能吃得太饱,不然会导致胃部压力增加,然后引起胃气上逆,从而出现反流,最理想的饱感应在7分-8分之间;其次要避免抽烟喝酒,抽烟会导致食管下段括约肌松弛,从而导致胃酸的反流,而喝酒则会导致食管清除酸性物质的能力下降。

除此之外还要避免肥胖,因为肥胖会增加腹部压力,更容易将胃部的食物和液体挤压上去。


再者,如果已经出现了胃食管反流,平时吃饭后不要立即躺卧,这样更容易引起反流。此外在睡觉的时候,尽量把头部垫高,这样食管处于高处,下段胃部反流的可能性就降低一些了。

参考资料:

[1]《胃食管反流会变脸!一亿人烧心、胸痛、腹痛都因它》.健康时报网.2019-2-22.


[2]《胃酸反流很常见,但它却让我父亲得了癌症》.果壳网.2019-5-29.

[3]《饭后反酸烧心?饮酒肥胖人群当心胃食管反流》.新京报.2020-1-19.

未经作者允许授权,禁止转载


原文转载:http://health.shaoqun.com/a/149001.html

跨境电商:https://www.ikjzd.com/

智赢:https://www.ikjzd.com/w/1511

zappos.com:https://www.ikjzd.com/w/330


核心提示:"老李有十多年的饮酒史,近段时间总是觉得烧心,反酸, 有时一低头,嘴里就会冒酸水,去医院做了好几次检查,呼吸内科、耳鼻喉科、胸外科、骨外科……都找不到病因,症状也一直没得到缓解,老李很受折磨。 后来与 "老李有十多年的饮酒史,近段时间总是觉得烧心,反酸,有时一低头,嘴里就会冒酸水,去医院做了好几次检查,呼吸内科、耳鼻喉科、胸外科、骨外科……都找不到病因,症状也一直没得到缓解,老
敦煌网站:敦煌网站
美菜:美菜
怎么设置亚马逊listing的关键词,挑关键词要遵循哪些原则?:怎么设置亚马逊listing的关键词,挑关键词要遵循哪些原则?
虚假QA、滥用变体...网一后关店潮来袭!:虚假QA、滥用变体...网一后关店潮来袭!
Terapeak:Terapeak

“啪啪”就像上刑场,全因这个恼人的盆腔炎

核心提示:盆腔炎是一种常见的疾病,指女性上生殖道结构的感染,分为急性和慢性,可累及子宫、输卵管和卵巢中的任意或所有部位,而且常常伴有临近盆腔器官受累。

很多女性因为反反复复的盆腔炎,每次啪啪啪都好像上刑场一样,心惊胆战、疼痛难受,最后只好偃旗息鼓。今天就来聊聊这个恼人的盆腔炎:

什么是盆腔炎?

盆腔炎是一种常见的疾病,指女性上生殖道结构的感染,分为急性和慢性,可累及子宫、输卵管和卵巢中的任意或所有部位,而且常常伴有临近盆腔器官受累。


造成盆腔炎性疾病的危险因素:

  1. 性行为是盆腔炎性疾病的主要危险因素。禁欲的女性没有患盆腔炎性疾病的风险,长期只有1个性伴侣的女性也很少发生,而有多个性伴侣的女性患病风险最高。

  2. 其他的重要危险因素包括年龄较小、既往衣原体感染、性伴侣有STI,以及既往盆腔炎史。坚持采用屏障避孕,也就是坚持好好带套,具有一定的保护作用,可以显著降低盆腔炎的风险。

  3. 发生盆腔炎,下腹部的疼痛常常是最主要的症状,在啪啪啪的时候加剧的疼痛,有时可能是盆腔炎的唯一症状。还有的女性会感觉到在月经期间,或月经刚结束时发作的疼痛。



什么症状下需要治疗?

性活跃年轻女性或有性传播感染风险者,出现盆腔或下腹疼痛,且检查显示有宫颈剧痛子宫压痛或附件牙痛等临床下诊断为盆腔炎,不管症状轻重都需要治疗!否则不治疗或延迟治疗会增加远期并发症风险。

最后强调:博览群鸡虽然听起来诱人,但是总有很多未知风险,平时生活中一定要注意预防和避免哦!


原文转载:http://health.shaoqun.com/a/148991.html

跨境电商:https://www.ikjzd.com/

moss:https://www.ikjzd.com/w/1653

芒果店长:https://www.ikjzd.com/w/1533


核心提示:盆腔炎是一种常见的疾病,指女性上生殖道结构的感染,分为急性和慢性,可累及子宫、输卵管和卵巢中的任意或所有部位,而且常常伴有临近盆腔器官受累。 很多女性因为反反复复的盆腔炎,每次啪啪啪都好像上刑场一样,心惊胆战、疼痛难受,最后只好偃旗息鼓。今天就来聊聊这个恼人的盆腔炎:什么是盆腔炎?盆腔炎是一种常见的疾病,指女性上生殖道结构的感染,分为急性和慢性,可累及子宫、输卵管和卵巢中的任意或所有部位
olive:olive
easybuy:easybuy
箱包品类数据解读:箱包品类数据解读
被罚1200多万美金!首例亚马逊虚假刷:被罚1200多万美金!首例亚马逊虚假刷
Amazon选品思路:Amazon选品思路

健康的男人,行事时间应该是多长?太长太短都不好

核心提示:夫妻生活不仅可以调节夫妻之间的感情,也可以借此来了解一个人的身体状况,而同房的频率对健康也有一定联系。

夫妻生活不仅是调理夫妻双方感情的润滑剂,通过夫妻生活的质量也可以了解一个人的身体状况,那么正常情况下夫妻之间同房的频率是多少,同房过多会对身体造成什么伤害呢?

正常的同房频率是多少

多数男人都很在意x生活持续时间,如果持久性太短就会认为自己身体不行会觉得没自信、难堪,其实这种衡量方式并不正确,如果背负着这样的观念很容易导致男性zao泄,一个健康的男人,夫妻生活持续的时间一般在三分钟以上,如果在这个过程当中有适当的停顿也可以延长s精时间,其时间可以长达十分钟到半个小时,也有一些还会超过这个时间。

而对于夫妻生活的频率,在不同年龄段的人群回答是不同的,没有固定的数值,从身体方面来考虑,应该以第二天不会出现明显疲劳腰酸乏力的现象为基础,不能影响正常的工作以及生活,可见,在不同的年龄段不同的性格不同工作性质的人身上频率是不同的。

正常而言,不到三十岁的年轻人每个星期在两次到四次,处于三十岁到四十岁的人群每个星期需要保障夫妻生活频率在两次,处于四十岁到五十岁的人群每个星期需要至少保障一次夫妻生活,五十岁以上的人群每三四周一次即可。

同房过多的危害可不少

1、影响体质

夫妻生活是一个耗时耗力的过程,会导致一个人的体力消耗太大,长时间下去自然会影响一个人的身体状况,会出现精神不济记忆力下降等症状。

2、性器官疲劳

因为性冲动的连续性发生,就会加重控制性活动的中枢神经,也会给x器官造成负担,x器官在重复性活动下去就会出现功能衰竭,可能会导致zao泄出现。

3、出现性功能障碍

经常性进行x生活会延长s精的时间,这样s精时间越来越长也就会埋下阳wei、s精时间迟缓的隐患,长时间下去还会影响夫妻生活的质量。

4、腰背劳损

同房时间太过频繁,x器官反复性充血会引发前列腺炎精囊炎的出现概率,长时间下去还会导致女性腰酸背痛以及血精的症状,而女子同房频率太高也会让x器官长时间处于充血的状态会诱发盆腔充血,出现下身沉重的现象。


5、频繁同房的表现

如果同房次数太多就会出现面容憔悴、身体消瘦、以及精神倦怠、萎靡不振、心跳气短以及失眠多梦的症状,一旦出现这些信号一定要调整自己的同房频率。

虽然说夫妻生活可以增加夫妻之间的感情,但是同房太频繁对健康是非常不利的,也会造成身体隐患,因此在生活中一定要注意控制欲望。


原文转载:http://health.shaoqun.com/a/148974.html

跨境电商:https://www.ikjzd.com/

出口易:https://www.ikjzd.com/w/1317

hunter:https://www.ikjzd.com/w/992


核心提示:夫妻生活不仅可以调节夫妻之间的感情,也可以借此来了解一个人的身体状况,而同房的频率对健康也有一定联系。 夫妻生活不仅是调理夫妻双方感情的润滑剂,通过夫妻生活的质量也可以了解一个人的身体状况,那么正常情况下夫妻之间同房的频率是多少,同房过多会对身体造成什么伤害呢?正常的同房频率是多少多数男人都很在意x生活持续时间,如果持久性太短就会认为自己身体不行会觉得没自信、难堪,其实这种衡量方式并不正
writer:writer
西集网:西集网
省钱!听说"亚马逊物流轻小商品计划"可以?:省钱!听说"亚马逊物流轻小商品计划"可以?
亚马逊海卖助手正式停用,功能强大的替代工具4KMILES来袭!:亚马逊海卖助手正式停用,功能强大的替代工具4KMILES来袭!
写给新卖家- 3.8女神节来临,跨境电商日本樱花爆款产品遍地盛开:写给新卖家- 3.8女神节来临,跨境电商日本樱花爆款产品遍地盛开

2021-01-30

作为一名合格的开发者,必须了解的编程原则有哪些?

目录

通用

  • KISS (Keep It Simple Stupid)

  • YAGNI

  • 做最简单的事情

  • 关注点分离

  • 保持事情不再重复

  • 为维护者写代码

  • 避免过早优化

  • 童子军军规

  • 2021Java面试宝典

模块间/类

  • 最小化耦合

  • 迪米特法则

  • 组合优于继承

  • 正交性

  • 稳健性原则

  • 控制反转

模块/类

  • 最大化聚合

  • 里氏代换原则

  • 开放/封闭原则

  • 单一职责原则

  • 隐藏实现细节

  • 科里定律

  • 封装经常修改的代码

  • 接口隔离原则

  • 命令查询分离

KISS

大多数系统如果保持简单而不是复杂,效果最好。

为什么

  • 更少的代码可以花更少的时间去写,Bug更少,并且更容易修改。

  • 简单是复杂的最高境界。

  • 完美境地,非冗杂,而不遗。

YAGNI

YAGNI的意思是"你不需要它":在必要之前不要做多余的事情。

为什么

  • 去做任何仅在未来需要的特性,意味着从当前迭代需要完成的功能中分出精力。

  • 它使代码膨胀;软件变得更大和更复杂。

怎么做

  • 在当你真正需要它们的时候,才实现它们,而不是在你预见到你需要它们的时候。

做最简单的事情

为什么

  • 仅有当我们只解决问题本身时,才能最大化地解决实际问题。

怎么做

  • 扪心自问:"最简单的事情是什么?"。

关注点分离

关注点分离是一种将计算机程序分离成不同部分的设计原则,以便每个部分专注于单个关注点。例如,应用程序的业务逻辑是一个关注点而用户界面是另一个关注点。更改用户界面不应要求更改业务逻辑,反之亦然。

引用Edsger W. Dijkstra (1974)所说:

我有时将其称为"关注点分离",即使这不可能完全做到,但它也是我所知道的唯一有效的思维整理技巧。这就是我所说的"将注意力集中在某个方面"的意思:这并不意味着忽略其他方面,只是对于从某一方面的视角公正地来看,另一方面是不相关的事情。

为什么

  • 简化软件应用程序的开发与维护。

  • 当关注点很好地分开时,各个部分可以被重用,并且可以独立开发和更新。

怎么做

  • 将程序功能分成联系部分尽可能少的模块。

保持事情不再重复

在一个系统内,每一项认识都必须有一个单一的、明确的、权威的表示。

程序中的每一项重要功能都应该只在源代码中的一个地方实现。相似的函数由不同的代码块执行的情况下,抽象出不同的部分,将它们组合为一个函数通常是有益的。

为什么

  • 重复(无意或有意的重复)会造成噩梦般的维护,保养不良和逻辑矛盾。

  • 对系统中任意单个元素的修改不需要改变其他逻辑上无关的元素。

  • 此外,相关逻辑的元素的变化都是可预测的和均匀的,因此是保持同步的。

怎么做

  • 只在一个处编写业务规则、长表达式、if语句、数学公式、元数据等。

  • 确定系统中使用的每一项认识的唯一来源,然后使用该源来生成该认识的适用实例(代码、文档、测试等)。

  • 使用三法则(Rule of three).

为维护者写代码

为什么

  • 到目前为止,维护是任何项目中最昂贵的阶段。

怎么做

  • _成为_维护者。

  • 不论何时编写代码,要想着最后维护代码的人是一个知道自己住在哪里的暴力精神病人。

  • 如果某个入门的人掌握了代码,他们就会从阅读和学习代码中获得乐趣,以这样的想法去编写代码和注释。

  • 别让我想(Don't make me think).

  • 使用最少惊讶原则(Principle of Least Astonishment).

避免过早优化

引用Donald Knuth所说:

程序员浪费大量的时间来思考或担心程序的非关键部分的速度,而考研尝试这些优化实际上在调试和维护时有很强的负面影响。比如说在97%的开发时间,我们应该忽略低效率:过早的优化是万恶之源。然而,我们不应该在关键的3%中放弃我们的机会。

当然,需要理解什么是"过早"什么不是"过早"。

为什么

  • 瓶颈在哪是未知的。

  • 优化后,阅读和维护可能会更困难。

怎么做

  • 使它运作,使它正确,使它更快(Make It Work Make It Right Make It Fast)

  • 不要在你不需要的时候优化,只有在你发现一个瓶颈之后才能优化它。

最小化耦合

模块/组件之间的耦合是它们互相依赖的程度,较低的耦合更好。换句话说,耦合是代码单元"B"在未知的代码单元"A"更改后"被破坏"的几率。

为什么

  • 一个模块的更改通常会导致其他模块的更改,产生涟漪效益。

  • 由于模块间的依赖性增加,模块装配可能需要更多的工作和/或时间。

  • 特定的模块可能难以重用和/或测试,因为必须包含相关模块。

  • 开发人员可能害怕更改代码,因为他们不确定什么会收到影响。

怎么做

  • 消除,最小化和降低必要关联的复杂性。

  • 通过隐藏实现细节,减少耦合。

  • 使用迪米特法则。

迪米特法则

不要和陌生人说话。

为什么

  • 这通常会导致更紧密的耦合。

  • 可能会暴露过多的实现细节。

怎么做

对象的方法只能调用以下方法:

  1. 对象自身的方法。

  2. 方法参数中的方法。

  3. 方法中创建的任何对象的方法。

  4. 对象的任何直接属性或字段的方法。

组合优于继承

为什么

  • 类之间的耦合减少。

  • 使用继承,子类很容易做出假设,并破坏里氏代换原则(LSP)。

怎么做

  • 测试LSP(可替换性)以决定何时继承。

  • 当存在"有"(或"使用")的关系时使用组合,当存在"是"的关系时使用继承。

正交性

正交性的基本概念是,概念上不相关的东西在系统中不应该相关。

来源:Be Orthogonal

它越简单,设计越正交,异常就越少。这使得用编程语言学习、读写程序变得更容易。正交特征的含义是独立于环境;关键参数是对称性与一致性。

来源:Orthogonality

稳健性原则

坚持保守自己的作为,自由接受他人的作为。

合作的服务依赖于彼此的接口。通常,接口需要提升,导致另一端接收未指定的数据。如果接收到的数据没有严格遵守规范,那么简单的实现将仅拒绝合作。更复杂的实现却可以忽略它无法识别的数据。

为什么

  • 为了能够提高服务,你需要确保提供者可以进行更改以支持新的需求,同时对现有客户端造成最小的破坏。

怎么做

  • 向其他机器(或同一机器上的其他程序)发送指令或数据的代码应该完全符合规范,但接受输入的代码应接受不一致的输入,只要其意义明确。

控制反转

控制反转又被称为好莱坞原则,"不要打电话给我们,我们会打电话给你"。它是一种设计原则,计算机程序的自定义编写部分从通用框架接收控制流。控制反转具有强烈的含义,即可重用代码和特定于问题的代码是独立开发的,即使它们在应用程序中一同工作。

为什么

  • 控制反转用于提高程序的模块性,使其具有可扩展性。

  • 将任务的执行与实现分离。

  • 将模块集中在其设计任务上。

  • 使模块不受关于其他系统如何执行其任务的假设约束,而是依赖于约定。

  • 以防止模块更换时出现副作用。

怎么做

  • 使用工厂模式

  • 使用服务定位器模式

  • 使用依赖注入

  • 使用依赖查找

  • 使用模板方法模式

  • 使用策略模式

最大化聚合

单个模块/组件的聚合性是其职责形成有意义的单元的程度,越高的聚合性越好。

为什么

  • 增加了理解模块的难度。

  • 增加了维护系统的难度,因为域中逻辑的更改会影响多个模块,并且一个模块的更改需要相关模块的更改。

  • 由于大多数应用程序不需要模块提供的随机操作集,因此重用模块的难度增加。

怎么做

  • 与组相关的功能共享一项职责(例如在一个类中)。

里氏代换原则

里氏代换原则(LSP)完全是关于对象的预期行为:

程序中的对象应该可以替换为其子类型的实例,而不会改变该程序的正确性。

开放/封闭原则

软件实体(例如类)应对扩展是开放的,但对修改是封闭的。也就是说,这样的实体可以允许在不改变其源代码的情况下修改其行为。

为什么

  • 通过最小化对现有代码的修改来提高可维护性和稳定性

怎么做

  • 编写可以扩展的类(而不是可以修改的类)

  • 只暴露需要更换的活动部分,隐藏其他所有部分。

单一职责原则

一个类不应该有多个修改的原因。

长话版:每个类都应该有一个单独的职责,并且该职责应该完全由该类封装。职责可以定义为修改的原因,一次类或模块应该有且仅有一个修改的原因。

为什么

  • 可维护性:仅有一个模块或类中需要修改。

怎么做

  • 使用 科里定律.

隐藏实现细节

软件模块通过提供接口来隐藏信息(即实现细节),而不泄露任何不必要的信息。

为什么

  • 当实现更改时,客户端使用的接口不必更改。

怎么做

  • 最小化类和成员的可访问性。

  • 不要公开成员数据。

  • 避免将私有实现细节放入类的接口中。

  • 减少耦合以隐藏更多实现细节。

科里定律

科里定律是关于为任何特定代码选择一个明确定义的目标:仅做一件事。

  • Curly's Law: Do One Thing

  • The Rule of One or Curly's Law

封装经常修改的代码

一个好的设计可以辨别出最有可能改变的热点,并将它们封装在API之后。当预期的修改发生时,修改会保持在局部。

为什么

  • 在发生更改时,最小化所需的修改。

怎么做

  • 封装API背后不同的概念。

  • 将可能不同的概念分到各自的模块。

接口隔离原则

将臃肿的接口减少到多个更小更具体的客户端特定接口中。接口应该比实现它的代码更依赖于调用它的代码。

为什么

  • 如果类实现了不需要的方法,则调用方需要了解该类的方法实现。例如,如果一个类实现了一个方法,但只是简单的抛出异常,那么调用方将需要知道实际上不应该调用这个方法。

怎么做

  • 避免臃肿的接口。类不应该实现任何违反单一职责原则的方法。

童子军军规

美国童子军有一条简单的军规,我们可以使用到我们的职业中:"离开营地时比你到达时更干净"。根据童子军军规,我们应该至终保持代码比我们看到时更干净。

为什么

  • 当对现有代码库进行更改时,代码质量往往会降低,从而积累技术债务。根据童子军军规,我们应该注意每一个提交(Commit)的质量。无论规模有多小,技术债务都会受到不断重构的抵制。

怎么做

  • 每次提交都要确保它不会降低代码库的质量。

  • 任何时候,如果有人看到一些代码不够清楚,他们就应该抓住机会在那里修复它。

命令查询分离

命令查询分离原则规定,每个方法都应该是执行操作的命令,或者是向调用者返回数据但不能同时做两件事的查询。提问不应该改变答案。

利用这个原则,程序员可以更加自信地进行编码。查询方法可以在任何地方以任何顺序使用,因为它们不会改变状态。而使用命令,你必须更加小心。

为什么

  • 通过将方法清晰地分为查询和命令,程序员可以在不了解每个方法的实现细节的情况下,更加自信地编码。

怎么做

  • 将每个方法实现为查询或命令。2021Java面试宝典

  • 对方法名使用命名约定,该方法名表示该方法是查询还是命令。












原文转载:http://www.shaoqun.com/a/521207.html

跨境电商:https://www.ikjzd.com/

跨境通网站:https://www.ikjzd.com/w/1329

识货:https://www.ikjzd.com/w/1745


目录通用KISS(KeepItSimpleStupid)YAGNI做最简单的事情关注点分离保持事情不再重复为维护者写代码避免过早优化童子军军规2021Java面试宝典模块间/类最小化耦合迪米特法则组合优于继承正交性稳健性原则控制反转模块/类最大化聚合里氏代换原则开放/封闭原则单一职责原则隐藏实现细节科里定律封装经常修改的代码接口隔离原则命令查询分离KISS大多数系统如果保持简单而不是复杂,效果最好
深诺互动:深诺互动
modcloth:modcloth
旺季物流:意大利稳了,欧洲4国运费有调整! :旺季物流:意大利稳了,欧洲4国运费有调整!
销量猛涨3倍,屠榜品类TOP?卖家私藏亚马逊日本站时尚品类爆单秘诀!:销量猛涨3倍,屠榜品类TOP?卖家私藏亚马逊日本站时尚品类爆单秘诀!
国务院:关于印发6个新设自由贸易试验区总体方案的通知:国务院:关于印发6个新设自由贸易试验区总体方案的通知

ConcurrentHashMap详解

原文链 id="concurrenthashmap详解">ConcurrentHashMap详解

JDK7

Segment

在jdk8之前concurrentHashMap使用该对象进行分段加锁,降低了锁的粒度,使得并发效率提高,Segment本身也相当于一个HashMap,Segment包含一个HashEntry数组,数组中每个HashEntry既是一个键值对,又是一个链表的头结点

get方法

  • 根据key做hash运算,得到hash值
  • 通过hash值,定位到对应的segment对象
  • 再次通过hash值,定位到segment当中数组的具体位置

put方法

  • 根据key做hash运算,得到hash值
  • 通过hash值,定位到对应的segment对象
  • 获取可重入锁
  • 再次通过hash值,定位到segment当中数组的具体位置
  • 插入或覆盖hashEntry对象
  • 释放锁

但是使用这种方式实现需要进行两次hash操作,第一次hash操作找到对应的segment,第二次hash操作定位到元素所在链表的头部

JDK8

在jdk8的时候参考了HashMap的设计,采用了数组+链表+红黑树的方式,内部大量采用CAS操作,舍弃了分段锁的思想

CAS

CAS是compare and swap的缩写,即我们所说的比较交换,CAS属于乐观锁。

CAS包含三个操作数,---内存中的值(V),预期原值(A),新值(B) 如果内存中的值和A的值一样,就可以将内存中的值更新为B。CAS通过无限循环来获取数据,一直到V和A一致为止

乐观锁

乐观锁会很乐观的认为不会出现并发问题,所以采用无锁的机制来进行处理,比如通过给记录加version来获取数据,性能比悲观锁要高

悲观锁

悲观锁会很悲观的认为肯定会出现并发问题,所以会将资源锁住,该资源只能有一个线程进行操作,只有前一个获得锁的线程释放锁之后,下一个线程才可以访问

源码分析

重要变量
// 表示整个hash表,初始化阶段是在第一次插入的时候,容量总是2的次幂transient volatile Node<K,V>[] table;// 下一个使用的表 只有在扩容的时候非空,其他情况都是nullprivate transient volatile Node<K,V>[] nextTable;/** * Base counter value, used mainly when there is no contention, * but also as a fallback during table initialization * races. Updated via CAS. */private transient volatile long baseCount;// 用于初始化和扩容控制// 0:默认值// -1:正在初始化// 大于0:为hash表的阈值// 小于-1:有多个线程在进行扩容 该值为 -(1+正在扩容的线程数)private transient volatile int sizeCtl;/** * The next table index (plus one) to split while resizing. */private transient volatile int transferIndex;/** * Spinlock (locked via CAS) used when resizing and/or creating CounterCells. */private transient volatile int cellsBusy;/** * Table of counter cells. When non-null, size is a power of 2. */private transient volatile CounterCell[] counterCells;// viewsprivate transient KeySetView<K,V> keySet;private transient ValuesView<K,V> values;private transient EntrySetView<K,V> entrySet;
构造函数
/** * Creates a new, empty map with the default initial table size (16). */public ConcurrentHashMap() {}/** * Creates a new, empty map with an initial table size * accommodating the specified number of elements without the need * to dynamically resize. * * @param initialCapacity The implementation performs internal * sizing to accommodate this many elements. * @throws IllegalArgumentException if the initial capacity of * elements is negative */public ConcurrentHashMap(int initialCapacity) { if (initialCapacity < 0)  throw new IllegalArgumentException(); int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ?    MAXIMUM_CAPACITY :    tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1)); this.sizeCtl = cap;}/** * Creates a new map with the same mappings as the given map. * * @param m the map */public ConcurrentHashMap(Map<? extends K, ? extends V> m) { this.sizeCtl = DEFAULT_CAPACITY; putAll(m);}/** * Creates a new, empty map with an initial table size based on * the given number of elements ({@code initialCapacity}) and * initial table density ({@code loadFactor}). * * @param initialCapacity the initial capacity. The implementation * performs internal sizing to accommodate this many elements, * given the specified load factor. * @param loadFactor the load factor (table density) for * establishing the initial table size * @throws IllegalArgumentException if the initial capacity of * elements is negative or the load factor is nonpositive * * @since 1.6 */public ConcurrentHashMap(int initialCapacity, float loadFactor) { this(initialCapacity, loadFactor, 1);}/** * Creates a new, empty map with an initial table size based on * the given number of elements ({@code initialCapacity}), table * density ({@code loadFactor}), and number of concurrently * updating threads ({@code concurrencyLevel}). * * @param initialCapacity the initial capacity. The implementation * performs internal sizing to accommodate this many elements, * given the specified load factor. * @param loadFactor the load factor (table density) for * establishing the initial table size * @param concurrencyLevel the estimated number of concurrently * updating threads. The implementation may use this value as * a sizing hint. * @throws IllegalArgumentException if the initial capacity is * negative or the load factor or concurrencyLevel are * nonpositive */public ConcurrentHashMap(int initialCapacity,       float loadFactor, int concurrencyLevel) { if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0)  throw new IllegalArgumentException(); if (initialCapacity < concurrencyLevel) // Use at least as many bins  initialCapacity = concurrencyLevel; // as estimated threads long size = (long)(1.0 + (long)initialCapacity / loadFactor); int cap = (size >= (long)MAXIMUM_CAPACITY) ?  MAXIMUM_CAPACITY : tableSizeFor((int)size); this.sizeCtl = cap;}
重要方法
put方法

ConcurrentHashMap是如何保证在插入的时候线程安全的呢

public V put(K key, V value) { return putVal(key, value, false);}
final V putVal(K key, V value, boolean onlyIfAbsent) { 	// ConcurrentHashMap不允许key和value为null if (key == null || value == null) throw new NullPointerException(); 	// 计算hash值 int hash = spread(key.hashCode()); int binCount = 0; for (Node<K,V>[] tab = table;;) {  Node<K,V> f; int n, i, fh;  	// tab为null,哈希表还没有初始化,进行初始化哈希表  if (tab == null || (n = tab.length) == 0)   tab = initTable();  	// 该索引位置为null,表示还没有元素  else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {   	// 使用CAS的方式添加节点   if (casTabAt(tab, i, null,       new Node<K,V>(hash, key, value, null)))    break;     // no lock when adding to empty bin  }  	// 节点的hash值为-1,表示该哈希表正在扩容  else if ((fh = f.hash) == MOVED)   tab = helpTransfer(tab, f);  else {   V oldVal = null;   	// 对头节点加锁   synchronized (f) {    	// 再次判断一下该节点是否为目标索引位置的头节点,防止期间被修改    if (tabAt(tab, i) == f) {     	// 表示是普通的链表     if (fh >= 0) {      binCount = 1;      for (Node<K,V> e = f;; ++binCount) {       K ek;       if (e.hash == hash &&        ((ek = e.key) == key ||         (ek != null && key.equals(ek)))) {        oldVal = e.val;        if (!onlyIfAbsent)         e.val = value;        break;       }       Node<K,V> pred = e;       if ((e = e.next) == null) {        pred.next = new Node<K,V>(hash, key,               value, null);        break;       }      }     }     	// 红黑树 TreeBin的hash值为TREEBIN,是-2     else if (f instanceof TreeBin) {      Node<K,V> p;      binCount = 2;      if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,              value)) != null) {       oldVal = p.val;       if (!onlyIfAbsent)        p.val = value;      }     }    }   }   	// 可以看一下上述的赋值流程   	// 默认初始值是0   	// 链表时为1 在遍历时进行累加,直到找到所要添加的位置为止   	// 红黑树时为2   if (binCount != 0) {    	// 链表的长度是否达到8 达到8转为红黑树    if (binCount >= TREEIFY_THRESHOLD)     treeifyBin(tab, i);    	// oldVal不为null,表示只是对key的值进行的修改,没有添加元素,直接返回即可    if (oldVal != null)     return oldVal;    break;   }  } } 	//  addCount(1L, binCount); return null;}

哈希函数根据hashCode计算出哈希值,这里的hash值与HashMap的计算方式稍微有点不同,在低十六位异或高十六位之后还需要与HASH_BITS在进行与运算,HASH_BITS的值是0x7fffffff,转为二进制是31个1,进行与运算是为了保证得到的hash值为正数。

ConcurrentHashMap中hash值为负数包含有其他含义,-1表示为ForwardingNode节点,-2表示为TreeBin节点

static final int spread(int h) { 	// (h ^ (h >>> 16)与hashMap相同 	// HASH_BITS进行与运算 return (h ^ (h >>> 16)) & HASH_BITS;}

初始化hash表的操作

private final Node<K,V>[] initTable() { Node<K,V>[] tab; int sc; 	// hash表为null时才需要进行初始化 while ((tab = table) == null || tab.length == 0) {  	// sizeCtl小于0表示有其他线程在进行初始化操作了  if ((sc = sizeCtl) < 0)   Thread.yield(); // lost initialization race; just spin  	// 将SIZECTL设为-1,表示该线程要开始初始化表了  else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {   try {    if ((tab = table) == null || tab.length == 0) {     int n = (sc > 0) ? sc : DEFAULT_CAPACITY;     @SuppressWarnings("unchecked")     Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];     table = tab = nt;     	// n右移两位 表示1/4n n-1/4n为3/4n 即为n*0.75     sc = n - (n >>> 2);    }   } finally {    sizeCtl = sc;   }   break;  } } return tab;}
private final void addCount(long x, int check) { CounterCell[] as; long b, s; if ((as = counterCells) != null ||  !U.compareAndSwapLong(this, BASECOUNT, b = baseCount, s = b + x)) {  CounterCell a; long v; int m;  boolean uncontended = true;  if (as == null || (m = as.length - 1) < 0 ||   (a = as[ThreadLocalRandom.getProbe() & m]) == null ||   !(uncontended =    U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))) {   fullAddCount(x, uncontended);   return;  }  if (check <= 1)   return;  s = sumCount(); } if (check >= 0) {  Node<K,V>[] tab, nt; int n, sc;  while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&    (n = tab.length) < MAXIMUM_CAPACITY) {   int rs = resizeStamp(n);   if (sc < 0) {    if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||     sc == rs + MAX_RESIZERS || (nt = nextTable) == null ||     transferIndex <= 0)     break;    if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1))     transfer(tab, nt);   }   else if (U.compareAndSwapInt(this, SIZECTL, sc,           (rs << RESIZE_STAMP_SHIFT) + 2))    transfer(tab, null);   s = sumCount();  } }}

由于本身的博客百度没有收录,博客地 />






原文转载:http://www.shaoqun.com/a/521203.html

跨境电商:https://www.ikjzd.com/

grab:https://www.ikjzd.com/w/841

extra:https://www.ikjzd.com/w/1736


原文链id="concurrenthashmap详解">ConcurrentHashMap详解JDK7Segment在jdk8之前concurrentHashMap使用该对象进行分段加锁,降低了锁的粒度,使得并发效率提高,Segment本身也相当于一个HashMap,Segment包含一个HashEntry数组,数组中每个HashEntry既是一个键值对,又是一个链表的头
淘粉吧怎么返利:淘粉吧怎么返利
斑马物联网:斑马物联网
腾邦:腾邦
美国最新法律:各州及地方政府可对互联网零售商强征销售税!:美国最新法律:各州及地方政府可对互联网零售商强征销售税!
又一爆款陨落!房子烧了, 亚马逊召回50万件产品, 卖家面临被起诉!:又一爆款陨落!房子烧了, 亚马逊召回50万件产品, 卖家面临被起诉!

东部大混战!篮网升至第二名,雄鹿遭爆冷,奇才4连败+内部动荡_尼克斯

原标题:东部大混战!篮网升至第二名,雄鹿遭爆冷,奇才4连败+内部动荡

1月30日进行的NBA常规赛非常精彩,有多达11支东部球队出战,其中包括了篮网击败雷霆豪取4雄鹿,雄鹿爆冷不敌鹈鹕,黄蜂险胜步行者,老鹰大胜奇才,尼克斯击败骑士,魔术惨败给快船等等。接下来我们来看看东部最新排名:

篮网豪取4连胜,升至东部第二名;

今天篮网在缺少杜兰特的情况下大胜雷霆,从而拿下了一波4连胜,反超雄鹿升至东部第二名。哈登再度砍下三双的数据,他在篮网队内的作用非常明显,球队在前场可以通过他的得分和传球打开局面, 今天的比赛就非常明显。这也是"欧哈组合"第一次带队赢球,篮网逐渐走向了正轨,球队这一波4连胜也让他们升到了第二名,期待接下来他们的表现。

雄鹿遭爆冷,无缘3连胜;

今天雄鹿在新奥尔良没有了状态,他们在上半场一度落后对手29分,下半场疯狂反扑,可惜末节关键时刻霍乐迪走步,同时球队关键球也没有投进,这样遗憾的输给了西部倒数第二名的鹈鹕,爆出冷门。这样无缘3连胜的雄鹿排名也被篮网反超,下降一位。

尼克斯和骑士稳居前八;

尼克斯和骑士是东部的搅局者,今天两队直接对话,最终尼克斯大胜,也稳定住了自己东部前八的位置。这两支球队都有自己的特点,骑士是在塞克斯顿的带领下还有德拉蒙德和小南斯等一众高个子球员,尼克斯队内则是有托平和巴雷特这样的天才球员,他们如果持续高光表现的话,是很有机会搅翻东部格局的。

猛龙热火连败;

作为本赛季东部强队中的难兄难弟,猛龙近期3连败,热火5连败,他们的表现很糟糕,虽然队内都有实力超强的球员,但本赛季截止到目前位置的发挥不尽如人意。这两支强队是需要一个爆点来刺激下自己的,也期待他们的反弹。

奇才4连败垫底+内部动荡;

奇才今天又输球了,他们面对老鹰末节没有能够完成逆转,吃到了4连败。球队位居东部倒数第一,同时队内的比尔还传出了想要离开的传闻,这样的情况下奇才想要强势反弹,难度确实很大。

返回搜狐,查看更多

责任编辑:

原文转载:http://sport.shaoqun.com/a/389630.html

跨境电商:https://www.ikjzd.com/

shopyy:https://www.ikjzd.com/w/1661

easel:https://www.ikjzd.com/w/1721


原标题:东部大混战!篮网升至第二名,雄鹿遭爆冷,奇才4连败+内部动荡1月30日进行的NBA常规赛非常精彩,有多达11支东部球队出战,其中包括了篮网击败雷霆豪取4雄鹿,雄鹿爆冷不敌鹈鹕,黄蜂险胜步行者,老鹰大胜奇才,尼克斯击败骑士,魔术惨败给快船等等。接下来我们来看看东部最新排名:篮网豪取4连胜,升至东部第二名;今天篮网在缺少杜兰特的情况下大胜雷霆,从而拿下了一波4连胜,反超雄鹿升至东部第二名。哈登
c88:c88
c2c模式:c2c模式
不懂A9算法的亚马逊跨境电商运营,等于白做:不懂A9算法的亚马逊跨境电商运营,等于白做
怎样才能提高Facebook广告转化率?:怎样才能提高Facebook广告转化率?
口述:情夫和老公串通好 故意冷淡我:口述:情夫和老公串通好 故意冷淡我

亚马逊要推FBA新计划,卖家拍手叫好

亚马逊或推出新的FBA计划,目前已经在征求意见,卖家纷纷拍手叫好。此外,亚马逊欧洲站费用减免,也将于3月1日生效。

 

亚马逊考虑推出新的FBA退货计划

 

近日,一位卖家称收到了亚马逊团队发来的邮件,很高兴亚马逊的新计划能实现。

 

亚马逊在邮件里提到:我们想确定你是否对两个潜在计划感兴趣?这两个计划是改善FBA客户退货流程的。我们将于2021年2月3日之前进行问卷调查。

 

QQ截图20210129185607.png

 

亚马逊的两种计划方案为:

 

1、不可售退货:卖家只会收到无法单件出售的退货,可继续出售的退货将返回您的可出售库存;

2、全部退货:卖家将收到所有客户退回的单个产品。亚马逊不会为卖家已加入的产品评分。相反,它们将被归为次品。无论是由谁损坏的,已损坏的产品不符合退款资格。

 

在这两种方案中,卖家都将在客户发起退货后30天或更短的时间内收到退货,顾客将照常得到退款。

 

收到邮件的卖家纷纷表示,对于FBA卖家来说,这两种选择都是一个胜利!天哪,请这样做!

 

有卖家称,觉得这个计划可以,希望我的大部分退货都是未开封的,此前退回的"有缺陷的"产品要花几个月才能送回,而且有时候还无法到自己手里。我希望退货能全部寄回,以便我根据需要检查和重新包装。

 

看起来,亚马逊终于听取卖家关于物流退货政策的心声了。因为其在号召卖家填写调查报告。这就是往前迈的较大一步了!

 

但是,仍有部分卖家对此提出了质疑。他们认为无论损坏者是谁,都将无资格获得退款,这条是很容易被滥用的。一位卖家表示,我一直希望所有退货退回,因为想对自己产品质量负责。但是"坏顾客"知道他们退还FBA 的产品,可以退回旧产品保留新产品,他们依旧可以钻政策的空子,尽可能多地使用产品,而卖家无权追索。如果是这样的话,是否有退货退钱的条件?除非卖家遇到很诚实的购买者。

 

有卖家直言:亚马逊物流总是让人感到困惑,也许亚马逊想强迫卖家使用FBM?我已经有一段时间没有做FBA了。

 

其实无论是什么样的计划,都不可能符合所有卖家的心愿。所以总会被部分人吐槽。但是相较之前亚马逊的退货政策,新的计划已经相对友好了。

 

疫情期间网购比例大幅上升,退货数量也随之上升。统计显示,美国在线购物的退货率约为30%,2020年美国消费者退回了价值约2.8万亿元的商品,约占美国当年零售总额的10.6%。其中方便的退货方式,和一些电商平台退款不退货的政策助长了退货的增长,退货背后是一些卖家为此买单。

 

另外,亚马逊近期也发了另外两条新政,会对部分卖家有一些影响。

 

亚马逊欧洲站费用减免,3月1日生效

 

此前,亚马逊已经宣布将年费调整时间推迟到2021年6月1日,昨天亚马逊再次公告表示,将降低客户退货处理费,延长对服装、鞋子和手袋的推荐费促销,退货手续费变更将于2021年3月1日生效。

 

在公告中,亚马逊表示会扩大广受欢迎的FBA新选品计划(FBA New Selection programme)新选品计划为新ASIN提供了免费的每月存储和移除服务,适用于英国、德国、法国、意大利和西班牙的亚马逊店铺,新的变更将于2021年4月1日生效,有需要的卖家可重点关注。

 

2.jpg

 

欧洲站之外,美国站物流政策也有更新。

 

美亚重要提示:这些一件代发方式被禁

 

本周,亚马逊更新了一件代发政策。在这则"重要提示"中,亚马逊强调,如果卖家通过第三方来完成订单(即一件代发),则必须遵守所有相关政策,任何违反其一件代发政策的行为都会影响账户健康状况,并对卖家今后履行订单造成不良影响。

 

亚马逊上严格禁止以下一件代发方式:

 

——卖家可能不直接购买产品而是从其他零售商处提供送货服务,如货件未将其识别为记录卖方,装箱单、发票或外包装上出现除卖家以外的其他人等;

 

——卖家不得配送显示除自身信息外的装箱单、发票、外包装及其他可指示卖家名称和联系方式信息的订单。这就意味着来自其他零售商的名称、logo或任何其他标识信息不能出现在客户收到的内容上。

 

如果要使用一件代发配送,卖家必须遵守这些要求:必须始终是产品记录的卖方,即卖家在商品随附的所有信息中都将自己标识为产品的卖方;在配送之前,删除所有标识第三方代发者的信息;负责接受和处理客户退货。

 

对于亚马逊这番"语重心长",卖家并不买账。

 

一位卖家表示:"这份'更新'中没有新内容。它说的是与现行政策完全相同的东西,只不过是以一种更加清晰和直接的方式。实际上,我梦想着有一天亚马逊要求所有的货运标签都使用Amazon Buy Shipping,这会有效遏制在线套利的一件代发者。"多位卖家对此表示赞同。

 

也有卖家就亚马逊的几点要求做了更接地气的翻译,即:禁止Walmart、Costco、Target、Lowes、Home Depot和Chewy等的包装盒,禁止eBay的磁带,禁止使用看起来像是一件代发的重复利用的箱子。但这并不容易,一位卖家表示,其收到过来自沃尔玛、好市多等的货品,并在feedback中进行反馈,结果是反馈被删除了,而那些卖家仍能继续售卖。

 

美国偷包裹太猖獗,卖家无奈承受损失

 

疫情之下,美国线上销售迎来了大幅增长。Digital Commence 360预估,2020年美国网购销售额可能同比飙升40.3%,达到8390亿美元。

 

根据新浪科技的报道,网购增加之际,美国包裹失窃问题日益猖獗。纽约州私立大学Rensselaer Polytechnic Institute的调查估计,2019年美国每天都有170万个包裹被偷或丢失或寄错,直接财务损失和劳务成本超过2500万美元,单是纽约市每天就有9万个包裹丢失。

 

疫情期间越多人失去工作,偷包裹可能是改善经济的一种途径。从区域上来看加州成偷包裹重灾区。此外,趁暴乱抢包裹、入室抢包裹、抢劫送包裹的货车等事件轮番上演。

 

包裹被偷了之后,大部分美国人首先想到的不是报警,而是马上联系平台或卖家。在大多数情况下,有卖家来承受损失。亚马逊和大卖家通常会直接给顾客退款或者补寄。

 

一位亚马逊卖家介绍,他们遇到消费者反映包裹丢失的情况,通常是直接先退款,随后再和平台沟通。相比产品退款,他们更担心买家因为收不到货而给产品打差评。真是卑微!





原文转载:http://www.shaoqun.com/a/521185.html

跨境电商:https://www.ikjzd.com/

f2c:https://www.ikjzd.com/w/1242

敏思达:https://www.ikjzd.com/w/2304


亚马逊或推出新的FBA计划,目前已经在征求意见,卖家纷纷拍手叫好。此外,亚马逊欧洲站费用减免,也将于3月1日生效。亚马逊考虑推出新的FBA退货计划近日,一位卖家称收到了亚马逊团队发来的邮件,很高兴亚马逊的新计划能实现。亚马逊在邮件里提到:我们想确定你是否对两个潜在计划感兴趣?这两个计划是改善FBA客户退货流程的。我们将于2021年2月3日之前进行问卷调查。亚马逊的两种计划方案为:1、不可售退货:卖
欧苏丹:欧苏丹
paipaiwang:paipaiwang
继"啥是佩奇"后又有新难题——啥是无货源跨境电商? :继"啥是佩奇"后又有新难题——啥是无货源跨境电商?
Facebook产品更新!新增自动广告、视频编辑等多款工具:Facebook产品更新!新增自动广告、视频编辑等多款工具
跨境独立站十年浮沉 如今仍是市场"泡沫"?:跨境独立站十年浮沉 如今仍是市场"泡沫"?

2021-01-29

Facebook2020年广告收入同比增长了21%,达842亿美元

近日社交媒体巨头Facebook公布了其2020年第四季度的收入报告。报告显示,在2020年第四季度,Facebook的利润增长了53%,达到了创纪录的112亿美元;收入增长了33%,达到约281亿美元。

 

与此同时,Facebook2020年的总收入同比增长了22%,达到了860亿美元,其中广告业务的营收增长了21%,达到842亿美元,由此可见Facebook的大部分收入都来自于出售广告空间。


脸书财报.png

Facebook强劲的收入增长表明,营销人员增加了在Instagram等社交网络上的广告支出,尤其是节假日期间以吸引消费者进店选购。

 

除了广告收入的持续增长,Facebook旗下包括Oculus虚拟现实部门和Facebook分类广告市场在内的的"其他"业务收入也增长显著,在2020年第四季度同比去年增长了156%至8.85亿美元。

 

用户数据方面,Facebook的第四季度月度活跃用户(MAU)为28亿人次,同比增长12%;每日活跃用户数为18.4亿人次,同比增长11%。Facebook旗下应用程序包括InstagramWhatsAppMessenger在内的用户数量在2020年第四季度增长了10%,达到了26亿。


Facebook 苹果.png


疫情无疑对Facebook的发展起到了一定的促进作用。Facebook强调说明了今年使其收益的两个广泛的经济趋势,即实体零售向在线电商的持续转变以及消费者需求从服务向产品的转变。但是如果其中的任何一个趋势减弱或者逆转都会成为Facebook广告增收的障碍。

 

因此虽然Facebook2020年的各项数据表现良好,但该公司仍对2021年的业绩发展持谨慎态度,并预计2021年Facebook将面临更大的"广告逆风"。

 

Facebook表示,"广告逆风"还可能来自于苹果IDFA(广告商标识符)新规的影响以及不断发展变化的隐私政策。IDFA标识符可被用来跟踪Apple用户的在线活动并据其投放个性化广告。

 

Facebook预计苹果IDFA条款的变更将在第一季度末开始产生影响。苹果系统更新后,当应用程序请求访问公司在其设备内置的IDFA权限时,Apple用户将收到选择是否允许商家使用该权限的弹框,苹果表示其采取这一举措的原因是为了尊重用户的隐私。

 

目前大约有70%的iOS用户与应用程序发布者共享其IDFA,等到苹果的隐私政策更改之后,预计这一数字将下降到10%到15%,这样一来Facebook的广告收入肯定会大受影响。

 

而更让Facebook头疼的是,苹果今年也报告了强劲的iPhone销售业绩。而且有统计数据显示,全球 iPhone 活跃用户数量已经达到了 16.5 亿,

 

真是不是冤家不聚头,要知道后续Facebook的广告收入和广大中小卖家的引流渠道是否会受到较大的影响,可能还真得等到苹果的iOS14更新版正式上线了才知道了。




原文转载:http://www.shaoqun.com/a/521161.html

跨境电商:https://www.ikjzd.com/

易趣:https://www.ikjzd.com/w/210

hemingway:https://www.ikjzd.com/w/2344


近日社交媒体巨头Facebook公布了其2020年第四季度的收入报告。报告显示,在2020年第四季度,Facebook的利润增长了53%,达到了创纪录的112亿美元;收入增长了33%,达到约281亿美元。与此同时,Facebook在2020年的总收入同比增长了22%,达到了860亿美元,其中广告业务的营收增长了21%,达到842亿美元,由此可见Facebook的大部分收入都来自于出售广告空间。Fa
易速:易速
百思买:百思买
亚马逊意法西VAT税务问题解析:亚马逊意法西VAT税务问题解析
Wish仓库管理,怎样提高旺季的发货效率?:Wish仓库管理,怎样提高旺季的发货效率?
跨境运营关键词查找:必知的几种方法介绍!:跨境运营关键词查找:必知的几种方法介绍!

封装

封装

该露的露,该藏的藏

  • 我们程序设计要追求高内聚,低耦合

    高内聚:类的内部操作细节自己完成,不允许外部干涉

    低耦合:仅暴露少量的方法给外部使用

  • 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问(赋值和获取),这称为信息隐藏

  • 封装大部分是对于属性来的,对方法比较少,学了面向对象后,属性一般都用private修饰,不咋用public了

  • 有返回值参数的方法被调用会被当成一个值,可以直接用输出语句输出,也可以让它返回一个值然后在输出那个值

,一般直接输出语句输出,例如:System.out.println(demo05.getname());

  • 那么属性既然被private修饰了,那怎么使用该属性呐?

    要用get/set方法,一个赋值,一个获取

    快捷键:Alt+insert

    输出语句的快捷键:要输出的东西 . sout

  • 我们可以通过set方法增强程序的安全性,例如:

    public class Demo05 { //属性一般都用private修饰 private String name; private int age; //set/get方法来赋值和获取 public int getAge() {  return age; } public void setAge(int age) {  //判断输入的年龄是否合理  if(age>120 || age<0){   System.out.println("您输入的年龄不在正常范围内!");  }else{   this.age = age;  } } public static void main(String[] args) {  Demo05 demo05 = new Demo05();  demo05.setAge(999);  System.out.println(demo05.getAge()); }}
  • 封装的意义:

    1. 提高程序的安全性
    2. 隐藏代码的实现细节
    3. 增加了系统的可维护
  • 记住这句就够了:属性私有,get/set









原文转载:http://www.shaoqun.com/a/521157.html

跨境电商:https://www.ikjzd.com/

tchibo:https://www.ikjzd.com/w/1928

taofenba:https://www.ikjzd.com/w/1725


封装该露的露,该藏的藏我们程序设计要追求高内聚,低耦合高内聚:类的内部操作细节自己完成,不允许外部干涉低耦合:仅暴露少量的方法给外部使用通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问(赋值和获取),这称为信息隐藏封装大部分是对于属性来的,对方法比较少,学了面向对象后,属性一般都用private修饰,不咋用public了有返回值参数的方法被调用会被当成一个值,可以直接用输出语句
网易考拉海购大促:网易考拉海购大促
雨果网:雨果网
口述:节俭婆婆买廉价奶粉给孙子:口述:节俭婆婆买廉价奶粉给孙子
疫情恐影响到Prime Day销售?亚马逊紧急群发邮件:疫情恐影响到Prime Day销售?亚马逊紧急群发邮件
天猫国际数据显示,宠物行业成近年销量增速最快行业!:天猫国际数据显示,宠物行业成近年销量增速最快行业!

吃避孕药有哪些副作用

核心提示:现代男女冲动性行为可能会忘记采取避孕措施。如果女方担心事后意外怀孕,会购买紧急避孕药。

现代男女冲动性行为可能会忘记采取避孕措施。如果女方担心事后意外怀孕,会购买紧急避孕药。一般来说,如果紧急避孕药在72小时内服用,会有避孕效果,但会有副作用。那么,吃了紧急避孕药后有什么副作用?今天我给大家详细介绍一下。

吃了紧急避孕药后有什么副作用

类早孕反应,症状大多是先严重后轻微,然后逐渐消失,可能与身体的逐渐适应有关。服药初期,少数人有轻度早孕反应,如恶心、头晕、乏力等。通常发生在服药的第一至第二周。原因与暂时性雌激素水平过高有关,导致体内水钠潴留,胃肠功能障碍。一般服药2 ~ 3个月后,反应可自然消失或减轻,晚上睡前服药可使白天反应减轻。反应严重的患者可服用维生素B6,每次20毫克,每天3次。如果仍然没有缓解,可以考虑换避孕药,选择雌激素含量较少的药物。

白带增多多为长效口服避孕药所致。所以雌激素含量高,过量的雌激素影响宫颈内膜的分泌细胞,使其分泌旺盛,引起白带增多。


乳房胀痛原因是雌激素对乳房的刺激。

经量减少或闭经,这种情况经常发生在服用短效避孕药后,由于药物抑制排卵,卵巢分泌的雌激素量较少,药物中所含的雌激素量也较少,子宫内膜无法正常生长,子宫内膜较薄,所以月经量减少,甚至停经。月经减少对健康没有影响。如果在服药过程中停经2个月,就应该停药,使用其他避孕措施,大部分可以自行恢复正常。服用长效避孕药后经常出现月经。

经量增多,经期延长。常发生于服用长效口服避孕药的患者。出血较多时可使用止血药物,必要时可注射丙酸睾酮。如果月经量持续增加,出血持续3个月以上,应停止服用长效口服避孕药,改用短效药物。使用长效注射避孕药时,月经不调,如月经延长、月经量过多、周期缩短、不规则出血或闭经,常发生在服药前3个月。如果能坚持使用,以后会逐渐恢复正常。如果出现出血,可以服用炔雌醇3天。


原文转载:http://health.shaoqun.com/a/148955.html

跨境电商:https://www.ikjzd.com/

法瑞儿:https://www.ikjzd.com/w/412

汇通天下物流:https://www.ikjzd.com/w/2055


核心提示:现代男女冲动性行为可能会忘记采取避孕措施。如果女方担心事后意外怀孕,会购买紧急避孕药。 现代男女冲动性行为可能会忘记采取避孕措施。如果女方担心事后意外怀孕,会购买紧急避孕药。一般来说,如果紧急避孕药在72小时内服用,会有避孕效果,但会有副作用。那么,吃了紧急避孕药后有什么副作用?今天我给大家详细介绍一下。吃了紧急避孕药后有什么副作用类早孕反应,症状大多是先严重后轻微,然后逐渐消失,可能与
萌店:萌店
斑马物流:斑马物流
实锤!国家税务总局对跨境电商企业征税问题"既往不咎":实锤!国家税务总局对跨境电商企业征税问题"既往不咎"
爆单策略:如何在黑五网一中脱颖而出!:爆单策略:如何在黑五网一中脱颖而出!
产品主图多重要?看完这篇你就知道!:产品主图多重要?看完这篇你就知道!

Shopee爆单赚钱的核心方法,广州女装大卖年总复盘

【纯干货】Shopee爆单赚钱的核心方法-广州女装大卖年总复盘

看懂ROI(投入产出比),无论做哪个平台的电商都是一个核心技能。

一、什么是ROI?

ROI的全称是return on investment,简称投入产出比。Shopee平台的ROI 计算公式是 ROI= 销售金额 ÷ 花费

举个例子,比如A商品,花了100元广告,销售额300元。那么A 商品的 ROI 就是 3 。

但是,如果仅仅知道ROI等于3。是没有任何意义的。卖家根本无法判断这个3 这个数字的意义,到底代表着赚钱了,还是亏钱了?

所以,必须引入另一个重要的概念:ROI 的盈亏平衡点。

二、重点内容"ROI 的盈亏平衡点"

先说结论:ROI 的盈亏平衡点只跟毛利率有关系,跟其他没有关系。怎么理解这一句话?

例如我们卖女装的,整个行业的毛利率就在33%附近;只要我们知道了毛利率,就可以立马得出女装行业的ROI盈亏平衡点的数值必须的大于3.5。不然就是亏钱的。

教大家一个方法来验证:用数字1来除以ROI。这个是什么意思?

以上面ROI=3.5为例子。用计算机算一下,1除3.5等于0.285。

我们先来看一下ROI=3.5表示什么,是不是可以理解为投入1块钱广告的成本花费,带来3块5 的销售额。那么用1块钱广告成本来 除以 3块5的销售额,就能算出营销成本在销售额当中的占比。

得出来的营销成本占比是28.5%;再拿28.5%跟我们毛利率33%比较大小。立马可以知道当ROI等于3.5的情况下,我们还可以有一点小毛利。

那如果ROI 等于2,那就意味着营销成本占比销售额的50%,比毛利率33%大。营销成本大于毛利率,很明显是亏钱的。亏了17%。

上面就是我们整个的分析过程,非常实用。以后遇到ROI 相关问题,就用数字1来除以ROI ,算出营销占比。再跟毛利率做对比就可以了。

下面我们会用初中的数学知识来推导ROI 的盈亏平衡点只跟毛利率有关系,跟其他没有关系的结论。如果感觉太难,可以忽略不看~

要达到不亏不赚的境界,就是盈亏平衡点

当 利润 = 广告花费的时候

就是盈亏平衡点

设ROI =r 时,取得盈亏平衡点

r 就是ROI 

根据公式 ROI(r)= 销售额 ÷ 广告花费

可以得出

销售额 = ROI (r)x 广告花费

然后

利润我们可以用 销售额 和  毛利率 来表示

利润 = 销售额 x 毛利率 

因为 销售额 = ROI(r) x 广告花费

替换进去

利润(l)=ROI x 广告花费 x 毛利率

当 利润 = 广告花费,就是盈亏平衡点

那么就是

ROI x 广告花费 x 毛利率 = 广告花费

广告花费一约掉

我们就获得了

ROI x 毛利率 =1

ROI 的盈亏平衡点 = 1 ÷ 毛利率

所以我们的结论:

ROI 的盈亏平衡点只跟毛利率有关系,跟其他没有关系

接着我们把他们两者的关系做成了函数图像,如下图:

建议保存本表格,后面知道了毛利率,立马查一下就知道ROI的盈亏平衡点在哪里了。因为毛利率跟ROI 盈亏平衡点,是一一对应的关系。

三、靠ROI怎么逆袭成为大卖家?

虾皮每个站点ROI都不一样,有高有低。按照上述内容的分析,ROI 越高越好。

不难发现,菲律宾站点的ROI ,无论是从哪个维度,ROI的数值都要比其他站点高。不可思议的是,关键字的自动投放,ROI居然可以去到12 。意味着什么,营销费用占比销售额只有8%。只要是毛利率大于30%,妥妥的赚钱。

这也从侧面解释了。2020年,为什么菲律宾站点会突然大爆发。其中一个原因就是因为广告的助力。广告的投放产出比如此的高。

相信你只要掌握了这个技能,给半年时间,只要挖掘对了站点,挖掘对了类目,成为大卖还会远吗?

(来源:虾皮运营日记)

文章来源:https://www.ikjzd.com/home/141643

跨境电商:https://www.ikjzd.com/

reddit:https://www.ikjzd.com/w/180

c2c:https://www.ikjzd.com/w/1576

acca:https://www.ikjzd.com/w/1370

Shopee爆单赚钱的核心方法,广州女装大卖年总复盘

看懂ROI(投入产出比),无论做哪个平台的电商都是一个核心技能。一、什么是ROI?ROI的全称是returnoninvestment,简称投入产出比。Shopee平台的ROI计算公式是ROI=销售金额&#247;花费举个例子,比如A商品,花了100元广告,销售额300元。那么A商

什么原因导致脱发

核心提示:一谈起脱发掉发这种事情时,大家都觉得应该只有年老的人才会有脱发困扰,殊不知,脱发这件事情根本没有年龄分级,现在很多年轻人也有脱发困扰,注意我们这里所指的是脱发并不掉发。掉发就是头皮新陈代谢作用自然脱落的废旧头发,旧的去还有新的来,可是严重脱发的人们,生发速度远远快于脱发速度,若没有及时控制就可能出现光头、秃顶的问题。到底是什么原因导致脱发的呢?

一谈起脱发掉发这种事情时,大家都觉得应该只有年老的人才会有脱发困扰,殊不知,脱发这件事情根本没有年龄分级,现在很多年轻人也有脱发困扰,注意我们这里所指的是脱发并不掉发。掉发就是头皮新陈代谢作用自然脱落的废旧头发,旧的去还有新的来,可是严重脱发的人们,生发速度远远快于脱发速度,若没有及时控制就可能出现光头、秃顶的问题。到底是什么原因导致脱发的呢?

什么原因导致脱发

恶性脱发绝对不是无缘无顾就会发生的事情,与个人生活习惯、饮食习惯、精神压力、护发方式有很大关系,不要以为吃饭这件事情干扰不到头发健康。我们从食物中获取的营养,被分配到全身每个部位,当然也包括头皮毛囊,身体任何皮肤都需要营养补充,如果头皮毛囊没有营养供给,就没有办法继续新生头发,那发生掉发脱发这种情况也就再正常不过。甚至有人为了减肥瘦身,长期过度节食,这个不能吃,那个不让吃的,时间久了营养不良的问题同样会有,那最终会伤及发质健康。

有不少人平时好抽烟喝酒,可能当时觉得不是什么大事,平淡无奇,但时间久了真的会引起脱发,再加上经常熬夜,长期对着电脑产生一些辐射的情况下不仅让人的精神状态受到影响,也会给脱发创造机会。


有不少女生喜欢烫发染发,虽然确实让自己变美了,但不能忽略在烫发染发时会对头发造成伤害,尤其过度频繁做头发的话,对发质、头皮毛囊健康都十分不利。再有就是使用过热的水洗头发,使用过于刺激性的洗发水,这些小细节都是造成脱发的重要诱因。

什么原因导致脱发?真的有太多,以上内容中列举的是我们生活中常会出现的事情,为了保证头发健康,也为了预防脱发,请保持良好生活习惯,有良好护发习惯,不要小看平时这些工作,只要安排妥当,是可以治疗预防脱发的。



原文转载:http://health.shaoqun.com/a/148942.html

跨境电商:https://www.ikjzd.com/

铭宣海淘:https://www.ikjzd.com/w/1551

wangwei:https://www.ikjzd.com/w/1744


核心提示:一谈起脱发掉发这种事情时,大家都觉得应该只有年老的人才会有脱发困扰,殊不知,脱发这件事情根本没有年龄分级,现在很多年轻人也有脱发困扰,注意我们这里所指的是脱发并不掉发。掉发就是头皮新陈代谢作用自然脱落的废旧头发,旧的去还有新的来,可是严重脱发的人们,生发速度远远快于脱发速度,若没有及时控制就可能出现光头、秃顶的问题。到底是什么原因导致脱发的呢? 一谈起脱发掉发这种事情时,大家都觉得应该只
sgshop:sgshop
blibli:blibli
后院起火!亚马逊总部被迫搬家!:后院起火!亚马逊总部被迫搬家!
"令和"将至,日本站跨境卖家该如何选品运营?:"令和"将至,日本站跨境卖家该如何选品运营?
【2019爆单必备】K圈福袋来了!VC+独立站+数据分析最全干货!:【2019爆单必备】K圈福袋来了!VC+独立站+数据分析最全干货!

如何增加肌肉

核心提示:现在的人们对于健康的重视度越来越高了,所以说在平时生活中总是想办法增强自身的免疫力与抵抗力,这样就少不了平时的锻炼,也可以增加身体的肌肉,会让人显的更加强壮,不过仍然有很多人并不知道如何增加自身的肌肉,那么如何增加肌肉呢?

现在的人们对于健康的重视度越来越高了,所以说在平时生活中总是想办法增强自身的免疫力与抵抗力,这样就少不了平时的锻炼,也可以增加身体的肌肉,会让人显的更加强壮,不过仍然有很多人并不知道如何增加自身的肌肉,那么如何增加肌肉呢?

如何增加肌肉

在平时生活中如果说想要增加肌肉含量的话,首先要注意自身的饮食控制,在饮食方面要适当的多吃一些高蛋白质以及高脂肪的食物,在日常生活中可以适量的吃些牛奶、蛋黄、瘦肉或者是深海鱼,在这些食物里面均含有了大量的蛋白质,并且在饮食方面,要尽量的注意,吃食物的时候,要适量的吃一些瘦肉,尤其是红肉以及动物肝脏,这些食物对于增加肌肉含量有着非常大的帮助。


还需要根据自身的情况,选择一些适合自己的一些体育锻炼项目,需要做到健身,才可以使肌肉的含量有所增加,在健身不好的情况下,很容易引起体质虚胖,无法增加肌肉的含量。一周的时间内进行两至三次的肌肉锻炼,健美计划一般情况下分为一周一次打击身体部位,说明需要很长时间才可以锻炼一定特定的肌肉群,一周只能举重三次,可以尝试下全身锻炼,一次锻炼中锻炼全身,一周打三次肌肉,每组肌肉执行两至三组。

另外还需要提前30分钟睡觉,恢复是肌肉生长的必要条件,没有什么更好的方法恢复,并不是简单的睡更多,每晚可以睡八至九个小时。保持良好的作息习惯,不但对增加肌肉有帮助,对身体健康也是有很多好处的。

如何增加肌肉呢?很多人都说想增加自身的肌肉,但是却始终没有找到正确的方法帮助自己增加肌肉,然而在生活中增加肌肉的方法有很多,并且也都是非常简单的,可以从饮食、运动锻炼以及睡觉等方面做起,在以上有相关介绍,希望能帮到大家。


原文转载:http://lady.shaoqun.com/a/265105.html

跨境电商:https://www.ikjzd.com/

easy buy:https://www.ikjzd.com/w/2162

xinong:https://www.ikjzd.com/w/1368


核心提示:现在的人们对于健康的重视度越来越高了,所以说在平时生活中总是想办法增强自身的免疫力与抵抗力,这样就少不了平时的锻炼,也可以增加身体的肌肉,会让人显的更加强壮,不过仍然有很多人并不知道如何增加自身的肌肉,那么如何增加肌肉呢? 现在的人们对于健康的重视度越来越高了,所以说在平时生活中总是想办法增强自身的免疫力与抵抗力,这样就少不了平时的锻炼,也可以增加身体的肌肉,会让人显的更加强壮,不过仍然
reverb:reverb
anker:anker
Lazada运营—如何利用生意参谋为搜索推广选品选词&案例分析:Lazada运营—如何利用生意参谋为搜索推广选品选词&案例分析
亚马逊智能化妆镜爆款供应商曝光!一年营收超5亿!:亚马逊智能化妆镜爆款供应商曝光!一年营收超5亿!
Wish: 复工后的明星产品,增长率4颗星!:Wish: 复工后的明星产品,增长率4颗星!