1. Lambda

1.1 函数式编程思想概述

  • 在数学中,函数就是有输入量、输出量的一套计算方案,也就是“数据做操作“
  • 面向对象思想强调“必须通过对象的形式来做事情”
  • 函数式思想则尽量忽略面向对像的复杂语法:“强调做什么,而不是以什么形式去做”
  • 而我们要学习的Lambda表达式就是函数式思想的体现

1.2 体验lambda表达式

需求:启动一个线程,在控制台输出一句话:多线程程序启动了

方式1:

  • 定义一个类MyRunnable:实现Runnable接口,重写run() 方法
  • 创建MyRunnable类的对象
  • 创建Thread类的对象,把MyRunnable的对象作为构造参数传递
  • 启动线程

方式2:

  • 匿名内部类的方式改进

方式3:

  • Lambda表达式的方式改进
//1.创建MyRunnable类
package demo_01;public class MyRunnable implements Runnable{@Overridepublic void run() {System.out.println("多线程启动了");}
}//2.实现类
package demo_01;
//需求:启动一个线程,在控制台输出一句话:多线程程序启动了
public class LambdaDemo {public static void main(String[] args) {//实现类的方式实现需求/* MyRunnable my = new MyRunnable();Thread th = new Thread(my);th.start();*///匿名内部类的方式改进/*new Thread(new Runnable() {@Overridepublic void run() {System.out.println("多线程启动了");}}).start();*///Lambda表达式的方式改进new Thread(() -> {System.out.println("多线程启动");}).start();}
}

1.3 Lambda表达式的标准格式

匿名内部类中重写run() 方法的代码分析:

  • 方法形式参数为空,说明调用方法时不需要传递参数
  • 方法返回值类型为void,说明方法执行没有结果返回
  • 方法体中的内容,是我们具体要做的事情
//匿名内部类的方式改进
new Thread(new Runnable() {@Overridepublic void run() {System.out.println("多线程启动了");}
}).start();

Lambda表达式的代码分析:

  • () :里面没有内容,可以看成是方法形式参数为空
  • -> :用箭头指向后面要做的事情
  • {}:包含一段代码,我们称之为代码块,可以看成是方法体中的内容

组成Lambda表达式的三要素:形式参数,箭头,代码块

//Lambda表达式的方式改进
new Thread(() -> {System.out.println("多线程启动");
}).start();

Lambda表达式的格式:

  • 格式:(形式参数)-> {代码块}
  • 形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
  • ->:由英文中画线和大于符号组成,固定写法。代表指向动作
  • 代码块:是我们具体要做的事情,也就是以前我们写的方法体内容

1.4 Lambda表达式的使用

Lambda表达式的使用前提:

  1. 有一个接口
  2. 接口中有且仅有一个抽象方法

练习1:

  • 定义一个接口(Eatable),里面定义一个抽象方法:void eat();
  • 定义一个测试类(EatableDemo),在测试类中提供两个方法:
    一个方法是:useEatable(Eatable e)
    一个方法是主方法,在主方法中调用useEatable方法
//1.创建接口
package demo_02;public interface Eatable {void eat();
}//2.接口实现类
package demo_02;public class EatableLmpl implements Eatable{@Overridepublic void eat() {System.out.println("吃水果");}
}//3.测试类
package demo_02;
/*
- 定义一个接口(Eatable),里面定义一个抽象方法:void eat();- 定义一个测试类(EatableDemo),在测试类中提供两个方法:一个方法是:useEatable(Eatable e)一个方法是主方法,在主方法中调用useEatable方法
*/
public class EatableDemo {public static void main(String[] args) {//接口实现类方法Eatable el = new EatableLmpl();useEatable(el);//匿名内部类useEatable(new Eatable() {@Overridepublic void eat() {System.out.println("吃水果");}});//lambda表达式useEatable(()->{System.out.println("吃水果");});}public static void useEatable(Eatable e){e.eat();}
}

练习2:

  • 定义一个接口(Flyable),里面定义一个抽象方法:void fly(String s):
  • 定义一个测试类(FlyableDemo),在测试类中提供两个方法
    一个方法是:useFlyable(Flyable f)
    一个方法是主方法,在主方法中调用useFlyable方法
//1.创建Flyable接口
package demo_03;public interface Flyable {void fly(String s);
}//测试类
package demo_03;
/*
- 定义一个接口(Flyable),里面定义一个抽象方法:void fly(String s):- 定义一个测试类(FlyableDemo),在测试类中提供两个方法一个方法是:useFlyable(Flyable f)一个方法是主方法,在主方法中调用useFlyable方法*/
public class FlyableDemo {public static void main(String[] args) {//匿名内部类useFlyable(new Flyable() {@Overridepublic void fly(String s) {System.out.println(s);System.out.println("万物复苏");}});//lanbada表达式useFlyable((s -> {System.out.println("lambada引用");}));}public static void useFlyable(Flyable f){f.fly("出暖花开,生机勃勃");}
}

练习3:

  • 定义一个接口(Addable),里面定义一个抽象方法:int add(intx, inty);
  • 定义一个测试类(AddableDemo),在测试类中提供两个方法:
    一个方法是:useAddable(Addable a
    一个方法是主方法,在主方法中调用useAddable方法
//1.创建接口
package demo_04;public interface AddAble {int add(int x,int y);
}//2.测试类
package demo_04;
/*
- 定义一个接口(Addable),里面定义一个抽象方法:int  add(intx, inty);- 定义一个测试类(AddableDemo),在测试类中提供两个方法:一个方法是:useAddable(Addable a一个方法是主方法,在主方法中调用useAddable方法*/
public class AddAbleDemo {public static void main(String[] args) {//调用useAddable方法useAddable(((x, y) -> {return x + y;}));}public static void useAddable(AddAble a){int sum = a.add(10,20);System.out.println(sum);}
}

1.5 Lambda表达式的省略模式

省略规则:

  • 参数类型可以省略。但是有多个参数的情况下,不能只省略一个
  • 如果参数有且仅有一个,那么小括号可以省略
  • 如果代码块的语句只有一条,可以省略大括号和分号,甚至是return
//1.定义Addable接口
package demo_05;public interface Addable {int add(int x, int y);
}//2.创建Flyanle接口
package demo_05;public interface Flyable {void fly(String s);
}//3.测试类
package demo_05;import demo_03.Flyable;
import demo_04.AddAble;public class LambdaDemo {public static void main(String[] args) {//参数类型可以省略useAddable((x,y)->{return x + y;});useFlyable((s) -> {System.out.println(s);});//如果参数有且仅有一个,那么小括号也可以省略useFlyable(s -> System.out.println(s));//如果代码语句只有一条,可以省略大括号和分号useFlyable(s -> System.out.println(s));//如果代码语句只有一条,可以省略大括号和分号,如果有return,也可以省略掉useAddable((x,y)-> x + y);}public static void useFlyable(Flyable f){f.fly("春暖花开,万物复苏");}public static void useAddable(AddAble a){int sum = a.add(20,30);System.out.println(sum);}
}

1.6 Lambda表达式的注意事项

注意事项:

  • 使用Lambda必须要有接口,并且要求接口中有且仅有一个抽象方法
  • 必须有上下文环境,才能推导出Lambda对应的接口
    根据局部变量的赋值得知Lambda对应的接口:Runnable r=()->System.out.println(“Lambda表达式”);
    根据调用方法的参数得知Lambda对应的接口:new Thread(()->System.out.println(“Lambda表达式”).start();

1.7 Lambda表达式和匿名内部类的区别

1.所需类型不同

  • 匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
  • Lambda表达式:只能是接口

2.使用限制不同

  • 如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
  • 如果接口中有多个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式

3.实现原理不同

  • 匿名内部类:编译之后,产生一个单独的.class字节码文件
  • Lambda表达式:编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成

3.方法引用

3.1方法引用符

**方法引用符"::"**该符号为引用运算符,而它所在的表达式被称为方法引用

体验方法引用中的代码:

  • Lambda表达式:usePrintable(s->System.out.println(s));
  • 分析:拿到参数s之后通过Lambda表达式,传递给System.out.println方法去处理
  • 方法引用:usePrintable(System.out::printIn);
  • 分析:直接使用System.out中的println方法来取代Lambda,代码更加的简洁推导与省略
  • 如果使用Lambda,那么根据“可推导就是可省略”的原则侧,无需指定参数类型,也无需指定的重载形式,它们都将被自动推导
  • 如果使用方法引用,也是同样可以根据上下文进行推导
  • 方法引用是Lambda的李生兄弟
//1.创建接口
package demo_01;public interface Printable {void printInt(int i);
}//2.测试类
package demo_01;public class PrintableDemo {public static void main(String[] args) {//Lambda表达式调用usePrintable(i -> System.out.println(i));//方法引用usePrintable(System.out::println);}private static void usePrintable(Printable p){p.printInt(666);}
}

3.2 引用类方法

引用类方法,其实就是引用类的静态方法

  • 格式:类名::静态方法

  • 范例:Integer::parselnt

    Integer类的方法:public static int parselnt(String s)将此String转换为int类型数据

//1.
package demo_02;public interface Converter {int convert(String s);
}//2.
package demo_02;public class ConverterDemo {public static void main(String[] args) {//Lambda表达式调用useConvert(s -> Integer.parseInt(s));useConvert((String s)->{int i = Integer.parseInt(s);return i;});//引用类方法useConvert(Integer::parseInt);//Lambda表达式被类方法替代的时候,他的形式参数全部传递给静态方法作为参数}private static void useConvert(Converter c){int result = c.convert("666");System.out.println(result);}
}

3.3 引用对象的实例方法

引用对象的实例方法,其实就引用类中的成员方法

  • 格式:对象::成员方法
  • 范例:“HelloWorld”::toUpperCase
    String类中的方法:public String toUpperCase0将此String.所有字符转换为大写
//1.创建对象
package demo_03;public class PrintString {public void printUpper(String s){//toUpperCase()把字符转化为大写String s1 = s.toUpperCase();System.out.println(s1);}
}
//2.创建接口
package demo_03;public interface Printer {void printUpperCase(String s);
}
//3.测试类
package demo_03;public class PrinterDemo {public static void main(String[] args) {//Lambda表达式usePrinter(s -> System.out.println(s.toUpperCase()));//引用对象的实例方法PrintString ps = new PrintString();usePrinter(ps::printUpper);}private static void usePrinter(Printer p){p.printUpperCase("helloword");}
}

3.4 引用类的实例方法

引用类的实例方法,其实就是引用类中的成员方法

  • 格式:类::成员方法
  • 范例:String::substring
//1.创建接口
package demo_04;public interface MyString {String mySubString(String s,int x,int y);
}//2.测试类
package demo_04;public class MyStringDemo {public static void main(String[] args) {/*useMyString((String s,int x, int y)->{return s.substring(x, y);});*///        useMyString((s,x,y)->s.substring(x,y));//引用类的实例方法useMyString(String::substring);}private static void useMyString(MyString my){String s = my.mySubString("helloword", 2, 5);System.out.println(s);}
}

3.5 引用构造器

引用构造器,其实就是引用构造方法

  • 格式:类::new
  • 范例:Student::new
//1.创建接口
package demo_05;public interface StudentBuilder {Student build(String name,int age);
}
//2.创建学生类
//3.测试类
package demo_05;public class StudentDemo {public static void main(String[] args) {useStudentBuilder((name, age) -> new Student(name,age));//引用构造器useStudentBuilder(Student::new);}private static void useStudentBuilder(StudentBuilder sb){Student s1 = sb.build("张三", 18);System.out.println(s1.getName()+s1.getAge());}
}

5. 类加载器

5.1类加载

当程序要使用某个类时,如果该类还未被加截到内存中,则系统会通过类的加载,类的连接,类的初始化这三个步骤来对类进行初始化。如果不出现意外情况,JVM将会连续完成这三个步骤,所以有时也把这三个步骤统称为类加载或者类初始化

类的加载

  • 就是指将class文件读入内存,并为之创建一个java.lang.Class对象
  • 任何类被使用时,系统都会为之建立一个java.lang.Class对象

类的连接

  • 验证阶段:用于检验被加载的类是否有正确的内部结构,并和其他类协调一致
  • 准备阶段:负责为类的类变量分配内存,并设置默认初始化值
  • 解析阶段:将类的二进制数据中的符号引用替换为直接引用

类的初始化

  • 在该阶段,主要就是对类变量进行初始化

类的初始化步骤

  1. 假如类还未被加载和连接,则程序先加载并连接该类
  2. 假如该类的直接父类还未被初始化,则先初始化其直接父类
  3. 假如类中有初始化语句,则系统依次执行这些初始化语句
  4. 注意:在执行第2个步骤的时候,系统对直接父类的初始化步骤也遵循初始化步骤1-3

类的初始化时机:

  1. 创建类的实例
  2. 调用类的类方法
  3. 访问类或者接口的类变量,或者为该类变量赋值
  4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
  5. 初始化某个类的子类
  6. 直接使用java.exe命令来运行某个主类

5.2 类加载器

类加载器的作用

  • 负责将.class文件加载到内存中,并为之生成对应的java.lang.Class对象
  • 虽然我们不用过分关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行

JVM的类加载机制

  • 全盘负责:就是当一个类加载器负责加载某个Class时,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入
  • 父类委托:就是当一个类加载器负责加载某个Class时,先让父类加载器试图加载该Class,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类
  • 缓存机制:保证所有加载过的Class都会被缓存,当程序需要使用某个Class对象时,类加载器先从缓存区中搜索该Class,只有当缓存区中不存在该Class对象时,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存储到缓存区

ClassLoader:是负责加载类的对象

Java运行时具有以下内置类加载器

  • Bootstrap class loader:它是虚拟机的内置类加载器,通常表示为null,并且没有父nul川
  • Platform class loader:平台类加载器可以看到所有平台类,平台类包括由平台类加载器或其祖先定义的Java SE平台API,
    其实现类和DK特定的运行时类
  • System class loader:它也被称为应用程序类加载器,与平台类加载器不同。系统类加载器通常用于定义应用程序类路径模块路径和JDK特定工具上的类
  • 类加载器的继承关系:System的父加载器为Platform,而Platform的父加载器为Bootstrap

ClassLoader中的两个方法

  • static ClassLoader getSystemClassLoader():返回用于委派的系统类加载器
  • ClassLoader getParent():返回父类加载器进行委派

6 反射

6.1 反射概述

Java反射机制:是指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展

练习

//三种方式获取Class对象://1.使用类的class,属性来获取该类对应的Class对象。举例:Student.class将会返回Student类对应的Class对象//2.调用对象的getClass()方法,返回该对象所属类对应的Class对象//该方法是Object类中的方法,所有的Java对象都可以调用该方法//3.使用CLass类中的静态方法ForName(String className),该方法需要传入字符串参数,该字符串参数的值是某个类的全路径,
//1.创建Student类//2.测试类
package demo_01;public class Demo {public static void main(String[] args) throws ClassNotFoundException {//1.使用类的class,属性来获取该类对应的Class对象。举例:Student.class将会返回Student类对应的Class对象Class<Student> c1 = Student.class;System.out.println(c1);//2.调用对象的getClass()方法,返回该对象所属类对应的Class对象Student s1 = new Student();Class<? extends Student> c2 = s1.getClass();System.out.println(c2 == c1);//3.使用CLass类中的静态方法ForName(String className),该方法需要传入字符串参数,该字符串参数的值是某个类的全路径,Class<?> c3 = Class.forName("demo_01.Student");System.out.println(c3 == c2);}
}

6.2 反射获取构造方法并使用

Class类中用于获取构造方法的方法:

Constructor<?>[] getConstructors():返回所有公共构造方法对象的数组
Constructor<?>[] getDeclaredConstructors():返回所有构造方法对象的数组
Constructor<T> getConstructor((Class<?>parameterTypes):返回单个公共构造方法对象
Constructor<T> getDeclaredConstructor(Class<?>parameterTypes):返回单个构造方法对像
Constructora类中用于创建对象的方法
T newInstance(Object.initargs):根据指定的构造方法创建对象

6.2 练习1:反射获取构造方法的使用

练习1:通过反射实现如下操作

  • Student s=new Student(“林青霞”,30,“西安”);
  • System.out.println(s);
  • 基本数据类型也可以通过.class得到对应的Class类型
package test;import java.lang.reflect.Constructor;public class Test_01 {public static void main(String[] args) throws Exception{//获取class对象Class<?> c = Class.forName("demo_01.Student");//Constructor<T> getConstructor(类<?>... parameterTypes)//返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共 类函数。Constructor<?> cos = c.getConstructor(String.class, int.class, String.class);//T newInstance(Object... initargs)//使用此 Constructor对象表示的构造函数,使用指定的初始化参数来创建和初始化构造函数的声明类的新实例。 Object obj = cos.newInstance("林青霞", 18, "西安");System.out.println(obj);}
}

练习2:通过反射实现如下操作

Student s=new Student(“林青霞”);
System.out.printIn(s);

public void setAccessible(boolean flag):值为true,取消访问检查
package test;import java.lang.reflect.Constructor;public class Test_02 {public static void main(String[] args) throws Exception{//获取class对象Class<?> c = Class.forName("demo_01.Student");//Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)//返回一个 Constructor对象,该对象反映 Constructor对象表示的类或接口的指定 类函数。Constructor<?> con = c.getDeclaredConstructor(String.class);//暴力反射//public void setAccessible(boolean flag):值为true,取消访问检查con.setAccessible(true);Object obj = con.newInstance("林青霞");System.out.println(obj);}
}

6.3 反射获取成员变量

Class类中用于获取成员变量的方法

  • Field[] getFields():返回所有公共成员变量对象的数组
  • Field[] getDeclaredFields():返回所有成员变量对象的数组
  • Field getField(String name):返回单个公共成员变量对象
  • Field getDeclaredField(String name):返回单个成员变量对象

Field类中用于给成员变量赋值的方法

  • void set(Object obj,Object value):给obj对象的成员变量赋值为value

练习:获取成员变量

要求:Student s new Student();s.name="林青霞";s.age = 30;s.address="西安";System.out.printin(s);
package test;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;public class Test_03 {public static void main(String[] args) throws Exception{//获取Class对象Class<?> c = Class.forName("demo_01.Student");//获取无参构造方法对象Constructor<?> con = c.getConstructor();Object obj = con.newInstance();//获取成员变量nameField name = c.getDeclaredField("name");name.setAccessible(true);name.set(obj,"林青霞");System.out.println(obj);//获取成员变量ageField age = c.getDeclaredField("age");age.setAccessible(true);age.set(obj,30);System.out.println(obj);//获取成员变量addressField address = c.getDeclaredField("address");address.setAccessible(true);address.set(obj,"西安");System.out.println(obj);}
}

6.4 反射获取成员方法

Class类中用于获取成员方法的方法

  • Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
  • Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
  • Method getMethod(String name,Class<?>.parameterTypes):返回单个公共成员方法对象
  • Method getDeclaredMethod(String name,Class<?>.parameterTypes):返回单个成员方法对象

Method类中用于调用成员方法的方法

  • Object invoke(Object obj,Object.args):调用obj对象的成员方法,参数是args,返回值是Object类型

练习

package test;import java.lang.reflect.Constructor;
import java.lang.reflect.Method;/*
练习:通过反射实现如下操作:Student s new Student();s.method1();s.method2("林青霞");String ss=s.method3("林青霞",30);System.out.printIn(ss);s.function();
*/
public class Test_04 {public static void main(String[] args) throws Exception{//获取Class对象Class<?> c = Class.forName("demo_01.Student");//获取无参构造方法对象Constructor<?> con = c.getConstructor();Object obj = con.newInstance();//获取方法 s.method1();Method m1 = c.getMethod("method1");m1.invoke(obj);//s.method2("林青霞");Method m2 = c.getMethod("method2", String.class);m2.invoke(obj,"林青霞");//String ss=s.method3("林青霞",30);Method m3 = c.getMethod("method3", String.class, int.class);Object result = m3.invoke(obj, "林青霞", 18);System.out.println(result);//s.function();Method m4 = c.getDeclaredMethod("function");m4.setAccessible(true);m4.invoke(obj);}
}

6.5 练习:越过泛型检查

练习1:我有一个ArrayList.集合,现在我想在这个集合中添加一个符串数据,如何实现?

package test;import java.lang.reflect.Method;
import java.util.ArrayList;public class Test_越过泛型检查 {public static void main(String[] args) throws Exception{//创建集合ArrayList<Integer> array = new ArrayList<Integer>();//获取Class对象Class<? extends ArrayList> c = array.getClass();Method m = c.getDeclaredMethod("add", Object.class);//添加元素m.invoke(array,"hello");m.invoke(array,"world");m.invoke(array,"java");System.out.println(array);}
}

6.6 练习:运行配置文件指定内容

package com.itheima.demo09Reflect;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
import java.util.ResourceBundle;public class Demo09 {public static void main(String[] args) throws Exception {//方式一/*// 1.通过Properties加载配置文件Properties pp = new Properties();pp.load(new FileReader("day_13\\src\\config.properties"));System.out.println("pp = " + pp);// 2.得到类名和方法名String className = pp.getProperty("classname"); // com.itheima.demo09Reflect.TeacherString methodName = pp.getProperty("methodname"); // teach*///方式二ResourceBundle config = ResourceBundle.getBundle("config"); //读取config.properties//得到类名和方法String classname = config.getString("className");String methodname = config.getString("methodName");// 3.通过类名反射得到Class对象Class<?> cls = Class.forName(classname);// 4.通过Class对象创建一个对象Object obj = cls.getConstructor().newInstance();// 5.通过Class对象得到方法Method method = cls.getMethod(methodname);// 6.调用方法method.invoke(obj);}
}//2.Worker类
package com.itheima.demo09Reflect;public class Worker {public void working() {System.out.println("我是十年后来的工人,我跑的很开心!");}
}

Java笔记 - 黑马程序员_08(Lambda表达式,接口组成更新,方法引用,类加载器,反射)相关推荐

  1. 十三、Java高级特性 Lambda表达式 | 接口组成更新 | 方法引用 | 函数式接口

    文章目录 十三.Java高级特性 1.Lambda表达式 1.1体验Lambda表达式[理解] 1.2Lambda表达式的标准格式[理解] 1.3Lambda表达式练习1[应用] 1.4Lambda表 ...

  2. [学习笔记]黑马程序员-Hadoop入门视频教程

    文章目录 参考资料 第一章:大数据导论与Linux基础(p1-p17) 1.1 大数据导论 1.1.1 企业数据分析方向 1.1.2 数据分析基本流程步骤 明确分析的目的和思路 数据收集 数据处理 数 ...

  3. Java教程-黑马程序员版

    很多初学Java的小伙伴,在选择Java教程的时候有很多困惑.哪一套Java教程更适合入门?某一个技术学完之后能做什么?黑马程序员为大家整理了2022年Java教程的选择建议.希望对大家有帮助~ 如果 ...

  4. [学习笔记]黑马程序员python教程

    文章目录 思维导图 Python基础知识图谱 面向对象 SQL入门和实战 Python高阶技巧 第一阶段 第九章:Python异常.模块与包 1.9.1异常的捕获 1.9.1.1 为什么要捕获异常 1 ...

  5. [学习笔记]黑马程序员Spark全套视频教程,4天spark3.2快速入门到精通,基于Python语言的spark教程

    文章目录 视频资料: 思维导图 一.Spark基础入门(环境搭建.入门概念) 第二章:Spark环境搭建-Local 2.1 课程服务器环境 2.2 Local模式基本原理 2.3 安装包下载 2.4 ...

  6. c语言笔记——黑马程序员上课笔记

    C语言概述 1.1 什么是C语言 一提到语言这个词语,自然会想到的是像英语.汉语等这样的自然语言,因为它是人和人交换信息不可缺少的工具. 而今天计算机遍布了我们生活的每一个角落,除了人和人的相互交流之 ...

  7. Node.js学习笔记 [黑马程序员]——day34

    文章目录 初识 Express 简介 Express 的基本使用 托管静态资源 nodemon Express 路由 路由的概念 :dog:什么是路由 :dog:Express 中的路由 :dog: ...

  8. Node.js学习笔记 [黑马程序员]——day2

    文章目录 模块化的基本概念 模块化规范 Node.js 中模块的分类 Node.js 中模块的分类 加载模块 Node.js 中的模块作用域 向外共享模块作用域中的成员 `module` 对象 `mo ...

  9. 黑马程序员_抽象类和接口

    ------- android培训.java培训.期待与您交流! ---------- ★抽象类 我们在定义一个类的时候,常常需要定义方法来描述该类的行为特征, 但有的时候这个(方法)的{方法体}怎样 ...

最新文章

  1. P1541 乌龟棋 题解(洛谷,动态规划递推)
  2. 通过举例谈谈阻塞赋值与非阻塞赋值的区别
  3. [20181220]使用提示OR_EXPAND优化.txt
  4. Python3.x 发送邮件
  5. 虚拟机:Centos 7 安装JDK8(亲测)
  6. c语言for循环++_C ++程序使用循环查找数字的幂
  7. php http_user_agent 微信浏览器改变为其他浏览器,微信内置浏览器HTTP_USER_AGENT
  8. 软考信息系统项目管理师_管理科学(运筹学)2---软考高级之信息系统项目管理师034
  9. 【深入理解JVM】JVM的五大运行时数据区域
  10. c语言汉诺塔递归算法_Python进阶之递归函数的用法及其示例
  11. 如何将Mac的磁盘空间从0G清理出100G?
  12. 解析LIFO(FILO)结构栈(C语言版)
  13. 数字人民币智慧学生证来了,对于特定群体硬钱包或大有可为
  14. 视频局部区域的马赛克处理
  15. 2018世界人工智能大会
  16. 从Python爬虫到Spark预处理数据的真实需求[四]
  17. 计算机全键在线使用说明书,键盘说明图_电脑键盘使用说明讲解
  18. Unity中的静态合批、动态合批、GPU Instance 以及SRP Batching
  19. ARM发布 Cortex-M35P保护物联网智能连接
  20. 你能分清比例和比率吗?

热门文章

  1. 【Python从零到壹】Python文件的操作详解
  2. 良心安利芒种节气海报设计素材
  3. Win10系统Anaconda+TensorFlow+Keras 环境搭建教程
  4. javascript小案例-----tab栏切换
  5. 【总结】从0到1的项目经历
  6. 职业能力倾向测试下什么软件,职业能力倾向测验
  7. 不同性能测试工具的并发模式
  8. 电动牙刷也有国产黑马,竟然比千元大牌还厉害 | 钛空实测
  9. The type 类名 is already defined
  10. 今天,魅族发布了一款AirPods!