033.Python面向对象_类补充_生命周期

news2024/11/20 0:38:05

无奋斗不青春

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈
入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈
虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈
PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈
Oracle数据库教程:👉👉 Oracle数据库文章合集 👈👈
优 质 资 源 下 载 :👉👉 资源下载合集 👈👈

分隔线

类&补充_生命周期

    • 生命周期
      • 概念
      • 涉及问题
      • 监听对象生命周期
        • `__new__` 方法
        • `__init__` 方法
        • `__del__` 方法
      • 生命周期案例
    • 内存管理机制
      • 存储方面
      • 垃圾回收方面
        • 引用计数机制
        • 垃圾回收机制
          • 主要作用
          • 底层实现原理(了解/难)
          • 垃圾回收时机(掌握&简单)
          • 循环引用解决办法

生命周期

概念

  • 生命周期指的是一个对象从诞生到消亡的过程
  • 当一个对象被创建时,会在内存中分配相应的内存空间进行存储
  • 当这个对象不在使用,为了节约内存,就会把这个对象释放

涉及问题

  • 如何监听一个对象的生命过程?
  • Python是如何掌控一个对象的生命?

监听对象生命周期

__new__ 方法
  • 当我们创建一个实例对象时,用于给这个实例对象分配内存的方法
  • 通过拦截这个方法,可以修改实例对象的创建过程。例如:单例设计模式
    # 对比示例
    class Person1(object):
        pass
    
    
    p1 = Person1()
    print(p1)            # 输出:<__main__.Person object at 0x000001F672F8F5E0>
    
    
    # __new__方法示例
    class Person2(object):
        def __new__(cls, *args, **kwargs):
            print('新建一个实例对象,被我拦截了')
    
    
    p2 = Person2()
    print(p2)            # 输出:新建一个实例对象,被我拦截了    None
    
__init__ 方法
  • 当实例对象被创建完成之后,会自动调用这个方法,并且将这个对象传递给self
  • 在这个方法中可以给这个创建好的对象增加一个额外的信息(如:属性)
  • 通过__new__方法拦截实例对象创建操作后,该方法也无法执行
    class Person(object):
        def __init__(self):
            print('对象初始化')
            self.name = '失心疯'
    
    
    p = Person()
    print(p.name)
    
    
    # 实例对象创建被拦截后,该方法也无法执行
    class Person(object):
        def __new__(cls, *args, **kwargs):
            print('新建实例对象,被拦截了')
            
        def __init__(self):
            print('对象初始化')
            self.name = '失心疯'
    
    
    p = Person()
    print(p.name)
    
    # 输出结果
    # Traceback (most recent call last):
    #   File "E:\StudyCode\Python\13-面向对象\18-生命周期.py", line 28, in <module>
    #     print(p.name)
    # AttributeError: 'NoneType' object has no attribute 'name'
    # 新建实例对象,被拦截了
    
__del__ 方法
  • 当对象被释放时,会自动调用这方法(如:通过del方法删除对象)
    class Person(object):
        # def __new__(cls, *args, **kwargs):
        #     print('新建实例对象,被拦截了')
    
        def __init__(self):
            print('对象初始化')
            self.name = '失心疯'
    
        def __del__(self):
            print('对象被释放了')
    
    
    p = Person()
    print(p.name)
    del p
    

生命周期案例

  • 要求:记录一下,当前这个时刻由Person类产生的实例对象有多少个
  • 实现:创建一个实例对象,计数+1,删除一个实例对象,计数-1
    personCount = 0
    
    class Person(object):
        def __init__(self):
            global personCount
            personCount += 1
            # print('创建实例对象 计数+1')
    
        def __del__(self):
            global personCount
            personCount -= 1
            # print('释放实例对象 计数-1')
    
    
    p1 = Person()
    p2 = Person()
    print('当前实例个数为:', personCount)      # 当前实例个数为: 2
    del p1
    print('当前实例个数为:', personCount)      # 当前实例个数为: 1
    
  • 这一段实现代码中有几个问题
    • 1、每次输出统计数量的时候都要重复写上print('当前实例个数为:', personCount)这一句,代码冗余
    • 2、用于计数的personCount变量是一个全局变量,在外部可以随意改变
    • 3、在类内部使用personCount变量时,都需要使用global关键字指定变量是全局变量
  • 解决方法:
  • 1、将重复性的操作封装成一个方法,每次要用的时候直接调用方法
  • 2、将全局变量定义成类属性(不定义成实例属性,是因为实例属性是分别记录各个实例对象的属性)
  • 示例代码优化
    class Person(object):
        personCount = 0
    
        def __init__(self):
            Person.personCount += 1
            # print('创建实例对象 计数+1')
    
        def __del__(self):
            self.__class__.personCount -= 1
            # print('释放实例对象 计数-1')
    
        @staticmethod   # 静态方法
        def count():
            print('当前实例个数为:', Person.personCount)
    
    
    p1 = Person()
    p2 = Person()
    Person.count()      # 当前实例个数为: 2
    
    Person.personCount = 100
    del p1
    Person.count()      # 当前实例个数为: 99
    
  • 优化后的代码中依然有一些问题
    • 1、这个类属性在外界通过类名.属性的方式依然可以对这个属性进行修改
  • 解决方法
    • 将这个类属性改成私有属性,外界就无法对这个属性进行修改了
  • 示例代码优化
    class Person(object):
        __personCount = 0
    
        def __init__(self):
            Person.__personCount += 1
            # print('创建实例对象 计数+1')
    
        def __del__(self):
            self.__class__.__personCount -= 1
            # print('释放实例对象 计数-1')
    
        @staticmethod   # 静态方法
        def count():
            print('当前实例个数为:', Person.__personCount)
    
    
    p1 = Person()
    p2 = Person()
    Person.count()      # 当前实例个数为: 2
    del p1
    Person.count()      # 当前实例个数为: 1
    
  • 在这一段代码中,依然可以进行优化
  • 在这个类中的静态方法def count()中用到了这个类,那么我们在定义这个方法的时候,就可以通过参数来接收一个类
  • 那么,就可以通过定义类方法来实现这个操作
    class Person(object):
        __personCount = 0
    
        def __init__(self):
            Person.__personCount += 1
            # print('创建实例对象 计数+1')
    
        def __del__(self):
            self.__class__.__personCount -= 1
            # print('释放实例对象 计数-1')
    
        @classmethod   # 类方法
        def count(cls):
            print('当前实例个数为:', cls.__personCount)
    
    
    p1 = Person()
    p2 = Person()
    Person.count()      # 当前实例个数为: 2
    del p1
    Person.count()      # 当前实例个数为: 1
    


内存管理机制

  • 在Python中,内存管理机制是引用计数机制和垃圾回收机制两套机制并行的
  • 垃圾回收机制解决循环引用的问题,但是引用计数机制效率更高

存储方面

  • 1、在Python中万物皆对象
    • 其他部分语言中存在基本数据类型和对象
    • Python不存在基本数据类型,int、float、bool、str等都是对象
  • 2、所有对象都会在内存中开辟一块空间进行存储
    • 会根据不同的类型一级内容,开辟不同的空间大小进行存储
    • 返回该控件的地址给外界接收(称为“引用”)没用与后续对这个对象的操作
    • 通过id(对象)函数可以获取指定对象的内存地址(10进制)
    • 通过hex(10进制内存地址)函数可以查看对应的16进制地址
  • 3、对于整数和短小的字符,Python会进行缓存处理,不会创建多个相同的对象
  • 4、容器对象存储的其他对象,仅仅是存储的其他对象的引用,并不是存储的其他对象本身

垃圾回收方面

引用计数机制
  • 概念

    • 一个对象会记录者自身被引用的个数
      • 每增加一个引用,这个对象的引用计数就会自动+1
      • 每减少一个引用,这个对象的引用计数就会自动-1
  • 查看引用计数

    • 可以通过sys模块中的getrefcount(对象)方法获取到指定对象的引用数
    • 调用这个函数的时候,这个对象作为参数被传递的时候就是被引用,所以统计出来的引用数会比实际的引用数大1
      import sys
      
      class Person(object):
          pass
      
      
      p1 = Person()                   # 引用个数:1
      print(sys.getrefcount(p1))      # 2,获取到的引用个数比实际的大1
      
      p2 = p1                         # 引用个数:2
      print(sys.getrefcount(p1))      # 3
      
      del p2                          # 引用个数:1
      print(sys.getrefcount(p1))      # 2
      
      del p1                          # p1对象被删除,后续就无法再通过p1进行查询操作
      print(sys.getrefcount(p1))      # 报错:NameError: name 'p1' is not defined
      
  • 引用计数发生改变的场景举例

  • 引用计数+1场景

    • 对象被创建时 p1 = Person()
    • 对象被引用时 p2 = p1
    • 对象被作为参数传入到一个函数中时 log(p1),引用计数会+2
      • 对象作为参数传入一个函数时,在函数内部会被两个属性引用(__globals__func_globals)
    • 对象作为一个元素存储到容器中时 l = [p1]
  • 引用计数-1场景

    • 对象的别名被现实销毁 del p1
    • 对象的别名被赋予新的对象 p1 = 123
    • 一个对象离开它的作用域
      • 一个函数执行完毕时,内部的局部变量关联的对象,它的引用会被释放
    • 对象所在的容器被销毁或者从容器中删除对象
  • 特殊场景-循环引用问题

  • 内存管理机制:当一个对象 被引用,引用计数+1,删除引用,引用计数-1;引用计数为0时,对象被自动释放

  • 循环引用:

    class Person(object):
        pass
    
    
    class Dog(object):
        pass
    
    
    p = Person()
    d = Dog()
    
    p.pet = d
    d.master = p
    
    del p
    del d
    
    • 在这里插入图片描述
    * 通过 p = Person() 实例化对象的时候,p 引用了 Person 的内存地址, Person 对象的引用计数+1,此时 Person 对象的引用计数=1
    * 通过 d = Dog() 实例化对象的时候, d 引用了 Dog 的内存地址, Dog 对象的引用计数+1,此时 Dog 对象的引用计数=1
    
    * 通过 p.pet = d 添加属性赋值, Person 对象的 pet 属性引用了 Dog 的内存地址, Dog 对象的引用计数再+1,此时 Dog 对象的引用计数=2
    * 通过 d.master = p 添加属性赋值, Dog 对象的 master 属性引用了 Person 的内存地址, Person 对象的引用计数再+1,此时 Person 对象的引用计数=2
    
    * 通过 del p 语句删除p实例对象,释放 Person 对象的一个引用, Person 对象的引用计数-1,此时 Person 对象的引用计数=1
    * 通过 del d 语句删除d实例对象,释放 Dog 对象的一个引用, Dog 对象的引用计数-1,此时 Dog 对象的引用计数=1
    
    * 此时已经没有变量引用 Person和Dog对象了,这两个对象就没办法被使用了,但是他们的引用计数依然保存着1,就不会被释放掉,就造成了内存泄漏
    * 这两个对象之间属于互相引用的关系,就成了循环引用,导致两个对象的引用计数都是1,所以不能被引用计数机制释放
    
  • 由于实例对象被删除之后,无法使用sys.getrefcount获取对象的引用计数,需要通过第三方库objgraphcount方法来查看垃圾回收器,跟踪的对象个数

    • 安装第三方库objgraph
      pip install objgraph
      
    • 使用第三方库跟踪对象个数
      # 没有被循环引用的情况
      import objgraph
      
      
      class Person(object):
          pass
      
      
      class Dog(object):
          pass
      
      
      p = Person()
      d = Dog()
      print(objgraph.count('Person'))     # 追踪关于Person这个类的相关对象个数:1(也就是由Person类创建的实例对象个数)
      print(objgraph.count('Dog'))        # 追踪关于Dog这个类的相关对象个数:1(也就是由Dog类创建的实例对象个数)
      
      
      del p
      del d
      print(objgraph.count('Person'))     # p实例对象被删除,Person类相关的对象个数:0
      print(objgraph.count('Dog'))        # d实例对象被删除,Dog类相关的对象个数:0
      
      
      #==================================================
      
      # 被循环引用之后的情况
      import objgraph
      
      
      class Person(object):
          pass
      
      
      class Dog(object):
          pass
      
      
      p = Person()
      d = Dog()
      print(objgraph.count('Person'))     # 追踪关于Person这个类的相关对象个数:1(也就是由Person类创建的实例对象个数)
      print(objgraph.count('Dog'))        # 追踪关于Dog这个类的相关对象个数:1(也就是由Dog类创建的实例对象个数)
      
      p.pet = d
      d.master = p
      
      del p
      del d
      print(objgraph.count('Person'))     # p实例对象被删除,但是被Dog类的master属性引用,Person类相关的对象个数:1
      print(objgraph.count('Dog'))        # d实例对象被删除,但是被Person类的pet属性引用,Dog类相关的对象个数:1
      
垃圾回收机制
  • 垃圾回收机制:是属于引用计数机制的一个补充机制(一般对象完全可以通过引用计数机制进行释放,但是如果对象被循环引用,就无法通过引用计数机制进行释放,所以就产生了垃圾回收机制)
主要作用
  • 从经历过“引用计数机制”仍未被释放的对象中,找到“循环引用”并且干掉相关对象
底层实现原理(了解/难)
  • 怎样找到“循环引用”?

    • 1、收集所有的“容器对象”,通过一个双向链表进行记录引用
      • 容器对象:可以引用其他对象的对象(列表、元组、字典、自定义类对象等可以添加其他对象的东西)
      • 非容器对象:不可以引用其他对象的对象(int、float、bool、str等不能添加其他对象的对象)<非容器对象不能引用其他对象,所以就不会出现循环引用的情况>
      • 双向链表:
    • 2、针对每一个“容器对象”,通过一个变量gc_refs来记录当前对应的引用计数
    • 3、针对每个“容器对象”,找到他引用的“容器对象”,并将这个引用的“容器对象”的引用计数-1
    • 4、经过步骤3之后,如果一个“容器对象”的引用计数为0,就代表这个“容器对象”可以被回收了,肯定是“循环引用”导致他活到现在的
    • 在这里插入图片描述
  • 如何提升查找“循环引用”的性能

  • 上面这种垃圾回收的检测机制需要把所有记录在双向链表中的“容器对象”进行检测一遍,是非常的耗费性能。

  • 基于这个问题,Python就提出了一个假设:命越大,越长寿

    • 假设一个对象经过10次检测都没有被释放掉,那就认定这个对象一定很长寿,就减少对这个对象的“检测频率”
  • 基于这种假设,就设计了一套机制:分代回收

  • 分代回收

    • 1、默认一个对象被创建出来之后,属于0代
    • 2、如果经历过这一代“垃圾回收”之后,依然没有被释放,则划分到下一代
    • 3、“垃圾回收”的周期
      • 0代“垃圾回收”一定次数,会触发0代和1代回收
      • 1代“垃圾回收”一定次数,会触发0代、1代和2代回收
    • 在这里插入图片描述
  • 垃圾回收器当中,新增的对象个数-消亡的对象个数,达到一定的阈值时,才会触发垃圾检测

  • 个人理解:当出现循环引用对象(无法被释放的对象)个数达到一定阈值时候才会触发垃圾检测

  • 查看和设置相关参数

  • 语法

    import gc
    
    gc.get_threshold()          # 查看触发机制的阈值
    # 输出 (700, 10, 10)
    # 700   触发垃圾检测的阈值
    # 10    触发0代和1代回收的阈值
    # 10    触发0代、1代和2代回收的阈值
    
    gc.set_threshold(触发垃圾检测的阈值,触发0代和1代回收的阈值,触发0代、1代和2代的阈值)
    # 设置触发阈值
    
  • 示例代码

    import gc
    
    print(gc.get_threshold())           # 输出:(700, 10, 10)
    # 700   垃圾回收器中, 新增对象个数 - 消亡对象个数 = 700,触发垃圾检测
    # 10    每经过10次【0代垃圾回收】检测,就触发一次【0代和1代回收】(前面10次仅执行0代回收)
    # 10    每经过10次【0代和1代垃圾回收】检测,就触发一次【0代、1代和2代回收】
    # 10次【0代回收】执行1次【0代和1代回收】,10次【0代和1代回收】执行1次【0代、1代和2代回收】
    
    gc.set_threshold(1000, 50, 20)
    # 1000   设置垃圾回收器中, 新增对象个数 - 消亡对象个数 = 1000时,才触发垃圾检测
    # 50     设置每经过50次【0代垃圾回收】检测,就触发一次【0代和1代回收】
    # 20      设置每经过20次【0代和1代垃圾回收】检测,就触发一次【0代、1代和2代回收】
    
    print(gc.get_threshold())           # 输出:(1000, 50, 20)
    
垃圾回收时机(掌握&简单)
  • 自动回收
  • 触发条件:开启垃圾回收机制并且达到了垃圾回收的阈值
  • 阈值:垃圾回收器中,新增的对象个数 与 释放的对象个数 之差
  • 垃圾回收机制开启和关闭设置
    import gc
    
    gc.enable()         # 开启垃圾回收机制(默认开启)
    gc.disable()        # 关闭垃圾回收机制
    gc.isenabled()      # 判定垃圾回收机制是否开启状态
    
  • 垃圾回收阈值获取和设置
    import gc
    
    gc.get_threshold()      # 获取自动回收阈值
    gc.set)threshold()      # 设置自动回收阈值
    
  • 手动回收
  • 语法
    import gc
    
    gc.collect(garbage=None)    # 运行垃圾收集器
        # garbage:可以是一个整数,指定要收集哪一代,默认运行完整收集(0代、1代、2代)
    
    # 无论垃圾回收机制是否开启,都可以运行
    
  • 示例(循环引用问题解决)
    # 默认情况,出现循环引用后无法被引用计数机制释放,未达到阈值的情况下也不会被垃圾回收机制释放
    import objgraph
    
    
    class Person(object):
        pass
    
    
    class Dog(object):
        pass
    
    
    p = Person()
    d = Dog()
    
    p.pet = d
    d.master = p
    
    del p
    del d
    
    print(objgraph.count('Person'))      # 输出:1
    print(objgraph.count('Dog'))         # 输出:1
    
    
    #=============通过手动开启垃圾回收机制进行释放=========================
    
    import objgraph
    import gc
    
    
    class Person(object):
        pass
    
    
    class Dog(object):
        pass
    
    
    p = Person()
    d = Dog()
    
    p.pet = d
    d.master = p
    
    del p
    del d
    
    gc.collect()                        # 手动开启垃圾回收机制
    
    print(objgraph.count('Person'))      # 输出:0
    print(objgraph.count('Dog'))         # 输出:0
    
    
循环引用解决办法
  • 可到达引用:可以直接访问真实对象的引用(p 和 d)
  • 不可到达引用:需要通过可到达引用间接的访问真实对象(pet 和 master)
    • 不能直接通过pet和master访问真实对象,必须通过p.pet和d.master间接访问,删除p和d之后,就无法通过pet和master访问到真实对象了
  • 强引用:会影响对象的引用计数的引用
  • 弱引用:与强引用相对,弱引用并不会影响对象的引用计数,也就是说其不影响对象是否被回收的判定(需要使用weakref模块)
  • 基础类型int、list、dict、tuple、str不支持弱引用,对其执行弱引用会报错
  • 可以通过__weakrefoffset__查看类型是否支持弱引用,该变量表示弱引用指针相对对象起始地址的偏移量,>0表示支持弱引用
  • weakref模块
  • 方法
    weakref.ref(obj)                    # 给指定对象创建一个弱引用
    weakref.WeakKeyDictionary(dict)     # 给指定字典的key创建一个弱引用
    weakref.WeakValueDictionary(dict)   # 给指定字典的value创建一个弱引用
    
  • 通过使用弱引用解决循环引用不能自动释放问题
    import objgraph
    import weakref
    
    
    class Person(object):
        pass
    
    
    class Dog(object):
        pass
    
    
    p = Person()
    d = Dog()
    
    p.pet = d
    d.master = weakref.ref(p)       # 通过weakref.ref进行弱引用
    
    del p
    del d
    
    
    print(objgraph.count('Person'))      # 输出:0
    print(objgraph.count('Dog'))         # 输出:0
    
  • 当一个对象引用多个对象时,可以使用字典的方式
    import objgraph
    import weakref
    
    
    class Person(object):
        pass
    
    
    class Dog(object):
        pass
    
    class Cat(object):
        pass
    
    
    p = Person()
    d = Dog()
    c = Cat()
    
    # p.pet = {'Dog': d, 'Cat': c}
    p.pet = weakref.WeakValueDictionary({'Dog': d, 'Cat': c})
    d.master = p
    
    del p
    del d
    del c
    
    
    print(objgraph.count('Person'))      # 输出:0
    print(objgraph.count('Dog'))         # 输出:0
    print(objgraph.count('Cat'))         # 输出:0
    
  • 在释放对象之前打断循环引用
    import objgraph
    
    
    class Person(object):
        pass
    
    
    class Dog(object):
        pass
    
    
    p = Person()
    d = Dog()
    
    p.pet = d
    d.master = p
    
    p.pet = None
    del p
    del d
    
    
    print(objgraph.count('Person'))      # 输出:0
    print(objgraph.count('Dog'))         # 输出:0
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1252280.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java基准测试工具JMH的简介与使用

JMH是一套Java基准测试工具&#xff0c;用于对Java执行进行基准测试以及生成测试报告。平时应用于Java一些基础Api或者一些工具类这种离开网络因素的纯系统测试。 使用方式 maven引入&#xff1a; <dependency><groupId>org.openjdk.jmh</groupId><art…

linux账户管理实例二

要求&#xff1a;我的 用户pro1&#xff0c;pro2&#xff0c;pro3是同一个项目开发人员&#xff0c;想让这三个人用户在同一个目录下工作&#xff0c;但这三个人拥有自己的主文件夹和基本的私有用户组&#xff0c;工作目录为/srv/projecta&#xff0c;如何实现&#xff1f; 分…

03_MySQL基本SQL语句讲解

#课程目标 能够创建、删除数据表能够对表里的数据记录进行增加、删除、修改、查询操作能够创建、删除用户能够给用户授权并回收权限了解delete和truncate语句的区别 #一、数据库基本操作 ##1、查看数据库相关信息 mysql> show databases; 查看所有数据库 mysql>…

【机器学习】聚类(三):原型聚类:高斯混合聚类

文章目录 一、实验介绍1. 算法流程2. 算法解释3. 算法特点4. 应用场景5. 注意事项 二、实验环境1. 配置虚拟环境2. 库版本介绍 三、实验内容0. 导入必要的库1. 全局调试变量2. 调试函数3. 高斯密度函数&#xff08;phi&#xff09;4. E步&#xff08;getExpectation&#xff09…

【开源组件】- 关于Jetcache的使用

关于Jetcache的使用 &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f31d;分享学习心得&#xff0c;欢迎指正&#xff0c;大家一起学习成长&#xff01; JetCache是由…

MobileNets发展与总结

写在前面&#xff1a;本博客仅作记录学习之用&#xff0c;部分图片来自网络&#xff0c;如需引用请注明出处&#xff0c;同时如有侵犯您的权益&#xff0c;请联系删除&#xff01; 文章目录 引言MobileNetsMobileNet - V1思想代码实现 MobileNet - V2思想代码实现 MobileNet - …

LeetCode Hot100 105.从前序与中序遍历序列构造二叉树

题目&#xff1a;给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 代码&#xff1a; class Solution {private Map<Integer, Integer> indexM…

1.6 C语言之数组概述

1.6 C语言之数组概述 一、数组二、练习 一、数组 所谓数组&#xff0c;就是内存中一片连续的空间&#xff0c;可以用来存储一组同类型的数据 数组有下标&#xff0c;从0开始&#xff0c;可以理解为是给数组中的元素编号&#xff0c;便于后续寻址访问 我们来编写一个程序&…

杂货铺 | Windows系统上解压缩tgz文件

文章目录 &#x1f4da;快速终端打开实现 & 解压缩实现步骤&#x1f4da;环境变量的一般配置步骤 & 问题解决思路 &#x1f4da;快速终端打开实现 & 解压缩实现步骤 将对应的tgz文件放入对应的文件夹。快速在指定文件夹下打开终端 打开对应的路径 双击地址栏 然后…

4.28每日一题(二重积分比较大小:被积函数的大小、正负性、积分区间奇偶性)

一般比较大小的题目我们不需要把结果全部计算出来 &#xff0c;而是通过奇偶性或者被积函数的大小或大于0、等于0、小于0等方法判断比较

1、Mysql架构与历史

Mysql逻辑架构 最上层是服务并不是Mysql所独有的&#xff0c;大多数基于网络的客户端/服务器的工具或者服务都有类似的架构&#xff0c;比如连接处理&#xff0c;授权认证&#xff0c;安全等。 第二层是Mysql比较有意思的部分。大多数Mysql的核心服务都在这一层&#xff0c;…

antv/g6的学习总结

新建一个简单实例 1、使用命令行在项目目录下执行以下命令 cnpm install --save antv/g6 2、创建容器 <div id"mountNode"></div> 3、在需要用的 G6 的 JS 文件中导入 import G6 from antv/g6; 4、 数据准备 引入 G6 的数据源为 JSON 格式的对象。…

量化交易:因子风险暴露

本文介绍了如何计算因子风险暴露的内容。 判断风险暴露的建模是否合理 通常&#xff0c;此分析是基于历史数据&#xff0c;而对历史风险暴露的估计可能会影响未来的风险暴露。 因此&#xff0c;计算因子风险暴露是不够的。 必须对风险暴露保持信心&#xff0c;并明白对风险暴…

Compose入门

​ 本篇文章主要是为了对Compose有一个初步了解。知道Compose是做什么的&#xff0c;用Compose能干什么&#xff0c;在目前的各种UI框架下面有些优势&#xff0c;参考Google官网的解释加上一些自己的理解生成的一篇文章。本人也是Compose初学者&#xff0c;通过每一步学习遇到哪…

带你用uniapp从零开发一个仿小米商场_2.创建空白项目及公共样式引入

创建空白项目 打开uniapp 点击新建->项目 如下, 是编辑你项目的名字的地方是你项目存放地址,可以点击浏览器去文件管理里面选地址是模板选择,这里选择默认模板就好是一些其他选择比如uvue能让你项目在编译成软件时运行更快,unicloud能让你用js写后端,且直接就是云开发,g…

【WSA】无法打开 适用于 Android™ 的 Windows 子系统,因为它处于脱机状态。可能缺少存储设备,或者存储设备已断开连接。

问题描述 之前可以正常使用适用于 Android™ 的 Windows 子系统&#xff08;WSA&#xff09;&#xff0c;但突然间无法启动了。 当尝试启动WSA中的软件时&#xff0c;都会出现以下错误提示&#xff1a; 无法打开 适用于 Android™ 的 Windows 子系统&#xff0c;因为它处于脱…

基于springboot实现留守儿童爱心网站项目【项目源码+论文说明】计算机毕业设计

基于springboot实现留守儿童爱心网站演示 摘要 随着留守儿童爱心管理的不断发展&#xff0c;留守儿童爱心网站在现实生活中的使用和普及&#xff0c;留守儿童爱心管理成为近年内出现的一个热门话题&#xff0c;并且能够成为大众广为认可和接受的行为和选择。设计留守儿童爱心网…

数字逻辑电路基础-时序逻辑电路之移位寄存器

文章目录 一、移位寄存器定义二、verilog源码三、仿真结果一、移位寄存器定义 移位寄存器定义 A shift register is a type of digital circuit using a cascade of flip flops where the output of one flip-flop is connected to the input of the next. 移位寄存器是一种将…

js逆向-某敏感网站登录参数分析

声明 本文仅供学习参考&#xff0c;如有侵权可私信本人删除&#xff0c;请勿用于其他途径&#xff0c;违者后果自负&#xff01; 如果觉得文章对你有所帮助&#xff0c;可以给博主点击关注和收藏哦&#xff01; 前言 目标网站&#xff1a;aHR0cHM6Ly9tZGZnaGcuNXhwb2lqaHRm…

LED面板显示屏驱动芯片

一、基本概述 TM1638是一种带键盘扫描接口的LED&#xff08;发光二极管显示器&#xff09;驱动控制专用IC,内部集成有MCU数字接口、数据锁存器、LED驱动、键盘扫描等电路。本产品质量可靠、稳定性好、抗干扰能力强。 二、主要应用场合 主要适用于家电设备(智能热水器、微波炉…