python基础篇--学习记录2

1.深浅拷贝

l1 = ["张大仙","徐凤年",["李淳刚","邓太阿"]]
# 变量名对应的就是内存地址,这里就是将l1的内存地址给了l2
# 现在两个变量指向同一个内存地址,l1变化l2也会变化
l2 = l1

现在的需求是l2是l1的拷贝版本,但是两者是完全分割开来的,l2修改之后不能影响我l1的数据

1.1 浅拷贝

l3 = l1.copy()

l1和l3 列表的id不一样但是里面存储内容的id却是一样的
拷贝的列表只是拷贝的容器本身,只是产生了一个新的容器,但是里面的数据还是原来的数据

l1 = ["张大仙", "徐凤年", ["李淳刚", "邓太阿"]]
# 变量名对应的就是内存地址,这里就是将l1的内存地址给了l2
# 现在两个变量指向同一个内存地址,l1变化l2也会变化
# l2 = l1

l3 = l1.copy()

print(l1, id(l1))  # ['张大仙', '徐凤年', ['李淳刚', '邓太阿']] 4553523080
print(l3, id(l3))  # ['张大仙', '徐凤年', ['李淳刚', '邓太阿']] 4555309832
print(id(l1[0]), id(l1[1]), id(l1[2]))  # 4353425648 4354327536 4353425224
print(id(l3[0]), id(l3[1]), id(l3[2]))  # 4353425648 4354327536 4353425224

浅拷贝后,发现l3确实被改变了,但是l1的子列表也发生了变化 

l1 = ["张大仙", "徐凤年", ["李淳刚", "邓太阿"]]
l3 = l1.copy()
l3[0] = "张坦克"
l3[1] = "徐晓"
l3[2][0] = "小明"
l3[2][1] = "小李"
print(l1)  # ['张大仙', '徐凤年', ['小明', '小李']]
print(l3)  # ['张坦克', '徐晓', ['小明', '小李']]

因为浅拷贝只会将原列表的第一层里面的索引和内存地址一模一样的拷贝到新的内存空间里面,由于列表里面的第一个和第二个元素是字符串,不可变类型,所以修改l3时,又会申请新的内存空间.但是由于列表是可变类型,我们修改其子列表的时候,它的内存地址是不会变的.所以l1和l3里面存的还是原来的子列表的内存地址,但是子列表的数据却被改掉了.

浅拷贝会把原列表第一层存的索引和内存地址完全拷贝一份给新的列表,如果原列表存储的都是不可变类型,浅拷贝就可以正常使用,新列表改动之后就会产生新的值,不会影响原来的列表.但是一旦包含了可变类型浅拷贝的原列表就没办法和原列表完全分开.

1.2 深拷贝

深拷贝针对不可变对象,第一层的索引和内存地址是一模一样的,但是对于可变对象,深拷贝会产生一个新的内存地址,但是还是使用的是原来的值

深拷贝针对可变类型会产生新的容器,可对不可变类型则是仍然使用原值

l1 = ["张大仙", "徐凤年", ["李淳刚", "邓太阿"]]
import copy

l3 = copy.deepcopy(l1)

print(l1, id(l1))  # ['张大仙', '徐凤年', ['李淳刚', '邓太阿']] 4325347208
print(l3, id(l3))  # ['张大仙', '徐凤年', ['李淳刚', '邓太阿']] 4327146568

print(id(l1[0]), id(l1[1]), id(l1[2]))  # 4479013104 4479914992 4479012680
print(id(l3[0]), id(l3[1]), id(l3[2]))  # 4479013104 4479914992 4480805448
print(id(l1[2][0]), id(l1[2][1]))  # 4470445136 4470445232
print(id(l3[2][0]), id(l3[2][1]))  # 4470445136 4470445232

l3[0] = "张坦克"
l3[1] = "徐晓"
l3[2][0] = "小明"
l3[2][1] = "小李"

print(l1)  # ['张大仙', '徐凤年', ['李淳刚', '邓太阿']]
print(l3)  # ['张坦克', '徐晓', ['小明', '小李']]

2.变量

2.0 储存

我们在定义一个变量的时候,它有两部分需要储存.一部分是变量名,一部分是变量值.在内存里面也是对应两块内存空间栈区是专门用来存放变量名的,堆区则是专门用来存放变量值的当定义一个name="张大仙"的时候,会先在堆区里面申请一块内存空间,把值张大仙存储进去.对应一个内存地址.在栈区里面放一个name,对应上刚刚的内存地址.当堆区的内存地址引用计数为0被清除的时候,对应栈区的变量名也会被清除

2.1 内存管理

定义变量就是在内存里面开辟了一个内存空间,然后将一个空间的内存地址捆绑给了变量名,通过这个变量名,我们就可以找到这个对应的值在哪.我们知道定义变量是要占用内存空间的,但是内存空间的大小是有限的.这时候就有一个问题,就是你申请的内存空间,不用了一定要及时的释放出来.否则的话,你将内存撑爆了的话就会导致内存溢出的问题,这个操作就叫做内存管理.

而python推出了一个内存管理机制,被叫做"垃圾回收机制",垃圾回收机制就是用来回收这种没有关联任何变量名的值.而这也涉及到一个概念叫做"引用计数",也就是一个内存空间身上捆绑了几个变量名.引用计数变为0的时候它就是一个垃圾

2.2 垃圾回收机制

2.2.1 引用计数的增加

a =100

申请一个内存空间将100 存进去,然后给这个内存空间绑定一个变量名叫a,a指向的就是100的内存地址

b = a

将a的内存地址给b,这时候a和b指向的就是同一个内存地址

c = a

现在 a b c指向的都是同一个内存地址

2.2.2  引用计数的减少

 del a

表面上看是删除a,实际上是解除a与100身上的绑定关系 

a = 100
b = a
c = a
del a
print(a)
del b
c = 123 # c会和100的绑定关系解除,重新指向123的内存地址

2.3 变量值特征

1) id: 根据变量值的内存地址所计算出来的一个id号码,类似于内存地址的映射.变量值的内存地址不一样,id就会不一样

2) type:查看变量值的类型

2.4 is和==的区别

1) is叫做身份运算,是用来比较左右两个值的身份是否相等的,而变量值的身份证号就是id号,所以is就是用来比较两个变量值的id是否相等的

2) == 是用来比较左右变量的值是否是相等的

将代码直接使用python解释器来运行 

所以只要是赋值操作,产生新的值的时候,都会申请一块新的内存空间,只要是申请了新的内存空间,它的内存地址就会不一样,id就会不一样.

2.5 小整数池的概念

申请内存空间将值存进去,这就是一种写操作,IO操作,不管是往硬盘里面读写还是往内存读写数据,这都是IO操作.这都是耗时的,python给我们做了优化,叫做小整数池.为了避免因创建相同的值,而重复申请内存空间带来的效率问题,python解释器会在启动的那一刻创建出小整数池(-5,256).就是python解释器一启动就立刻申请一堆内存空间,把这些值放进去,这个范围内的整数被重复使用时就不会再申请新的内存空间,而且这些小整数也永远不会被垃圾回收机制回收.

3. 列表在内存中的存储方式

直接引用:创建内存空间,将数值放进去,变量名直接指向内存地址

间接引用:列表是间接引用

开辟内存空间,存一个0号索引,对应值a的内存地址;1号索引,对应值b的内存地址;2号索引,对应值c的内存地址;a的内存地址再指向一个内存空间里面存放的才是a这个值,b,c同理.也就是说列表不会存放真正的值,只会存放索引和值的内存地址.而值会存放在单独的内存空间

 

4 内存管理

4.1 循环引用之内存泄露问题

前面说过不管是直接引用还是间接引用,只要引用计数为0时,它就会被垃圾回收机制回收.但是这种工作方式是有问题的

# _*_ coding utf-8 _*_
# george
# time: 2024/3/7上午9:21
# name: store.py
# comment:
l1 = ["a", "b"]
l2 = ["x", "y"]
l1.append(l2)
print(id(l2), id(l1[2]))  # 4410818440 4410818440
l2.append(l1)
print(l2)  # ['x', 'y', ['a', 'b', [...]]]
print(id(l1), id(l2[2]))  # 4355399496 4355399496
"""
现在l1存储了l2的内存地址,l2也存储了l1的内存地址,这两个列表中存在一种相互引用的关系,也就是循环引用.
循环引用会导致非常致命的问题
我现在解除了l1,l2的直接引用,但是他们的引用计数并没有变为0,它们身上只有他们相互之间的间接引用,我们再也没办法取到这两个表
垃圾回收机制会回收引用计数为0的内存空间,但是这两个列表变成了永远回收不了的垃圾,永远占据这两个内存空间,这就叫内存泄露
"""
del l1
del l2
print(l1,l2) # NameError: name 'l1' is not defined

现在l1存储了l2的内存地址,l2也存储了l1的内存地址,这两个列表中存在一种相互引用的关系,也就是循环引用.

循环引用会导致非常致命的问题 我现在解除了l1,l2的直接引用,但是他们的引用计数并没有变为0,它们身上只有他们相互之间的间接引用,我们再也没办法取到这两个表 垃圾回收机制会回收引用计数为0的内存空间,但是这两个列表变成了永远回收不了的垃圾,永远占据这两个内存空间,这就叫内存泄露.而循环引用就会导致内存泄露问题.python提供了一个补充解决方法叫做标记清除.

4.2 标记清除机制

 

 

标记清除会在python程序内存空间不够用的时候,将整个程序暂停下来,扫描栈区.把通过栈区所能够引用到的值不管是直接引用还是间接引用到的,全都标记为存活状态.一旦发现有通过栈区引用不到的值,都标记为死亡状态.死亡状态的值会被直接清理掉.就算它身上的引用计数不为0,只要我们访问不到它了,标记清除就会将它标记为垃圾,然后回收掉.

4.3 分代回收机制

前面说的引用计数和标记清除已经可以实现回收所有的垃圾了.但是现在垃圾回收机制还是有一个弊端.就是基于引用计数的垃圾回收机制,每次回收内存都需要把所有对象的引用计数全部都遍历一遍.当我们申请的变量很多的时候,每次都要将所有的变量全都扫描一边,这样的效率是非常低的.

分代回收机制的核心是:对象存在的时间越长,是垃圾的可能性就越小,应该尽量不对这样的对象进行垃圾回收。CPython将对象分为三种世代分别记为0、1、2,每一个新生对象都在第0代中,如果该对象在一轮垃圾回收扫描中存活下来,那么它将被移到第1代中,存在于第1代的对象将较少的被垃圾回收扫描到;如果在对第1代进行垃圾回收扫描时,这个对象又存活下来,那么它将被移至第2代中,在那里它被垃圾回收扫描的次数将会更少。

垃圾回收机制主要是引用计数来扫描并且回收垃圾,用标记清除解决引用计数回收不了的垃圾,用分代回收解决引用计数扫描效率的问题

5.可变与不可变类型

可变类型

值改变的情况下,id不变,说明改变的是原值,这里的值指的是堆区里面的内容.

列表,字典,集合这种容器类型都是可变类型

不可变类型

值改变的情况下下,id也发生了变化

所有的赋值操作都会申请新的内存空间,产生新的值

整型,浮点型,字符串,布尔值类型,元组

6.函数

6.1 函数的定义和调用

函数需要先定义,再调用

定义函数会申请内存空间,将函数的子代码存进去,然后将这个内存地址绑定给函数名,所以说函数名指向的就是函数的内存地址.并且在定义阶段,不会执行函数的子代码,必须要调用函数才会执行.

函数的定义阶段: 不会执行函数的子代码,但是会检测函数子代码的语法

函数的调用阶段,调用其实背后做了两件事情1)通过函数名找到函数的内存地址,在函数的内存地址后面加上(),触发函数子代码的运行 

 函数的定义阶段只会检测语法,不会执行代码.func1是没有语法错误的,func2的语法也是没有错误的
定义函数就是开辟内存空间,把函数子代码丢到内存空间里面去,然后将函数地址绑定给函数名.
1) 所以此时func1的子代码已经被放进了内存里,并且内存地址绑定给了func1
2) 检测func2也没有语法错误,func2的代码也丢到了内存里面,同时内存地址也绑定给了func2
到现在还没有执行任何函数子代码,但是内存里面已经存在了func1和func2的子代码
所以此时调用func1就不会报错

将函数的调用作为函数的参数来使用,本质上其实是将函数的返回值作为参数使用.

6.2 return

return就是函数结束的标志,只要函数子代码遇到return,就会立刻结束函数的运行,并且将return后面的值当做本次运行结果返回.如果我们返回多个值,就会被处理成为元祖

6.3 参数

函数的参数从定义阶段和调用阶段可以分为两部分

定义阶段:形式参数,简称形参

调用阶段:实际参数,简称实参

形参和实参在定义阶段是没有任何关系的,只有在调用阶段,实参才会绑定给形参,就是变量值绑定给变量名(变量值的内存地址,绑定给了变量名)

6.3.1 位置参数

位置参数就是按照从左到右的顺序,依次定义的参数.

位置形参:定义函数的时候,从左到右.依次定义的形参.必须传值,不能多也不能少

位置实参:在调用函数的时候,从左往右依次传入的值

def func(x, y, z):
    print(x, y, z)


func(1, 2, 3) # 1 2 3

6.3.2 关键字参数(关键字实参)

可以不按照顺序,而是以key=value的形式进行传值,key必须是定义函数的时候指定好的形参名

def func(x, y, z):
    print(x, y, z)


#  位置实参
# func(1, 2, 3)  # 1 2 3

# 关键字实参
func(z=3, x=1, y=2)  # 1 2 3

关键字实参和位置实参进行混用,但是必须遵循一个原则:位置实参一定要放在关键字实参之前

def func(x, y, z):
    print(x, y, z)


#  位置实参
# func(1, 2, 3)  # 1 2 3

# 关键字实参
# func(z=3, x=1, y=2)  # 1 2 3

# 混用
func(1, 2, z=3)  # 1 2 3
func(x=1, 2, 3)  # SyntaxError: positional argument follows keyword argument

6.3.4 默认参数(默认形参)

在定义阶段,就为其赋了默认值的形参.定义默认形参就意味着,在调用函数的时候可以不用为其传值.

定义的时候,默认形参必须放在位置形参之后

# 默认形参
def func(x, y=2):
    print(x, y)


func(2)  # 2 2
func(1, 3)  # 1 3

默认参数的值是在函数定义阶段被赋值的

# 默认形参
a = 2


def func(x, y=a):  # 其实就是y指向2的内存地址,3指向a的内存地址
    print(x, y)


a = 3
func(1)  # 1 2
a = [2, 3]


def func(x, y=a):  # y指向[2,3]的内存地址
    print(x, y)


a.append(4)  # 列表为可变数据类型,增加值时,内存地址不改变
func(1)  # => 1 [2, 3, 4]

python里面所有的值的传递,都是内存地址的传递,内存地址是对值的引用.

python里面所有的值传递,都是引用传递

虽然函数默认参数的值可以指定成为任意类型数据,但是不建议指定成为可变类型.因为一个函数的输出结果最好,只和函数的调用和函数的本身有关系.就是我传递什么参数,调用时就会得到什么结果,不会受到外界代码的影响.

# 之前说过尽量不要将默认形参的值设置成可变类型,虽然现在定义的形参不能被外界改变,用起来也没有问题
# 但是从规范层面上面来说我们不应该这么做
def my_append(x, y, l=[]):
    l.append(x)
    l.append(y)
    print(l)

l = [3,4]
my_append(1,2,[3,4]) # [3, 4, 1, 2]
def my_append(x, y, l=None):
    if l is None:  # 因为None也是小整数池里面的,None指向的都是同一个内存地址
        l = []
    l.append(x)
    l.append(y)
    print(l)


l = [3, 4]
my_append(1, 2, [3, 4])  # => [3, 4, 1, 2]

6.3.4 可变长参数

可变长参数是指在调用函数的时候,传入的参数个数是不固定的

6.3.4.1 可变长度的位置参数

用法: *形参名,形参名就可以用来接收多出来的位置实参

*在形参中

# 可变长度的位置参数
def func(x, y, *z):  # 将*处理成为元祖,然后赋值给z,z=(3,4,5)
    print(x, y, z)


func(1, 2, 3, 4, 5)  # => 1 2 (3, 4, 5)
# 求和
def func(*args):
    sum = 0
    for i in args:
        sum += i
    return sum


res = func(1, 2, 3, 4)
print(res)  # => 10
res1 = func(1, 2, 3, 4, 5)
print(res1)  # => 15

* 在实参 

def func(x, y, z):
    print(x, y, z)


# *会将后面的多个值打散,打散成为位置实参,相当于func(1,2,3)
func(*[1, 2, 3])  # => 1 2 3

*在形参中表示可变长度的位置参数,它会把多个值处理成为元祖.然后赋值给后面的形参名.

*在实参中间有打散的作用,打散成为位置实参

*在形参中也在实参中

def func(x, y, *args):
    print(x, y, args)


func(*"愿疫情早点结束!")  # 愿 疫 ('情', '早', '点', '结', '束', '!')
  6.3.4.2 可变长度的关键字参数

用法:**kwargs,它就是用于接收多出来的关键字实参的,**会将多出来的关键字实参处理成字典格式.然后赋值给**后面的形参名

无论是*还是**,都是用来接收溢出的实参的,所以一定要放在参数的最后,放在位置形参和默认形参之后

def func(x, y, **kwargs):  # kwargs={'a': 3, 'b': 4, 'c': 5, 'name': '张大仙'}
    print(x, y, kwargs)  # => 1 2 {'a': 3, 'b': 4, 'c': 5, 'name': '张大仙'}


func(x=1, y=2, a=3, b=4, c=5, name="张大仙")

**在形参中表示可变长度的关键字参数,它会把多个值处理成为字典.然后赋值给后面的形参名.

**在实参中间有打散的作用,打散成为关键字实参

def func(x, y, z):
    print(x, y, z) # 1 2 3


func(**{"x":1,"y":2,"z":3}) # => func(x=1,y=2,z=3)
def func(x, y, **kwargs):
    print(x, y, kwargs)  # => 1 2 {'z': 3}


func(**{"x": 1, "y": 2, "z": 3})  # 等价于 func(x=1,y=2,z=3)

6.3.5 可变参数混用

我们调用函数进行传参的时候,有多出来的位置实参,也有多出来的关键字实参,这个时候就涉及到*和**的混用.而此时**kwargs必须在*args之后 

def func(x, y=1, *args, **kwargs):
    print(args)  # => (1, 2, 3, 4)
    print(kwargs)  # => {'a': 1, 'b': 2, 'c': 3}


func(1, 2, 1, 2, 3, 4, a=1, b=2, c=3)

6.3.6 命名关键字形参(命名关键字参数)

pass

6.4 函数重中之重

def func1(x, y, z, s):
    print("func1>>", x, y, z, s)


# 这样就将传递给func2的参数,原封不动的传递给了func1
def func2(*args, **kwargs):  # args=(1,2,3,4)
    func1(*args, **kwargs)  # func1(1,2,3,4)


func2(1, 2, 3, 4)  # => func1>> 1 2 3 4

6.5 名称空间和作用域

名称空间就是用来存名字的.

我们定义x=5,在内存里面就涉及到两个空间,栈区和堆区.首先会在堆区里面申请一个名称空间将5存进去.并将这个内存地址绑定给栈区里面的变量名x.栈区里面就是存储名字的

名称空间其实是将栈区里面的名字做了一个分类,或者说是将栈区里面的名字分成了几块:内置名称空间,全局名称空间,局部名称空间.当栈区里面有了名称空间之后,栈区里面分成了不同的区域,不同区域里面存储相同的变量名称也不会发生冲突.

作用域:

在名称空间的基础上,按照作用范围的不同,将它们重新做了分类.内置名称空间和全局名称空间都被归为全局作用域,局部名称空间被归为局部作用域.

6.5.1 内置名称空间

存放python解释器内置名字的地方,内置名称空间只有一个内置名称空间,也就是说python解释器一启动就会创建内置名称空间.,让我们可以在任何位置使用内置名称空间里面的名字.python解释器关闭,内置的名称空间就会被销毁.

运行python程序有三个阶段

1)python解释器启动: 产生内置的名字

2)python解释器将文件内容,当做普通文本内容读入到内存.

3)识别python语法,运行代码,产生变量名产生函数名产生模块名  

6.5.2 全局名称空间

全局名称空间:Python文件内定义的变量名,包括函数名,类名,以及导入的模块名.既然python里面定义的名字是存放在全局名称空间里面的,那么就是说有多个pyhton文件就会有多个全局名称空间.全局名称空间可以有多个.但是这里要排除掉函数内部定义的名字(包括函数参数)

只要不是函数内部定义的名字,也不是内置的名字,剩下的都是全局名称空间里面的名字

全局名称空间它会在python文件执行之前产生,python文件运行完毕后销毁

6.5.3 局部名称空间

函数内部定义的名字(包括函数参数)

而局部名称空间会在函数调用时产生,就是运行函数子代码的时候产生,函数调用结束后销毁.局部名称空间也可以有很多个,调用一个产生一个.

名称空间加载顺序:

python解释器启动会加载内置名称空间,python解释器将文件内容,当做普通文本内容读入到内存.然后加载全局名称空间.加载完毕,识别python语法执行代码.调用函数产生名称空间

6.6 名字查找顺序

有了名称空间之后,不同名称空间的相同名字是不会相互影响的,但是名称空间的查找优先级?

局部名称空间>全局名称空间>内置名称空间

def func():
    print(x)


x = 10
func()  # => 10

加载内置名称空间->加载全局名称空间->将func丢入全局(函数在定义阶段只会检测语法,不会执行函数子代码)将x=10丢入全局,调用func时,全局存在x.

x = 10


def func1():
    print(x)


def func2():
    # print(x)
    x = 20
    func1()


func2() # => 10

名称空间的查找顺序是以定义阶段为基准的,和调用的位置没有任何关系

6.7 函数的嵌套

名字的查找是以定义阶段为基准的

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

七彩虹@电脑cpu频率上不去问题@控制中心性能模式cpu频率上不去@代理服务器超时@账户同步设置失败

文章目录 windows电脑cpu频率上不去新电脑的系统时间问题系统时间不准造成的具体问题举例代理超时vscode同步请求失败自动校准时间 windows电脑cpu频率上不去 问题描述,标压处理器的笔记本,cpu频率上不去 如果cpu没问题的话,就应该是系统限制了功耗导致的有的笔记本有控制中心…

本鲸:打造科技招商新引擎、实现政企资源高效对接

在当今这个快速变化的时代,科技创新已成为推动社会进步和经济发展的核心动力。本鲸,作为科技创新创业服务的平台,正以其独特的视角和专业服务,为政府和企业提供一站式科技招商解决方案,助力构建创新驱动的经济发展新模…

b站小土堆pytorch学习记录—— P27-P29 完整的模型训练套路

文章目录 一、定义模型(放在model.py文件中)二、训练三、测试四、完整的训练和测试代码 一、定义模型(放在model.py文件中) import torch from torch import nnclass Guodong(nn.Module):def __init__(self):super(Guodong,self)…

在vue2中使用tailwindcss(完整教程)

如果你看过好多教程之后,还是报错,无法使用tailwindcss,我希望本教程可以让你成功上岸。 环境要求 node:>v14.17.0 安装tailwindcss 由于最新的tailwind css使用post css 8版本,vue2框架暂时还不支持&#xff0…

Springboot + Vue用户管理系统

Springboot Vue用户管理系统 主要实现了管理员的登录,用户管理,用户的增删改查等操作, 技术实现,前端采用Vue 后端采用Springboot ,前后端分离系统,数据库使用mysql 还用到了redis,mybatis-plus。。。。。。。。。…

10大主流压力/负载/性能测试工具推荐

在移动应用和Web服务正式发布之前,除了进行必要的功能测试和安全测试,为了保证互联网产品的服务交付质量,往往还需要做压力/负载/性能测试。然而很多传统企业在试水互联网的过程中,往往由于资源或产品迭代速度等原因忽视了这一块工…

【Python】科研代码学习:三 PreTrainedModel, PretrainedConfig, PreTrainedTokenizer

【Python】科研代码学习:三 PreTrainedModel, PretrainedConfig, PreTrainedTokenizer 前言Models : PreTrainedModelPreTrainedModel 中重要的方法 tensorflow & pytorch 简单对比Configuration : PretrainedConfigPretrainedConfig 中重要的方法 Tokenizer : …

influxdb2.0插入数据字段类型出现冲突问题解决

一、问题出现 一个学校换热站自控系统,会定时从换热站获取测点数据,并插入到influxdb数据库中。influxdb插入数据时,报错提示: com.influxdb.exceptions.UnprocessableEntityException: failure writing points to database: par…

组合逻辑电路(二)(译码器和编码器)

目录 译码器 简单逻辑门译码器 二进制译码器 2线-4线译码器 3线-8线译码器 二-十进制译码器 4线-10线译码器 七段显示译码器 编码器 二进制普通编码器 二-十进制普通编码器(8421BCD码编码器) 优先编码器(Priority Encoder) 译…

《解密云计算:企业之选》

前言 在当今数字化时代,企业面临着巨大的数据处理压力和信息化需求,传统的IT架构已经无法满足日益增长的业务需求。在这样的背景下,越来越多的企业开始转向云计算,以实现灵活、高效和可扩展的IT资源管理和利用。 云计算 云计算是…

【QT中如何生成导出.exe可执行文件并打包给其他人使用】

1、将QT的部署设置改成Release编译模式。 2、运行项目生成release文件夹,其中包含.exe文件。 3、新建空文件夹,将release文件夹中的.exe文件复制到里面去。(此处新建了hellofile空文件夹来存放hello.exe文件) 4、在QT终端里&#…

SpringBoot学习之自定义注解和AOP 切面统一保存操作日志(二十九)

一、定义一个注解 这个注解是用来控制是否需要保存操作日志的自定义注解(这个类似标记或者开关) package com.xu.demo.common.anotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; i…

Filter过滤器+JWT令牌实现登陆验证

一、背景 我们需要在客户端访问服务器的时候给定用户一定的操作权限,比如没有登陆时就不能进行其他操作。如果他需要进行其他操作,而在这之前他没有登陆过,服务端则需要将该请求拦截下来,这就需要用到过滤器,过滤器可以…

【YOLO v5 v7 v8 v9小目标改进】AFPN 渐进式特征金字塔网络:解决多尺度特征融合中,信息在传递过程丢失

AFPN 渐进式特征金字塔网络:解决多尺度特征融合中,信息在传递过程丢失 提出背景AFPN 多尺度特征金字塔 非邻近层次的直接特征融合 自适应空间融合操作 小目标涨点YOLO v5 魔改YOLO v7 魔改YOLO v8 魔改YOLO v9 魔改 提出背景 论文:https:…

复试人工智能前沿概念总结

1.大模型相关概念(了解即可) 1.1 GPT GPT,全称为Generative Pre-training Transformer,是OpenAI开发的一种基于Transformer的大规模自然语言生成模型。GPT模型采用了自监督学习的方式,首先在大量的无标签文本数据上进…

力扣hot100题解(python版55-59题)

55、全排列 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1: 输入:nums [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示例 2: 输入&…

论文研读笔记1:

1.Improving Domain-Adapted Sentiment Classification by Deep Adversarial Mutual Learning: 1.1本篇论文提出了一种名为深度对抗性互学习(Deep Adversarial Mutual Learning, DAML)的新方法,用于改进领域适应性情感分类。 对…

使用 Cypress 进行可视化回归测试:一种务实的方法

每次组件库 Picasso 发布新版本时,都会更新所有的前端应用程序,让绝大部分新功能能与整个平台的设计保持一致。上个月,推出了 Toptal Talent Portal 的 Picasso 更新,这是我们的用户用来找工作和与客户互动的平台。 已知了这个版本…

C++指针(四)万字图文详解!

个人主页:PingdiGuo_guo 收录专栏:C干货专栏 前言 相关文章:C指针(一)、C指针(二)、C指针(三) 本篇博客是介绍函数指针、函数指针数组、回调函数、指针函数的。 点赞破六…

结构体和malloc学习笔记

结构体学习: 为什么会出现结构体: 为了表示一些复杂的数据,而普通的基本类型变量无法满足要求; 定义: 结构体是用户根据实际需要自己定义的符合数类型; 如何使用结构体: //定义结构体 struc…