美文网首页
BD1 - Java 1-4 周五总结

BD1 - Java 1-4 周五总结

作者: hongXkeX | 来源:发表于2017-07-28 09:38 被阅读20次

    上午小组总结:

    关于收获:

    面试时考查:

    • Java基础
    • 逻辑思维
    • 读代码能力
    • 写代码能力(编程题)
    • 算法题

    学习过程中 要从网上找题刷题!
    看公司的需求 去实习看需求 再去学习更多的知识

    对于Person类:

    public class Person{
        // 定义了两个成员变量
        public String name;
        public int age;
        // 定义了一个say方法
        public void say(String content){
            System.out.println(content);
        }
    }
    

    类是一种引用数据类型,因此程序中定义的Person类型的变量实际上是一个引用,它被存放在栈内存中,指向实际的Person对象;而真正的Person对象则存放在堆(heap)内存中

    // 定义p变量的同时并为p变量赋值
    Person p = new Person();
    // 访问p的name实例变量,直接为该变量赋值
    p.name = "暗影";
    // 调用p的say()方法,声明say()方法时定义了一个形参
    // 调用该方法必须为形参指定一个值
    p.say("Java 从入门到放弃");
    // 直接输出p的name实例变量,将输出暗影
    System.out.println(p.name); 
    

    对应:

    0.png

    数组在内存中的运行机制:
    我们知道数组变量属于引用数据类型

    数组是一种引用数据类型.png

    比较重点说明
    先来看代码:(尝试自己理解下)

    重点.png

    若有不清楚请看下面的解释:

    先来了解下数组在内存中的运行机制:
    我们知道数组变量属于引用数据类型

    数组是一种引用数据类型.png

    数组元素和数组变量在内存里是分开存放的!

    数组只是一个引用类型的变量,因此使用它定义一个变量时,仅表示定义了一个引用变量(也就是定义了一个指针) 这个引用变量可以指向任何有效的内存。

    只有当该引用指向有效内存后,才可以通过该数组变量来访问数组元素。

    引用变量是访问内存中真实对象的根本方式,
    也就是说,与所有引用变量相同,如果希望在程序中访问数组对象本身,则只能通过这个数组的引用变量来访问它。

    实际的数组对象被存放在堆(heap)内存中,而引用该数组对象的 数组引用变量(要是一个局部变量)被存储在栈(stack)内存中。

    堆栈内存.png

    即栈内存中的引用变量指向堆内存中的对象!

    再来看一下创建数组对象区别:

    int[] a = {1,2,3};
    int[] b = new int[] {1,2,3};
    int[] c = a;
    int[] d = a.clone();
    

    首先注意:

    int[] a = {1,2,3};
    

    int[] b = new int[] {1,2,3};
    

    都是数组的静态初始化方式,int[] a = {1,2,3}; 是 int[] b = new int[] {1,2,3}; 的简化形式。
    (另外注意 只有在定义数组的同时执行数组初始化才支持使用简化的静态初始化形式)

    int[] a = {1,2,3};
    int[] b = new int[] {1,2,3};
    

    后内存中引用指向:


    内存中指向.png

    (注意a,b指向不同的堆内存对象)

      int[] c = a;
    

    完成的动作是: 在栈中创建c引用变量 c指向 (a指向的对象):


    c指向.png

    再来看这个

      int[] d = a.clone();
    

    先看java doc 文档的说明:


    clone()说明.png

    即clone()解释为:返回一个实例(instance)的克隆,即:


    d.png

    创建数组对象说明完成,再来看比较的区别:
    首先要知道:原始基本数据类型的变量之间的==与!=所做的是相等性比较——值是否相等,而引用数据类型变量之间的==与!=做的是同一性比较——是否指向同一对象。
    所以数组作为引用数据类型 == 判断的是同一性比较(是否指向同一对象)

    数组自身的equals() 函数 和 == 一样,也比较 两者是否指向同一对象:


    equals().png

    且又因为:


    内存.png

    所以前两种比较结果一致:


    前两种比较结果.png

    再来看最后一种比较方式:(Arrays.equals(a,b),即Java8 提供的增强工具类Arrays)


    Arrays.equals(a,b).png

    可见Arrays.equals(a,b)比较的是内容相等,若内容一样则返回true

    老师还让练习了自己写equals() 函数,要求比较数组内容,并且不考虑数组元素顺序(即认为{1,2,3}和{2,1,3}相等)
    下面是我的代码和测试:

    public class Test2 {
    
        public static boolean equals(int[] a, int[] b) {
            if(a.length != b.length) {
                return false;
            }else{
                BubbleSort(a);
                BubbleSort(b);
                for(int i=0; i<a.length;++i){
                    if(a[i] != b[i]) return false;
                }
            }
            return true;
        }
        
        public static void BubbleSort(int[] a) {
            int temp;
            for(int i=0;i<a.length-1;++i) {
                for(int j=0;j<a.length - i - 1;++j) {
                    if(a[j] > a[j+1]) {
                        temp = a[j];
                        a[j] = a[j+1];
                        a[j+1] = temp;
                    }
                }
            }
        }
        
        public static void main(String[] args) {
            int[] a = {1,2,3};
            int[] t = {2,1,3};
            
            System.out.println("自己写的equals函数测试: " + equals(a, t));      
        }
    }
    
    

    控制台结果:
    自己写的equals函数测试: true

    练习了冒泡排序算法:

    public class BubbleSort {
        public static void main(String[] args) {
            int[] a = {3,2,6,7,8,1,22,55,66};
            int temp;
            for(int i=0;i<a.length-1;++i) {
                for(int j=0;j<a.length - i - 1;++j) {
                    if(a[j] > a[j+1]) {
                        temp = a[j];
                        a[j] = a[j+1];
                        a[j+1] = temp;
                    }
                }
            }
    
            for(int i:a) {
                System.out.println(i);
            }
        }
    }
    

    关于更多算法与数据结构请关注我的文集:
    C/C++ java 算法与数据结构
    (后续我会更新常用算法及数据结构的思想及其C++和Java源码实现)

    关于拓展:

    自己已经过了一遍Linux:
    Ubuntu-server-64:
    学习了一些常用命令
    (很多记不住 需要下来多用多记忆)

    但是设置静态IP出现问题,正在查找解决方法:


    QQ图片20170728093211.png

    桌面设置静态失败:


    1.png

    Hadoop:

    0 分布式
    由分布在不同主机上的进程协同在一起,才能构成整个应用。
    (同一台主机上的不用进程,他们之间的交互也属于分布式)

    1 海量数据

    • 1 byte = 8bit
    • 1024 B = 1 M
    • 1024 M = 1 G
    • 1024 G = 1 T
    • 1024 T = 1 P
    • 1024 P = 1 E
    • 1024 E = 1 Z
    • 1024 Z = 1 Y
    • 1024 Y = 1 N

    2 存储(大数据需要解决的问题1)

    • 分布式存储

    3 计算 (大数据需要解决的问题2)

    • 分布式计算

    4 hadoop (大象)

    • 创始人Doug Cutting
    • Apache 开源软件
    • 计算框架(分布式、可靠、可伸缩)
      reliable, scalable, distributed
      可伸缩指的是 扩容 (随时增加或减少节点)
    • 搜索引擎、海量数据存储

    赵老师总结:

    • 以后总结要展示一些代码(可以现场敲代码)
    • 要提出问题 尝试解决

    下午学习:

    包装类的享元模式:
    顾名思义:共享元对象。如果在一个系统中存在多个相同的对象,那么只需要共享一份对象的拷贝,而不必为每一次使用创建新的对象。
    享元模式是为数不多的、只为提升系统性能而生的设计模式。它的主要作用就是复用对象,以节省内存空间和对象创建时间。

    享元模式.png

    (num 和 num1共享内存,1和2不共享内存)

    总结常用包装类中的常用方法:


    Integer

    String类的常用方法:

    String类的常用方法 String类的常用方法.png 5.png 6 compareTo compareToIgnoreCase

    ASCII码大小写字母相差32 !!!

    substring trim

    ** replace : **


    replace

    replace 可去除一个字符串中所有的空格
    (中文和半角的中文不一样)

    Debug技巧:

    • 打印
    • logger (可控制打印的级别)
    • debug调试(设置断点)

    复习:

    final关键字:

    • 修饰类,不能被继承
    • 修饰方法,不能覆盖
    • 修饰变量,为常量

    方法覆盖操作:

    • 静态覆盖静态,非静态覆盖非静态,静态性约束性保持一致
    • 覆盖方法时,权限可以放大,但不可以缩小

    类的成员:

    • 成员变量
    • 成员函数
    • 构造代码块
    • 静态代码块
    • 另一个类

    内部类:

    • 定义在类内部的类称为内部类
    • 内部类可以在类的成员位置上(方法外)
    • 内部类也可以在方法内定义
    • 从内部类引用的本地变量必须是最终变量或实际上的最终变量(虽然Java8已经不要求内部类访问的局部变量声明时必须加final修饰,但是内部类内部中绝不能改变局部变量的值)

    内部类示例1: (函数外)

    public class Test {
       public static void main(String[] args) {
           Benz benz = new Benz();
           benz.run();
       }
    }
    
    class Benz {
       String color;
       int tires;
       
       public void run() {
           Engine e = new Engine();
           e.fire("Key0001");
           System.out.println("run...");
       } 
       
       class Engine {
           public void fire(String key) {
               System.out.println("key ready : " + key);
               System.out.println("fires...");
           }
       }
    }
    
    输出:
    key ready : Key0001
    fires...
    run...
    

    内部类示例2: (函数内)

    public class Test {
        public static void main(String[] args) {
            Benz benz = new Benz();
            benz.run("key888..");
        }
    }
    
    class Benz {
        String color;
        int tires;
        
        public void run(String key) {
            
            class Engine {
                public void fire() {
                    System.out.println("key ready : " + key);
                    System.out.println("fires...");
                }
            }
            
            Engine e = new Engine();
            e.fire();
            System.out.println("run...");
        } 
    }
    

    内部类引用的本地变量必须是最终变量:

    class Benz {
        String color;
        int tires;
        
        public void run(String key) {
            int k1 = 11111;
            int k2 = 22222;
            
            class Engine {
                k1 = 33333;
                public void fire() {
                    k2 = 44444;
                    System.out.println("key ready : " + key);
                    System.out.println("fires...");
                }
            }
            
            Engine e = new Engine();
            e.fire();
            System.out.println("run...");
        } 
    }
    

    k1 k2都错误: (把k1注释掉 k2也报错)

    k1 k2都错误

    (可以把内部类理解为黑箱,若黑箱在里面改变局部变量的值,则内部类外边的可能会受影响)

    抽象类:

    • 抽象定义

      • 抽象就是从多个实物中讲共性,本质的内容抽取出来(例如,狼和狗共性都是犬科,犬科就是抽象出来的概念)
    • 抽象类

      • Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类。

      • 若函数没有方法体,那么它必须是抽象的(即加abstract关键字),并且抽象方法必须在抽象类中。

      • 抽象类中可以没有抽象方法

      • 抽象类不能实例化

      • 抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类。

    //抽象类
    abstract class Animal {
        // 抽象方法
        abstract public void cry();
    }
    

    抽象类不能实例化:


    抽象类不能实例化

    抽象类通过其子类实例化:

    public class Test{
        public static void main(String[] args){
            // 不能实例化 Animal
            // Animal a = new Animal();
            
            Dog d = new Dog();
            d.cry();
        }
    }
    
    //抽象类
    abstract class Animal{
        // 抽象方法
        abstract public void cry();
    }
    
    class Dog extends Animal{
        // 实现抽象方法
        public void cry(){
            System.out.println("汪汪...");
        }
    }
    
    • 抽象类继续
      • 抽象类虽不能直接实例化,但是有构造函数!

    思考:抽象关键字abstract不可以和哪些关键字共存?
    回答问题前先总结以下关键字:

    • private (先不考虑修饰类)

      • 不能被继承
      • 不能被访问
    • final

      • 修饰类 不能被继承
      • 修饰方法 不能被覆盖
      • 修饰成员变量 不能被改变(为常量)
    • abstract(可以修饰方法 和 类)

      • 抽象类不能实例化,只能被继承
      • 抽象方法 子类必须实现
    • static

      • 和对象无关,只和类有关

    非法修饰组合:

    • private + abstract
    • final + abstract

    相关文章

      网友评论

          本文标题:BD1 - Java 1-4 周五总结

          本文链接:https://www.haomeiwen.com/subject/jrkxlxtx.html