A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 鹏鹏鹏鹏 初级黑马   /  2018-12-2 15:34  /  874 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

             
                                      day-11网络通信

一 软件结构介绍

     C/S结构:

        全称为Client/Server结构, 是指 客户端 和 服务器 结构

        常见程序有QQ, 迅雷等软件



    B/S结构:

        全称为Browser/Server结构, 是指 浏览器 和 服务器 结构

        常见浏览器有IE, 谷歌, 火狐等

网络编程: 在一定的"协议"下, 实现两台计算机的通信的程序

二 网络通信协议

概述:

        通信协议是计算机必须遵守的规则, 只有遵守这些规则, 计算机之间才能进行通信.

        协议中对数据的传输格式, 传输速率, 传输步骤等做了统一规定, 通信双方必须同时遵守, 最终完成数据交换

   TCP/IP协议:

        Transmission Control Protocol/Internet Protocol, 传输控制协议/因特网互联协议.

三 网络通信协议分类

   (1) UDP

               特点  1. 无连接的不可靠协议

                        2. 数据按包发送, 64K一个包

                        3. 速度快效率高, 容易丢包

        用于视频直播, 网络电话

(2) TCP

              特点  1. 需要建立连接的可靠协议  电话

                       2. 数据传输无大小限制

                       3. 速度慢效率低   重发机制

        用于文件下载, 浏览网页

    TCP 协议需要进行三次握手

四   网络编程三要素

             1. 通信协议    怎么传输

             2. IP地址       传给哪个主机

             3. 端口号      传给主机的哪个进程

五   TCP通信

        (1)  ServerSocket类: TCP服务端

       构造方法

                  ServerSocket(int port): 创建一个TCP服务端, 并监听指定端口

      成员方法

                Socket accept(): 监听数据, 会阻塞. 收到数据后返回Socket对象

               void close(): 关闭服务端ServerSocket

(2) Socket类: TCP客户端

         构造方法

              Socket(String ip, int port): 创建TCP客户端对象

        成员方法

            OutputStream getOutputStream(): 获取输出流对象, 用于发送数据

        InputStream getInputStream(): 获取输入流, 用于接收数据

        void shutdownOutput(): 关闭输出流, 发送结束标记

        void close(): 关闭客户端Socket

两端通信时步骤:

        1. 服务端程序需要先启动, 等待客户端的连接

        2. 客户端主动连接服务器端, 连接成功才能通信. 服务端不可以主动连接客户端

        两端之间以 "IO字节流" 进行通信

        一个服务端可以和多个客户端同时通信

        
                                    day12 函数式接口

一  函数式接口

      特性: 有且仅有一个抽象方法的接口,适用于函数式接口

      默认方法,静态方法,私有方法与Object类定义的 相同抽象方法,都不算作抽象方法

     @FunctionalInterface的作用:

        在接口上使用, 检测当前的接口是否为函数式接口

    函数式接口的使用:

        作为方法的参数类型, 传递Lambda表达式, 代替匿名内部类方式

   Lambda具有"延迟执行"的特点:

        传递Lambda对象, 只有当符合执行条件时, 才会执行代码

使用Lambda表达式作为方法参数

     当一个方法的参数是一个函数式接口时,可以使用Lambda表达式传递该参数,简化匿名内部类的代码

      当一个方法的返回值是一个函数式接口时,可以返回Lambda表达式,简化匿名内部类的代码

二,  Supplier生产型函数式接口

抽象方法

           T get():用于获取一个对象或值;

三,Consumer消费型函数式接口

     抽象方法

           void accept(T t):用于消费或使用一个对象或值

    默认方法     default Consumer<T> andThen(Consumer<? super T> after): 拼接两个Consumer接口的Lambda对象实现连续操作. 谁写前面, 谁先消费

四 Predicate条件判断函数式接口

     抽象方法    boolean test(T t): 判断参数传递的对象.

     默认方法   default Predicate<T> and(Predicate<? super T> other): 与 &&

        default Predicate<T> or(Predicate<? super T> other): 或  ||

        default Predicate<T> negate(): 非, 取相反结果   !

五 Function转换型函数式接口

         抽象方法 :

                     R apply(T t): 将T转换为R. 至于T和R是什么类型, 以及如何转换, 需要传递Lambda表达式实现

        默认方法:

                    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after): 拼接多个Function转换

                        day13 Stream 方法引用

Stream流

      tream流式思想:

                先编写所有处理方案, 最后再统一执行方案

                应用场景: 简化对集合/数组复杂操作的代码

    流相比于集合的2个优点:

        1. Pipelining(管道特性): "可以链式调用"

                Stream流对象的 延迟方法 调用后, 会返回新的Stream流对象, 可以链式调用

                每个方法类似于一条一条的管道, 衔接了不同的处理方案

        2. 内部迭代特性: "不用写for循环"

                集合遍历通过 Iterator 或者 增强for, 显式的在集合外部进行迭代, 这叫做外部迭代

                Stream提供了内部迭代的方法 forEach(Consumer c), 可以直接调用遍历方法



使用Stream流的3个步骤:

        1. 获取数据源 (从"集合"或"数组"转换为"Stream"对象)

        2. 数据处理 (调用延迟方法, 编写处理方案)

        3. 获得结果 (调用终结方法, 启动开关)

二 获取Stream流的方式

     1.利用"Collection接口"中的默认方法 default Stream<E> stream() 方法: 集合转Stream对象

    2.利用"Stream接口"中的静态方法 static <T> Stream<T> of(T... values): 数组转Stream对象

三. Stream 方法分类

    1.forEach 遍历(延迟方法)

      oid forEach(Consumer<? super T> action): 遍历流中的元素进行逐一消费. 并不保证元素的逐一消费动作在流中是被有序执行的

   2.filter()过滤

     Stream<T> filter(Predicate<? super T> predicate): 过滤符合条件的结果. 返回过滤后的流

3. map()映射转换

   R> Stream<R> map(Function<T, R> mapper): 将当前流中的T类型的元素, 转换R类型元素, 放入新流并返回

4. count()计数

   long count(): 获取流中的元素个数 (终结方法)

5.limit()获取前N个元素

Stream<T> limit(long maxSize): 从流中获取前maxSize个. 如果maxSize大于等于元素个数, 则返回所有元素的流

6.skip()不要前N个元素

  Stream<T> skip(long n): 从流中跳过n个元素, 获取后面的元素. 如果n大于等于元素个数, 则全都跳过

7.concat() 合并两个流

static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b): 合并两个流的元素, 变成一个新的流. 两个流中的元素类型必须相同, 或有共同的父类

四. 扩展

   1.流转为数组

     Object[] toArray(): 将当前Stream流对象转换为Object[]数组

   2.流转为集合

     <R,A> R collect(Collector<? super T,A,R> collector): 将当前Stream流对象根据传入的Collector转换为集合或数组

  注意 Collector需要Collectors工具类的方法

    static <T> Collector<T,?,List<T>> toList(): Stream转List集合  

        static <T> Collector<T,?,Set<T>> toSet(): Stream转Set集合

        static <...> Collector<...> toMap(Function<? super T,? extends K> keyMapper,

                                      Function<? super T,? extends U> valueMapper)

五 方法引用

     如果Lambda表达式仅仅是调用一个已经存在的方法, 那就可以通过方法引用来替代Lambda表达式

   ::方法引用运算符

  注意

    Lambda中, 重写方法的"参数", 必须是方法引用的方法"要接收的类型", 否则会抛出异常

  1.对象名引用成员方法

      对象名::成员方法名

   适用场景:

        当Lambda表达式中, 仅仅是"通过某个对象, 调用已有的方法"时, 就可以用这种方式简化

2  类名引用静态方法

    类名::静态方法名

    适用场景:

        当Lambda表达式中, 仅仅是"通过某个类名, 调用已有的静态方法"时, 就可以用这种方式简化

3. 通过super引用父类成员方法

  super::父类方法名

适用场景

        当Lambda表达式中, 仅仅是"在子类中, 调用父类某个已有的方法"时, 就可以用这种方式简化

4 this引用本类成员方法

   this ::本类方法名

适用场景:

        当Lambda表达式中, 仅仅是"调用本类中, 某个已有的方法"时, 就可以用这种方式简化

5.类的构造方法引用

类名:;new

使用场景

        当Lambda表达式中, 仅仅是"调用某个类的构造方法, 来创建一个对象"时, 就可以用这种方式简化

6.数组的构造方法引用

  数据类型[]::new

使用场景

        当Lambda表达式中, 仅仅是"创建一个数组对象"时, 就可以用这种方式简化

                                  day14 JUnit 反射 注解

一 JUnit 单元测试

        测试分类:

        1. 黑盒测试:不需要写代码, 给输入值, 看程序是否能够输出期望的值

                比如你下载一个APP, 随便点点点, APP闪退了

        2. 白盒测试:需要写代码的. 关注程序具体的执行流程

二   测试步骤

      Unit使用步骤:

        1. 定义一个测试类(也叫测试用例)

            包名:xxx.xxx.xx.test

                被测试的类名:   Calculator   

                对应的测试类名: CalculatorTest

        2. 定义测试方法:可以独立运行

                被测试的方法名:       add()      

        对应的测试方法名: testAdd()  

                    建议测试方法的返回值是void, 参数列表是空参

        3. 在方法上加 @Test 注解

        4. 在 @Test 注解上按 Alt+Enter, 选择 "Add 'JUnit4' to Classpath" 导入JUnit依赖环境

        5. 在方法名上右键, 选择 "Run '方法名()'"

            

判定结果:

        红色:失败

        绿色:成功.(测试通过)

       

断言: Assert

        使用断言操作来判断结果是否符合预期:



                Assert.assertEquals(期望的结果, 运算的结果);



                如果 期望的结果 和 运算的结果 相等, 则认为测试通过, 否则测试失败

       

测试失败的原因提示:

    java.lang.AssertionError:

    Expected :1    (表示我期望得到的是1)

    Actual   :-1   (但是实际得到的是-1)

三    JUnit: @Before, @After

     @Before: 修饰的方法会"在每个测试方法执行 之前"被执行

@After:  修饰的方法会"在每个测试方法执行 之后"被执行

注意:

        @Before, @After 修饰的方法可以有多个, 但是谁先执行是由JUnit内部来决定的, 没有明显的规律

        所以不要写多个@Before, @After 修饰的方法

四 反射

  概述:   将类的各个组成部分, 封装为其他对象, 这就是反射机制

        成员变量(字段): Field类的对象

        构造方法: Constructor类的对象

        成员方法: Method类的对象

        好处:

                (1). 可以在程序运行过程中, 操作这些对象

                (2). 可以解耦, 提高程序的可扩展性

file:///G:/CloudNotes/627285191@qq.com/365330a124ab47a6a5db35251d0a5a2d/%25E5%25AD%2597%25E8%258A%2582%25E7%25A0%2581.jpg

1  获取字节码对象的3中方式

     (1)Class.forName("全类名")

                将字节码文件加载进内存,返回Class对象

                适用场景: 多用于配置文件,将类名定义在配置文件中. 读取文件, 加载类

  (2)类名.class                         .

                通过类名的属性class获取

                适用场景: 多用于参数的传递  getConstructor(String.class, int.class)

  (3) 3. 对象.getClass()

                getClass()方法在Object类中定义

                适用场景: 多用于对象的获取字节码的方式 p.getClass()

五 Class的方法概述

   Class(T) 类:表示一个类的字节码对象,其中包含该类中定义的内容

成员变量

         Field[] getFields(): 获取所有 public 的成员变量

        Field getField(String name): 获取指定名称的 public 的成员变量

        Field[] getDeclaredFields(): 获取所有的成员变量, 不考虑权限修饰符

        Field getDeclaredField(String name): 获取指定名称的成员变量, 不考虑权限修饰符

构造方法

     Constructor<?>[] getConstructors(): 获取所有 public 的构造方法

        Constructor<T> getConstructor(Class<?>... parameterTypes): 获取指定的 public 构造方法

        Constructor<?>[] getDeclaredConstructors(): 获取所有的构造方法, 不考虑权限修饰符

        Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes): 获取指定的构造方法, 不考虑权限修饰符

成员方法

     Method[] getMethods(): 获取所有 public 的成员方法

        Method getMethod(String name, Class<?>... parameterTypes) : 获取指定的 public 成员方法

        Method[] getDeclaredMethods(): 获取所有的成员方法, 不考虑权限修饰符

        Method getDeclaredMethod(String name, Class<?>... parameterTypes): 获取指定的成员方法, 不考虑权限修饰符

Class对象代表的类的全类名

   String getName(): 获取当前Class对象代表的类的全类名

  创建对象

      T newInstance(): 使用当前类的空参构造, 创建一个对象

六  注解

     概念:说明程序的。给计算机看的

     作用分类:

              1. 编写文档: 通过代码里标识的注解生成文档

                (生成API文档 @author @version @since @param @return)

        2. 代码分析: 通过代码里标识的注解对代码进行分析 (使用反射)

        (JUnit提供的 @Test @Before @After)

        3. 编译检查: 通过代码里标识的注解让编译器能够实现基本的编译检查

                (@Override @FunctionalInterface)

七 JDK内置注解

    JDK中预定义的一些注解:

        @Override: 检测被该注解标注的方法是否是"重写"父类(接口)的

        @Deprecated: 该注解标注的内容,表示已过时

        @SuppressWarnings: 压制警告. 一般传递参数all  @SuppressWarnings("all")

八 自定义注解:格式和本质

   格式:    publci   @interface 注解名称{

属性(接口中的抽象方法)

}

   本质:注解本质上就是一个接口,该接口默认继承Annotation接口

十 枚举

    枚举:

        enum, enumeration. JDK 1.5 引入

        主要是用于定义一些"相关的"常量, 比如星期, 颜色, 用来进行区分



枚举定义方式:

public enum 枚举名 {

    枚举常量1, 枚举常量2, 枚举常量3;

}

使用方式:

枚举名.常量名

十一 自定义注解:属性定义

      属性:接口中的抽象方法

     属性返回值类型

          基本数据类型

            String

            枚举

            注解

           以上类型的数组

十二 元注解

       常用元注解:

        @Target: 描述注解能够作用的位置

                ElementType枚举的常用取值:

                        TYPE:可以作用于类上

                        METHOD:可以作用于方法上

                        FIELD:可以作用于成员变量上

                示例: @Target(value = {ElementType.TYPE, ElementType.METHOD})

        @Retention: 描述注解被保留的阶段

                RetentionPolicy枚举的取值:

                        SOURCE: 保留到源代码阶段

                        CLASS: 保留到类对象阶段

                        RUNTIME: 保留到运行时阶段

                示例: @Retention(RetentionPolicy.RUNTIME):保留注解到class字节码文件中并被JVM读取到

        @Documented: 加上后, 当前注解会被抽取到api文档中

        @Inherited: 加上后, 当前注解会被子类继承

十三  解析注解

         获取注解属性值的步骤:

        1. 获取注解定义位置的对象 (Class对象(类注解), Field对象(成员变量注解), Method对象(方法注解))

        2. 调用 ProAnno a = cls.getAnnotation(ProAnno.class) 方法获取注解对象

        3. 通过注解对象调用抽象方法获取属性值

     格式:

           注解类型 注解变量名 = 被注解的类.class.getAnnotation(注解名.class);

    数据类型 变量名 = 注解变量名.抽象方法();



   

1 个回复

倒序浏览
一个人一座城0.0 来自手机 中级黑马 2018-12-2 20:54:53
沙发
到此一观
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马