精华内容
下载资源
问答
  • 操作系统常见面试题

    2021-02-28 15:17:20
    文章目录1、进程线程的联系与区别联系区别2、为什么需要线程3、线程的类型用户级线程内核级线程4、并发并行5、进程的状态6、进程调度算法①先来先服务 FCFS②短作业优先 SJF③最短剩余时间优先算法④时间片...

    未更新完毕 仅用来个人学习

    1、进程和线程的联系与区别

    进程:进程是一个有特定功能的程序在某个数据集合上的一次运行。
    线程:线程是系统调度的最小单位,包含在进程之中。

    联系
    进程可以有多个线程,最少包含一个线程,即主线程。一个线程只能属于一个进程。
    线程是进程执行的实体。

    区别
    1、进程是资源分配的最小单位。进程拥有资源,而线程不拥有资源,但是进程中的多个线程可以共享所属进程中的资源。

    2、线程是系统调度的最小单位。

    3、进程的创建或撤销,系统需要为它分配或者回收资源,开销远大于线程的创建或撤销。进程间的切换需要保存当前CPU环境还需要配置新的CPU环境,而线程切换只需要保存和设置少量寄存器,开销很小。

    4、进程的崩溃不会引起其他进程的崩溃,而线程的崩溃,会引起整个进程的崩溃。

    线程占有的都是不共享的,其中包括:栈、寄存器、状态、程序计数器
    线程间共享的有:堆,全局变量,静态变量;



    2、为什么需要有线程

    1.因为进程执行过程中会因为阻塞而导致整个进程挂起,比如等待输入,即使进程中有些不依赖这个资源的工作,仍然不会执行。线程的引入能减少时空开销,更好的实现并发。
    2.线程的创建和销毁,只需要保留线程自己的栈区和少量寄存器,而进程的创建和销毁远远大于线程的开销



    3、线程的类型

    用户级线程
    这些线程的管理的所有工作都由应用程序完成。执行一个应用程序,操作系统会为该应用程序分配进程号、内存空间等资源。然后会在一个线程上运行这个应用程序,这个线程就是主线程。
    优点是非常高效,因为不需要进入内核空间,但是不能很好的实现并发

    内核级线程
    这类线程的管理的所有工作都由内核完成。应用程序不能够进行线程管理,只能够调用内核对外开放的该线程的接口。
    优点是内核可以讲不同线程分配给不同CPU,更好的实现并发,但是效率不高,因为需要在用户态和系统态之间不断切换。



    4、并发和并行

    并发是指在一段时间内,多个任务都在执行,也就是宏观上看是同时进行的,但是微观上其实同一时刻只有一个任务在执行。多个任务交替执行,交替时间非常快,所以宏观上看起来是同时的。

    并行是真正的实现了物理上的同时执行。在同一时刻多个任务同时执行。



    5、进程的状态

    就绪、阻塞、执行

    就绪->执行:在就绪队列中等待进入执行状态
    执行->就绪:时间片用完了,进入就绪
    执行->阻塞:因为一些资源等待阻塞了,比如等待IO输入
    阻塞->就绪:等待的条件已经满足



    6、进程调度算法

    ①先来先服务 FCFS
    按照进程进入就绪队列的顺序,从队列头开始处理进程,利于长作业,不利于短作业。
    短作业可能会因为前面长作业运行之间太长而饿死。

    ②短作业优先 SJF
    按照运行时间最短排序,然后开始执行,是一种抢占式的调度算法
    利于短作业,长作业可能会被饿死

    ③最短剩余时间优先算法
    当一个新的进程满足执行条件时候,和当前之前运行的进程,进行剩余时间比较,剩余时间较短的先执行。

    ④时间片轮转
    按照FCFS算法排成一个队列,每个进程都统一执行一个时间片,没执行完的进程加入队尾。
    时间片如果太大,大到超过就绪队列中进程的最大执行时间,就退化成FCFS
    如果时间片太小,那么需要不断进行进程之间的切换,开销非常大

    ⑤优先级算法
    对进程进行优先级编号,优先级高的优先,对于一直等待的进程,可以适当提高优先级,防止被饿死。

    ⑥多级反馈队列
    是对时间片轮转算法的一种改进,每个队列维护一个不同的时间片轮转时间。1、2、4、8…
    每次从当前队列执行完时间片时间后,如果还没运行后,就加入下一个队列中,就是提高了时间片。
    如果一个进程需要用时间片轮转七次,用多级反馈队列只需要三次,减少了进程切换的次数,减少开销。



    7、上下文切换

    这是一个超链接

    上下文切换指内核在CPU上对进程或者线程进行切换。

    上下文切换有三个步骤:
    ①保存上一个CPU的上下文
    ②将新任务的上下文加载到CPU(CPU寄存器和程序计数器)
    ③跳转到新任务的程序计数器所指的新指令

    上下文被保存在系统内核


    系统调用
    进程的运行空间分为用户空间内核空间
    在用户空间运行的进程叫做用户态,在内核空间运行的叫做内核态(系统态)

    从用户态到内核态需要经过系统调用
    系统调用会发生CPU上下文切换,先保存用户态状态,然后加载内核态内容。系统调用结束后,在加载回用户态状态。一次系统调用,会有两次CPU上下文切换


    进程上下文切换
    进程是由内核管理和调度的,进程的切换只能发生在内核态
    进程的上下文不但包括虚拟内存、栈、全局变量等用户空间资源,还包括内核堆栈、寄存器等内核空间状态。


    线程上下文切换
    线程上下文切换时,共享相同的虚拟内存和全局变量等资源不需要修改。而线程自己的私有数据,如栈和寄存器等,上下文切换时需要保存。


    线程上下文切换为什么比进程快
    这是一个超链接

    每个进程都有自己的虚拟地址空间,进程内的所有线程共享进程的虚拟地址空间。进程切换涉及虚拟地址空间的切换而线程不会。



    8、虚拟内存

    虚拟内存的目的是为了让物理内存扩充成更大的逻辑内存,从而让程序获得更多的可用内存。虚拟内存使用部分加载的技术,让一个进程或者资源的某些页面加载进内存,从而能够加载更多的进程,甚至能加载比内存大的进程,这样看起来好像内存变大了,这部分内存其实包含了磁盘或者硬盘,并且就叫做虚拟内存。

    虚拟内存,页表,快表,多级页表,倒排页表



    9、分页和分段

    这是一个超链接


    10、页面置换算法

    这是一个超链接

    先进先出算法(First in first out,FIFO) :将在内存中最久的的页面淘汰
    最近最久未使用算法(Least Recently used,LRU):将最久没使用的淘汰
    最不常用算法(Least Frequently Used,LFU):·将内存中页面使用次数最少的给淘汰掉



    11、死锁

    死锁
    指一个进程集合中的每个进程,都在等待该集合中的其他进程释放资源所形成的僵局,若无外力推进将无法继续执行。

    根本原因
    系统资源不足,导致资源不够分配。

    四个必要条件
    1.占有和等待,进程占有资源,并且等待剩下所需要的资源
    2.互斥,资源要么被分配给了一个进程,要么未分配
    3.不可抢占,不能进行抢占式的占有资源
    4.环路等待,每个进程都在等待其他进程释放资源为自己所用

    解决方法
    1.鸵鸟策略:忽略死锁的发生,当死锁发生的概率很低或者不会造成什么影响的时候选择忽略它。因为解决死锁的成本可能很高。
    2.死锁预防:指破坏死锁的必要条件

    • 破坏互斥,让多个进程同时访问资源
    • 破坏占有和等待,一次性申请所需要的全部资源
    • 破坏不可抢占,抢占式占有资源
    • 破坏环路等待,必须按顺序请求资源

    3.死锁的避免:采用银行家算法:假设将资源分配给进程P1后,最后所有的进程都能够得以释放资源,那么就分配给它

    4.死锁的检测与修复



    12、磁盘调度算法

    这是一个超链接
    上述博客讲的很好,推荐阅读

    1.先来先服务 FCFS
    2.最短寻道时间优先算法 SSTF
    3.扫描算法(电梯算法) SCAN
    4.循环扫描算法 C-SCAN
    5.LOOK调库和C-LOOK调度(其实就是扫描算法和循环扫描算法的优化,每次不需要到磁盘边缘,而是到最远的请求地方即可)



    13、进程间通信方式

    这是一个超链接

    无名管道、有名管道、消息队列、信号量、信号、共享内存、套接字

    共享内存是最快的通信方式、而套接字是最常用的通信方式,它可以实现不同主机的进程通信



    14、进程间同步方式



    15、中断

    这是一个超链接

    中断是指CPU对系统发生的某个事件做出的一种反应,CPU暂停正在执行的程序,保存现场后自动去执行相应的处理程序,处理完该事件后再返回中断处继续执行原来的程序。中断一般三类,一种是由CPU外部引起的,如I/O中断、时钟中断,一种是来自CPU内部事件或程序执行中引起的中断,也叫异常,例如程序非法操作,地址越界、浮点溢出、缺页中断,最后一种是在程序中使用了系统调用引起的。而中断处理一般分为中断响应和中断处理两个步骤,中断响应由硬件实施,中断处理主要由软件实施。

    展开全文
  • java面试宝典

    2013-02-28 16:04:01
    8、int Integer 有什么区别? 9 9、&&&的区别? 9 10、简述逻辑操作(&,|,^)与条件操作(&&,||)的区别? 9 11、heap stack 有什么区别? 9 12、Math.round(11.5) 等于多少? Math.round(-11.5)等于多少? 9 13、...
  • 千方百计笔试题大全

    2011-11-30 21:58:33
    8、int Integer 有什么区别? 9 9、&&&的区别? 9 10、简述逻辑操作(&,|,^)与条件操作(&&,||)的区别? 9 11、heap stack 有什么区别? 9 12、Math.round(11.5) 等于多少? Math.round(-11.5)等于多少? 9 13、...
  • oc总结第四讲:属性

    2015-11-03 19:42:00
    实例变量属性是一个包含关系,实例变量中包含属性,而属性是作为实例变量的子集 这种情况是需要为您举例子的,比如 汽车 是一个类(一个集合) 1.您指出了一辆特定的车(请注意,这里是指的单个的一辆车),那么这辆...

    一、学习属性我们首先要对属性有一个清晰地认识,什么是属性?属性和我们熟知的实例变量有用什么区别呢??

         实例变量和属性是一个包含关系,实例变量中包含属性,而属性是作为实例变量的子集
         这种情况是需要为您举例子的,比如 汽车 是一个类(一个集合)
          1.您指出了一辆特定的车(请注意,这里是指的单个的一辆车),那么这辆车属于 汽车 这个类,这辆车您就可以理解为是汽车这个类的实例变量(指出了一个例子,实例也可以叫做 对象 )
          2.而您可以看到这辆车的颜色、车轮、发动机等等的车身上的部件,我们就可以称这些部件为 属性。
          3.而汽车是如何发动的,如何跑的,关于这些 我们可以称作它们是这辆车的方法,当然所有的车都可以发动,都可以跑,所以这些方法也是属于汽车的这个类(集合的)
          如果用程序的角度编写的话,比如您设置了一个父类是NSObject的自定义类,就叫做Car
    那么这个Car中,您可以通过在头文件用@property或者大括号'{}'直接声明一些变量,比如颜色、厂家等等,这些用@property或者大括号声明的变量称作Car这个类的属性
    而您进入主程序,设置一个Car类的变量,并声明了一个内存空间给它
                                             Car * instanceCar = [[Car alloc]init];
    那么这个"instanceCar"就是一个 实例对象(也是一个变量),这个变量是属于Car这个类的,所以这个变量可以使用Car类中所有的属性,也就是说,您可以用instanceCar.某属性的方法直接为这些变量赋值,而赋值后instanceCar这个变量就是一个独一无二的变量,是一个已经具体化的汽车的例子,所以称作实例对象(变量).

    二、了解了什么是属性后,我们要学习为什么用属性?属性有什么作用?
          我们通过声明属性(@property)来摆脱繁琐的setter和getter方法的创建。@property声明与实现文件中的另一个声明@sythesize相结合,来完成setter和getter方法的创建。@property生成设置器和访问器方法的声明,@synthesize 生成设置器和访问器方法的实现。
    注意:只有当访问器不存在的时候, @synthesize才会自动生成访问器,所以,即使是使用 @synthesize声明了一个属性,你仍然可以实现自定义的getter和setter。
    属性是设置实例变量的方法,也是获取实例变量的方法。

    三、属性注意事项

     1、当属性名和成员变量名一样时,如果我们想保证成员变量有值,那么就需要在.m中加入@synthesize 变量名
     2、当属性名和成员变量名一样时,如果我们对成员变量的值不强求,但我们又想打印赋上的值,这时在.m里可以使用_属性名 或者 self.属性名
     3、当定义一个属性时,会首先查找是否有以_属性名命名的成员变量,如果有,则默认对其进行set和get,如果没有,则隐式生成以_属性名命名的变量
     4、当我们使用属性时,成员变量可以省略
    程序如下:
    #import <Foundation/Foundation.h>
    #import "Person.h"
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            Person *p = [[Person alloc] init];
            p.name = @"王三";//默认调用name的set方法
            NSLog(@"==%@",p.name);//默认调用get方法
            [p sayHi];
        }
        return 0;
    }
     1、当属性名和成员变量名一样时,如果我们想保证成员变量有值,那么就需要在.m中加入@synthesize 变量名
    #import <Foundation/Foundation.h>
    @interface Person : NSObject{
        NSString *name;//对应注意1
    }
    //属性的关键字,属性帮我们封装了set和get方法
    @property (nonatomic, strong) NSString *name;
    @property (nonatomic, assign) int a;
    -(void)sayHi;
    @end
     
    #import "Person.h"
    @implementation Person
    //@synthesize name;
    -(void)sayHi{
        NSLog(@"我是%@",name);
    }
    @end
     
    //2、当属性名和成员变量名一样时,如果我们对成员变量的值不强求,但我们又想打印赋上的值,这时在.m里可以使用_属性名 或者 self.属性名
    #import <Foundation/Foundation.h>
    @interface Person2 : NSObject{
        NSString *name;
    }
    @property NSString *name;
    -(void)sayHi;
    @end
     
    #import "Person2.h"
    @implementation Person2
    -(void)sayHi{
        NSLog(@"--%@",_name);
        NSLog(@"--%@",self.name);
    }
    @end
     
    //3、当定义一个属性时,会首先查找是否有以_属性名命名的成员变量,如果有,则默认对其进行set和get,如果没有,则隐式生成以_属性名命名的变量
    #import <Foundation/Foundation.h>
    @interface Person3 : NSObject{
        NSString *_nam8e;
    }
    @property NSString *name;
    -(void)sayHi;
    @end
     
    #import "Person3.h"
    @implementation Person3
    -(void)sayHi{
        NSLog(@"--%@",_name);
        NSLog(@"--%@",self.name);
    }
    @end
     
    //4、当我们使用属性时,成员变量可以省略
    #import <Foundation/Foundation.h>
    @interface Person4 : NSObject
    @property NSString *name;
    -(void)sayHi;
    @end
     
    #import "Person4.h"
    @implementation Person4
    -(void)sayHi{
        NSLog(@"--%@",_name);
        NSLog(@"--%@",self.name);
    }
    @end

    转载于:https://www.cnblogs.com/qing92/p/4934170.html

    展开全文
  • 4.1.3 ArrayListLinkedList有什么区别。 4.1.4 讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,当new的时候,他们的执行顺序。 4.1.5 用过哪些Map类,都有什么区别,...
  • JavaScript对象

    2021-01-20 18:19:12
    对象的属性普通的 javascript 变量基本没什么区别,仅仅是属性属于某个对象。 属性定义了对象的特征 可以通过点符号或者方括号访问或者设置一个对象的属性 对象的名字(可以是普通的变量)属性的名字都是大小写...

    1、概述

    • 一个对象就是一系列属性的集合
    • 一个属性包含一个名和一个值
    • 一个属性的值可以是函数,该属性也被称为方法

    2、对象和属性

    • 一个 javascript 对象有很多属性。
    • 一个对象的属性可以被解释成一个附加到对象上的变量。
    • 对象的属性和普通的 javascript 变量基本没什么区别,仅仅是属性属于某个对象。
    • 属性定义了对象的特征
    • 可以通过点符号或者方括号访问或者设置一个对象的属性
    • 对象的名字(可以是普通的变量)和属性的名字都是大小写敏感
    • 对象中未赋值的属性的值为undefined,而不是null
    var myCar = new Object();
    myCar.make = "Ford";
    myCar.model = "Mustang";
    myCar.year = 1969; 
    
    myCar["make"] = "Ford";
    myCar["model"] = "Mustang";
    myCar["year"] = 1969;
    

    3、枚举一个对象的所有属性

        class Parent {
            constructor(name) {
                this.name = name;
                this.height = name;
            }
            say() {}
        }
        class Child extends Parent {
            constructor(name, age) {
                super(name);
                this.age = age;
            }
            say() {}
        }
        Child.prototype.sex = "1";
        const child = new Child("child", 10);
        console.log(child);
    

    3.1 ES5 之前 getOwnPropertyNames

       <!-- ES6之前 -->
        function listAllProperties(o, isEnumerable = false) {
            //获取所有属性,包含原型链
            let objectToInspect;
            let result = [];
            for (
                objectToInspect = o;
                objectToInspect !== null;
                objectToInspect = Object.getPrototypeOf(objectToInspect)
            ) {
                result = result.concat(Object.getOwnPropertyNames(objectToInspect));
            }
            //数组元素去重
            const newRes = [];
            result.forEach((item) => {
                if (newRes.indexOf(item) === -1) {
                    if (isEnumerable === true) {
                        //保留不可枚举属性
                        newRes.push(item);
                    } else {
                        //不保留不可枚举属性
                        o.propertyIsEnumerable(item) && newRes.push(item);
                    }
                }
            });
            return newRes;
        }
        console.log("ES5之前:", listAllProperties(child, true));
        
        <!--//结果-->
        <!--["name", "height", "age", "constructor", "say", "sex", "__defineGetter__", "__defineSetter__", "hasOwnProperty", "__lookupGetter__", "__lookupSetter__", "isPrototypeOf", "propertyIsEnumerable", "toString", "valueOf", "__proto__", "toLocaleString"]-->
    

    3.2 for…in

    该方法依次访问一个对象及其原型链中所有可枚举的属性。

        const keys = [];
        for (let key in child) {
            keys.push(key);
        }
        console.log("for...in:", keys);
        <!--结果:["name", "height", "age", "sex"]-->
    

    3.3 Object.keys(o)

    该方法返回对象 o 自身包含(不包括原型中)的所有可枚举属性的名称的数组。

        console.log("Object.keys:", Object.keys(child));
        <!--结果:["name", "height", "age"]-->
    

    3.4 Object.getOwnPropertyNames(o)

    该方法返回对象 o 自身包含(不包括原型中)的所有属性(无论是否可枚举)的名称的数组。

         console.log(
            "Object.getOwnPropertyNames:",
            Object.getOwnPropertyNames(child)
        );
        <!--结果:["name", "height", "age"]-->
    

    4、创建新对象

    4.1 Object 构造函数

        <!--Object构造函数-->
        const obj1 = new Object();
        obj1.name = "zs";
        obj1.say = function () {
            console.log("obj1:", this.name);
        };
        obj1.say();
        console.log("obj1:", obj1);
    

    4.2 Object.create()

    创建一个新对象,使用现有的对象来提供新创建的对象的__proto__

        <!--Object.create函数-->
        // const obj2 = Object.create(obj1);
        // const obj2 = Object.create(Object.prototype);
        const obj2 = Object.create({});
        obj2.name = "zs";
        obj2.say = function () {
            console.log("obj2:", this.name);
        };
        obj2.say();
        console.log("obj2:", obj2);
    

    4.3 构造函数

    两步来创建对象:

    • 通过创建一个构造函数来定义对象的类型。首字母大写是非常普遍而且很恰当的惯用法。
    • 通过 new 创建对象实例。
        <!--构造函数-->
        function Person(name) {
            this.name = name;
            this.say = function () {
                console.log("obj3:", this.name);
            };
        }
    
        const obj3 = new Person("zs");
        obj3.name = "zs";
        obj3.say = function () {
            console.log("obj3:", this.name);
        };
        obj3.say();
        console.log("obj3:", obj3);
    

    4.4 字面量

        <!--字面量-->
        const obj4 = {};
        obj4.name = "zs";
        obj4.say = function () {
            console.log("obj4:", this.name);
        };
        obj4.say();
        console.log("obj4:", obj4);
    

    4.5 class 创建

        <!--class-->
        class People {
            constructor(name) {
                this.name = name;
            }
            say() {
                console.log("obj5:", this.name);
            }
        }
        const obj5 = new People("zs");
        obj5.name = "zs";
        obj5.say = function () {
            console.log("obj5:", this.name);
        };
        obj5.say();
        console.log("obj5:", obj5);
    

    5、原型

    • JavaScript 常被描述为一种基于原型的语言
    • 每个对象拥有一个原型对象,是隐藏属性
    • 对象以其原型为模板、从原型继承方法和属性。
    • 原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。
    • 这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。

    5.1 函数对象获取原型

    通过 prototype 属性访问原型。该属性定义在 Function 对象上。没有找到相关文档,但是可以通过以下验证

    Function.hasOwnProperty("prototype")
    //结果为 true
    
    • 每个 JavaScript 函数实际上都是一个 Function 对象实例
    • 构造函数也是函数
    function doSomething(){}
    console.log( doSomething.prototype );
    //var doSomething = function(){};
    //console.log( doSomething.prototype );
    
    

    输出结果为

    {
        constructor: ƒ doSomething(),
        __proto__: {
            constructor: ƒ Object(),
            hasOwnProperty: ƒ hasOwnProperty(),
            isPrototypeOf: ƒ isPrototypeOf(),
            propertyIsEnumerable: ƒ propertyIsEnumerable(),
            toLocaleString: ƒ toLocaleString(),
            toString: ƒ toString(),
            valueOf: ƒ valueOf()
        }
    }
    

    5.2 实例对象获取原型

    • __proto__属性,该方法从 Object.prototype 继承而来
    • Object.getPrototypeOf(obj)方法
    • obj.constructor.prototype,其中 constructor 方法从 Object.prototype 继承而来
    function People(){};
    const p = new People();
    console.log(p.__proto__)
    console.log(Object.getPrototypeOf(p))
    console.log(p.constructor.prototype)
    
    <!-- 结果-->
    <!--constructor: ƒ People()-->
    <!--__proto__:-->
    <!--constructor: ƒ Object()-->
    <!--hasOwnProperty: ƒ hasOwnProperty()-->
    <!--isPrototypeOf: ƒ isPrototypeOf()-->
    <!--propertyIsEnumerable: ƒ propertyIsEnumerable()-->
    <!--toLocaleString: ƒ toLocaleString()-->
    <!--toString: ƒ toString()-->
    <!--valueOf: ƒ valueOf()-->
    <!--__defineGetter__: ƒ __defineGetter__()-->
    <!--__defineSetter__: ƒ __defineSetter__()-->
    <!--__lookupGetter__: ƒ __lookupGetter__()-->
    <!--__lookupSetter__: ƒ __lookupSetter__()-->
    <!--get __proto__: ƒ __proto__()-->
    <!--set __proto__: ƒ __proto__()-->
    
    
    console.log(p.__proto__ === p.constructor.prototype)
    console.log(p.__proto__ === Object.getPrototypeOf(p))
    console.log(p.constructor.prototype === Object.getPrototypeOf(p))
    <!-- 结果-->
    <!--true->
    
    

    6、继承

    • JavaScript没有类,全是 ++对象++
    • 对象的原型叫 ++对象原型++
    • 通过对象创建的叫 ++对象实例++
    • 对象实例的原型是 ++对象原型++ 不是 ++对象++
    • 对象实例的初始属性来自 ++复制、初始化对象属性++ 和 ++继承对象原型/链属性++

    6.1 继承方式1:call

     //定义父类
        function People1(name) {
            //定义父类属性,每个实例对象值都一样,定义在对象上
            this.name = name;
        }
        //定义父类方法,每个实例对象执行方法一样,定义在原型上
        People1.prototype.say = function () {};
    
        //定义子类
        //1、实现属性拷贝和赋值
        function Student1(name, age) {
            //使用this调用父类构造函数,生成对象
            People1.call(this, name);
            //子类属性初始化赋值
            this.age = age;
        }
        //2、实现原型链指向
        /*
         * //不能直接指向父类原型,因为还要修改原型constructor指向,会破坏父类的原型链
         * Student1.prototype = People1.prototype;
         * */
        /*
         * //父类构造函数需要初始化参数,作为原型来讲还需要提供不必要的参数
         * Student1.prototype = new People1("");
         * */
        // 重新生成一个新的原型对象,防止子类父类原型链互相污染
        Student1.prototype = Object.create(People1.prototype);
        Student1.prototype.constructor = Student1;
    
        const people = new People1("ww");
        console.log("people:", people);
        console.log(
            "people.constructor.prototype:",
            people.constructor.prototype
        );
        People1.prototype.run2 = function () {};
        Student1.prototype.run3 = function () {};
        const student = new Student1("zs", 20);
        console.log("student:", student);
        console.log(
            "student.constructor.prototype:",
            student.constructor.prototype
        );
    

    6.2 继承方式1:extends

      class People2 {
            constructor(name) {
                this.name = name;
            }
            say = function () {};
        }
        class Student2 extends People2 {
            constructor(name, age) {
                super(name);
                this.age = age;
            }
        }
        const people2 = new People2("ww");
        console.log("people2:", people2);
        console.log(
            "people2.constructor.prototype:",
            people2.constructor.prototype
        );
        People2.prototype.run2 = function () {};
        Student2.prototype.run3 = function () {};
        const student2 = new Student2("zs", 20);
        console.log("student2:", student2);
        console.log(
            "student2.constructor.prototype:",
            student2.constructor.prototype
        );
    

    7、 Function 和 Object

    • Object.protype 是顶级原型对象
     //Object对象
        console.log("Object:", Object);
        console.log("-Object函数属性---");
        //Object函数原型
        console.log("Object.prototype:", Object.prototype);
        //Object函数原型的原型: 值为null
        console.log(
            "Object.prototype.__proto__:",
            Object.prototype.__proto__
        );
        console.log("-Object对象属性---");
        //Object对象-原型
        console.log("Object.__proto__:", Object.__proto__);
        //Object对象-原型-原型
        console.log(
            "Object.__proto__.__proto__:",
            Object.__proto__.__proto__
        );
        //Object对象-原型-原型 等于 Object.prototype
        console.log(
            "Object.__proto__.__proto__:",
            Object.__proto__.__proto__ === Object.prototype
        );
        //Object对象-原型-原型-原型 : 值为null
        console.log(
            "Object.__proto__.__proto__.__proto__:",
            Object.__proto__.__proto__.__proto__
        );
    
        console.log("-Object构造函数属性---");
        //Object对象-构造函数:Function
        console.log("Object.constructor:", Object.constructor);
    
        console.log("-Function构造函数属性---");
        //Function函数-原型
        console.log("Function.prototype:", Function.prototype);
        //Function函数-原型-原型
        console.log(
            "Function.prototype.__proto__:",
            Function.prototype.__proto__
        );
        //Function函数-原型-原型 等于 Object.prototype 等于 Object.__proto__.__proto__
        console.log(
            "Function.prototype.__proto__:",
            Function.prototype.__proto__ === Object.prototype
        );
        console.log("-Function对象属性---");
        //Function对象-原型
        console.log("Function.__proto__:", Function.__proto__);
        //Function对象-原型 等于 Function.prototype
        console.log(
            "Function.__proto__:",
            Function.__proto__ === Function.prototype
        );
    
        //Function对象-原型-原型
        console.log(
            "Function.__proto__.__proto__:",
            Function.__proto__.__proto__
        );
        //Function对象-原型-原型 等于Function.prototype.__proto__ 等于 Object.prototype 等于 Object.__proto__.__proto__
        console.log(
            "Function.__proto__.__proto__:",
            Function.__proto__.__proto__ === Function.prototype.__proto__
        );
    
        console.log("-Function构造函数属性---");
        console.log("Function.constructor:", Function.constructor);
        console.log(
            "Function.constructor:",
            Function.constructor.prototype
        );
        console.log(
            "Function.constructor:",
            Function.constructor.prototype === Function.__proto__
        );
    

    参考链接

    展开全文
  • JAVA面试题最全集

    2010-03-13 13:09:10
    37.classloader,JDK的API、Classpath的同web-inf的class加载方式有什么区别? 38.列举三种以上垃圾回收算法,并比较其优缺点? 39.编写代码实现一个线程池 40.描述一下JVM加载class文件的原理机制? 41....
  • 运行python3 -m uiautomator2 init安装包含httprpc服务的apk到手机+atx-agent, minicap, minitouch (在过去的版本,这一步是必须执行的,但是从1.3.0之后的版本,当运行python代码u2.connect()时就会自动推送这些...
  • 38.abstract classinterface有什么区别? 答: 声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类实现该类的情况。不能...
  • C#微软培训教材(高清PDF)

    千次下载 热门讨论 2009-07-30 08:51:17
    18.2 在 C #代码调用 C++ VB 编写的组件 .240 18.3 版 本 控 制 .249 18.4 代 码 优 化 .252 18.5 小 结 .254 第五部分 附 录 .255 附录 A 关 键 字.255 附录 B 错 误 码.256 附录 C .Net 名字空间...
  • C#微软培训资料

    2014-01-22 14:10:17
    18.2 在 C #代码调用 C++ VB 编写的组件 .240 18.3 版 本 控 制 .249 18.4 代 码 优 化 .252 18.5 小 结 .254 第五部分 附 录 .255 附录 A 关 键 字.255 附录 B 错 误 码.256 附录 C .Net 名字空间...
  • 数据的逻辑结构是对数据元素之间的逻辑关系的描述,它可以用一个数据元素的集合定义在此集合中的若干关系来表示。数据的逻辑结构两个要素:一是数据元素的集合,通常记为D;二是D上的关系,它反映了数据元素之间...
  • 数据字典是数据流图所有元素的定义的集合,一般由以下四类条目组成(C)。 A) 数据说明条目、控制流条目、加工条目、数据存储条目 B) 数据流条目、数据项条目、文件条目、加工条目 C) 数据源条目、数据流条目、...
  • 会计理论考试题

    2012-03-07 21:04:40
    15.下列软件属于系统软件的是 ___D__ 。 A、Windows B、Visual FoxPro C、UCDOS D、WPS97 16.应用软件在计算机普及起重要作用,下列 ___D__ 都属于应用软件。 A、WPS、DOS、Lotusl-2-3 B、WIndows95、Word、...
  • 19、队列有什么区别? 答: 队列先进先出;栈后进先出。 20、数组链表的区别? 答: 数组:数据顺序存储,固定大小; 链表:数据可以随机存储,大小可动态改变; 21、为什么数组名作为参数,会改变数组的内容,...
  • 4、 在软件生命周期,能准确地确定软件系统必须做什么和必须具备哪些功能的阶段()。 A、 概要设计 B、详细设计 C、可行性分析 D、需求分析 我的答案:B 5、 下列关于栈的叙述正确的是()。 A、 在栈...
  • 在一小时内学会 C#(txt版本)

    热门讨论 2009-08-19 18:09:37
    C++ 有所区别的是,C# 没有单独的声明(头)实现(CPP)文件。所有代码(类声明实现)都放在扩展名为 cs 的单一文件。 看看 C# 的 Hello World 程序。 复制内容到剪贴板 代码: using System; ...
  • oracle数据库经典题目

    2011-02-17 15:05:20
    模式是一系列逻辑数据结构或对象的集合,是数据库对象的组织管理单位。 2. 简要游标的作用游标操作的基本步骤。 答案: 游标的作用是将数据库的数据检索出来后缓存,可以被PL/SQL程序一行一行的读取并处理...
  • 开多个线程开多个协程会有什么区别 两个interface{} 能不能比较 必须要手动对齐内存的情况 go栈扩容栈缩容,连续栈的缺点 golang怎么做代码优化 golang隐藏技能:怎么访问私有成员 问题排查 trace pprof ...
  •  本书是一本关于oracle database 9i、10g 11g 数据库体系结构的权威图书,涵盖了所有重要的oracle 体系结构特性,包括文件、内存结构进程,锁闩,事务、并发多版本,表索引,数据类型,分区并行,以及...
  • 软件设计规范

    2015-03-11 11:57:50
    计算技术应用之间明显的区别,是两种不同的成分。软件规范是纯粹的,只关心计算技术。而不关心应用建模。计算方法本身早已经被发现了(也就是怎么自动计算,或者说什么是可计算的),剩下的问题只是应用问题。把...
  • 软件工程教程

    热门讨论 2012-07-06 23:10:29
    问:有什么应用价值? 答: 本项目是一个能提高用户参与娱乐程序的项目,具有一定的使用价值。 追求的结果--钢琴练奏师 1.2 项目背景 传统的音乐播放器功能单一,用户对音乐缺少参与感,本项目志在提高用户对...
  • Thinking.In.Java

    2012-03-21 22:35:53
    假如您学过一种宏语言,或者用过Perl之类的工具,那么它们的基本概念并无什么区别。总之,只要能习惯基本的编程概念,就可顺利阅读本书。当然,C/C++程序员在阅读时能占到更多的便宜。但即使不熟悉C,一样不要把自己...
  • 但是文档没有实战用例,没有告诉我们哪些可行或者哪些不可行,什么情况下可行或者什么情况下不可行,为什么可行或者为什么不可行,它只是“公事公办”为你呈上厚厚的一摞文字,告诉你情况就是这样,你自己看着办吧...

空空如也

空空如也

1 2 3
收藏数 42
精华内容 16
关键字:

集合中包含和属于有什么区别