100 个鲜为人知的 Python 高级技巧 0-20

news2024/12/26 21:52:59

100 鲜为人知的 Python 功能

这篇文章是为那些每天使用 Python,但从未真正坐下来通读所有文档的人准备的。

如果您已经使用 Python 多年,并且知道足够多的知识来完成工作,那么为了发现一些新技巧而通读几千页的文档可能不是明智之举。

因此,我列出了一个简短的(比较而言)功能列表,其中包括一些未被广泛使用,但广泛适用于一般编程任务的功能。

当然,这份清单会包含一些你已经知道的东西,也有一些你永远不会用到的东西,但我希望其中有一些对你来说是新的和有用的。

首先,做一下内务整理:

使用的 Python 3.8或以上版本。对于在此之后添加的一些功能,我会说明它们是何时添加的;

列表没有严格的顺序,但更基本的特性会放在开头;

如果你想消除我的好奇心,回复序号显示你认为有用的功能的标题。 现在,开始列表...

  1. help(x)

help 可以接收字符串、对象或任何内容。对于类实例,它会收集所有父类的方法,并显示哪些方法是从哪里继承来的(以及方法的解析顺序)。

当你想得到一些难以搜索的帮助时,比如^,这也很有用。

输入 help('^') 比查找 Python 文档中描述 ^ 如何工作的部分要快得多。

Operator precedence
*******************

The following table summarizes the operator precedence in Python, from
highest precedence (most binding) to lowest precedence (least
binding).  Operators in the same box have the same precedence.  Unless
the syntax is explicitly given, operators are binary.  Operators in
the same box group left to right (except for exponentiation, which
groups from right to left).

Note that comparisons, membership tests, and identity tests, all have
the same precedence and have a left-to-right chaining feature as
described in the Comparisons section.

+-------------------------------------------------+---------------------------------------+
| Operator                                        | Description                           |
|=================================================|=======================================|
"(expressions...)",  "[expressions...]""{key: | Binding or parenthesized expression,  |
| value...}"
"{expressions...}"                  | list display, dictionary display, set |
|                                                 | display                               |
+-------------------------------------------------+---------------------------------------+
"x[index]""x[index:index]",                   | Subscription, slicing, call,          |
"x(arguments...)""x.attribute"                | attribute reference                   |
+-------------------------------------------------+---------------------------------------+
"await x"                                       | Await expression                      |
+-------------------------------------------------+---------------------------------------+
"**"                                            | Exponentiation [5]                    |
+-------------------------------------------------+---------------------------------------+
"+x""-x""~x"                                | Positive, negative, bitwise NOT       |
+-------------------------------------------------+---------------------------------------+
"*""@""/""//""%"                        | Multiplication, matrix                |
|                                                 | multiplication, division, floor       |
|                                                 | division, remainder [6]               |
+-------------------------------------------------+---------------------------------------+
"+""-"                                        | Addition and subtraction              |
+-------------------------------------------------+---------------------------------------+
"<<"">>"                                      | Shifts                                |
+-------------------------------------------------+---------------------------------------+
"&"                                             | Bitwise AND                           |
+-------------------------------------------------+---------------------------------------+
"^"                                             | Bitwise XOR                           |
+-------------------------------------------------+---------------------------------------+
"|"                                             | Bitwise OR                            |
+-------------------------------------------------+---------------------------------------+
"in""not in""is""is not""<""<="">", | Comparisons, including membership     |
">=""!=""=="                                | tests and identity tests              |
+-------------------------------------------------+---------------------------------------+
"not x"                                         | Boolean NOT                           |
+-------------------------------------------------+---------------------------------------+
"and"                                           | Boolean AND                           |
+-------------------------------------------------+---------------------------------------+
"or"                                            | Boolean OR                            |
+-------------------------------------------------+---------------------------------------+
"if" – "else"                                   | Conditional expression                |
+-------------------------------------------------+---------------------------------------+
"lambda"                                        | Lambda expression                     |
+-------------------------------------------------+---------------------------------------+
":="                                            | Assignment expression                 |
+-------------------------------------------------+---------------------------------------+

-[ Footnotes ]-

[1] While "abs(x%y) < abs(y)" is true mathematically, for floats it
    may not be true numerically due to roundoff.  For example, and
    assuming a platform on which a Python float is an IEEE 754 double-
    precision number, in order that "-1e-100 % 1e100" have the same
    sign as "1e100", the computed result is "-1e-100 + 1e100"which
    is numerically exactly equal to "1e100".  The function
    "math.fmod()" returns a result whose sign matches the sign of the
    first argument instead, and so returns "-1e-100" in this case.
    Which approach is more appropriate depends on the application.

[2] If x is very close to an exact integer multiple of y, it’s
    possible for "x//y" to be one larger than "(x-x%y)//y" due to
    rounding.  In such cases, Python returns the latter result, in
    order to preserve that "divmod(x,y)[0] * y + x % y" be very close
    to "x".

[3] The Unicode standard distinguishes between *code points* (e.g.
    U+0041) and *abstract characters* (e.g. “LATIN CAPITAL LETTER A”).
    While most abstract characters in Unicode are only represented
    using one code point, there is a number of abstract characters
    that can in addition be represented using a sequence of more than
    one code point.  For example, the abstract character “LATIN
    CAPITAL LETTER C WITH CEDILLA” can be represented as a single
    *precomposed character* at code position U+00C7, or as a sequence
    of a *base character* at code position U+0043 (LATIN CAPITAL
    LETTER C), followed by a *combining character* at code position
    U+0327 (COMBINING CEDILLA).

    The comparison operators on strings compare at the level of
    Unicode code points. This may be counter-intuitive to humans.  For
    example, ""\u00C7" == "\u0043\u0327"" is "False", even though both
    strings represent the same abstract character “LATIN CAPITAL
    LETTER C WITH CEDILLA”.

    To compare strings at the level of abstract characters (that is,
    in a way intuitive to humans), use "unicodedata.normalize()".

[4] Due to automatic garbage-collection, free lists, and the dynamic
    nature of descriptors, you may notice seemingly unusual behaviour
    in certain uses of the "is" operator, like those involving
    comparisons between instance methods, or constants.  Check their
    documentation for more info.

[5] The power operator "**" binds less tightly than an arithmetic or
    bitwise unary operator on its right, that is, "2**-1" is "0.5".

[6] The "%" operator is also used for string formatting; the same
    precedence applies.

Related help topics: lambda, or, and, not, in, is, BOOLEAN, COMPARISON,
BITWISE, SHIFTING, BINARY, FORMATTING, POWER, UNARY, ATTRIBUTES,
SUBSCRIPTS, SLICINGS, CALLS, TUPLES, LISTS, DICTIONARIES, BITWISE

  1. 1_000_000

您可以使用下划线作为千位分隔符。这使得大数字更易读。

x = 1_000_000

你也可以用这种方式格式化一个数字:

assert f"{1000000:_}" == "1_000_000"
print(f"{1000000:_}")
1_000_000
  1. str.endswith() 取一个元组
if filename.endswith((".csv"".xls"".xlsx"))
    # 做一些事情

startswith() 也是如此,👇是文档中的 endswith

https://docs.python.org/3/library/stdtypes.html#str.endswith

  1. isinstance() 获取一个元组

如果要检查对象是否是多个类的实例,不需要多个 isinstance 表达式,只需传递一个类型元组作为第二个参数即可。

Python 3.10 开始 - 使用联合:

assert isinstance(7, (float, int))
assert isinstance(7, float | int)

关于 isinstance 和 union 类型的更多信息:

alt

https://docs.python.org/3/library/functions.html#isinstance

https://docs.python.org/3/library/stdtypes.html#types-union

  1. ...是一个有效的函数体

我用...表示 "我很快就会处理这个问题"(在提交任何更改之前),用 pass 表示更接近于无操作的意思。

def do_something():
    ...
  1. 海象运算符 :=

海象运算符(又名赋值表达式)允许你为变量赋值,但以表达式的形式赋值,这意味着你可以对结果值做一些事情。

这在 if 语句中非常有用,在 elif 语句中更是如此:

if first_prize := get_something():
    ...  # 对 first_prize 执行操作
elif second_prize := get_something_else():
    ...  # 对 second_prize 进行处理

请记住,如果要将结果与其他内容进行比较,则需要用括号将 walrus 表达式包起来,如下所示:

if (first_prize := get_something()) is not None:
    ...  # 对 first_prize 进行操作
elif (second_prize := get_something_else()) is not None:
    ...  # 对 second_prize 进行处理

借用原始 PEP 中的一个例子,这些可以用在很多地方:

filtered_data = [y for x in data if (y := f(x)) is not None]

如果 (y := f(x)) 不是 None

  • 语义分析文档 参见文档中的赋值表达式: https://docs.python.org/3/reference/expressions.html#assignment-expressions
  1. attrgetter 和 itemgetter

如果需要根据对象的特定属性对对象列表进行排序,可以使用 attrgetter(当需要的值是属性时,例如类实例)或 itemgetter(当需要的值是索引或字典键时)。

例如,按 "score "键对字典列表进行排序:

from operator import itemgetter

scores = [
    {"name""Alice""score": 12},
    {"name""Bob""score": 7},
    {"name""Charlie""score": 17},
]

scores.sort(key=itemgetter("score"))

assert list(map(itemgetter("name"), scores)) == ["Bob""Alice""Charlie"]

attrgetter 与之类似,在不使用点符号的情况下使用。它还可以嵌套访问,例如下面例子中的 name.first:

class Name(NamedTuple):
    first: str
    last: str

class Person(NamedTuple):
    name: Name
    height: float

people = [
    Person(name=Name("Gertrude""Stein"), height=1.55),
    Person(name=Name("Shirley""Temple"), height=1.57),
]

first_names = map(attrgetter("name.first"), people)

assert list(first_names) == ["Gertrude""Shirley"]
There’s also a methodcaller that does what you might g

还有一个 methodcaller 你可能猜到的功能。如果您不知道 NamedTuple 的作用,请继续阅读...

  • 语义分析文档

更多信息,请参阅操作符模块文档 https://docs.python.org/3/library/operator.html

  1. 作为函数的运算符

所有我们熟悉的运算符,如 +、< != 在运算符模块中都有对应的函数。在对集合进行迭代时。

例如使用 is_not 查找两个列表之间的不匹配时,这些操作符非常有用:

import operator

list1 = [1, 2, 3, 4]
list2 = [1, 2, 7, 4]

matches = list(map(operator.is_not, list1, list2))

assert matches == [False, False, True, False]
Here’s a table of operators and their function

下面是运算符及其功能对应表:

https://docs.python.org/3/library/operator.html#mapping-operators-to-functions

alt
alt
  1. 按值对字典排序

您可以使用 key 对 dictionary 按其值排序。在这种情况下,你传递给 key 的函数将被 dict 的每个键调用,并返回一个值,这与字典的 get 方法的作用相同。

my_dict = {
    "Plan A": 1,
    "Plan B": 3,
    "Plan C": 2,
}

my_dict = {key: my_dict[key] for key in sorted(my_dict, key=my_dict.get)}

assert list(my_dict.keys()) == ['Plan A''Plan C''Plan B']
  • 语义分析文档
  1. 从元组创建 dict

dict() 可以接收键/值对的元组序列。因此,如果你有键和值的列表,你可以把它们压缩在一起,变成一个字典:

keys = ["a""b""c"]
vals = [1, 2, 3]

assert dict(zip(keys, vals)) == {'a': 1, 'b': 2, 'c': 3}
  • 语义分析文档:

https://docs.python.org/3/library/stdtypes.html#mapping-types-dict

  1. 用 ** 组合 dict

通过使用 ** 操作符将 dict 解压缩到 dict 字面的主体中,可以组合字典:

sys_config = {
    "Option A": True,
    "Option B": 13,
}

user_config = {
    "Option B": 33,
    "Option C""yes",
}

config = {
    **sys_config,
    **user_config,
    "Option 12": 700,
}

这里的 user_config 将优先于 sys_config,因为它在后面。

  • 语义分析文档的词典解包:

https://docs.python.org/3/reference/expressions.html#dictionary-displays

  1. 用 |= 更新字典

如果你想扩展一个现有的 dict,而不是一个键一个键地扩展,可以使用 |= 操作符。

config = {
    "Option A": True,
    "Option B": 13,
}

later 这是在 Python 3.9 中添加的:

config |= {
    "Option C": 7,
    "Option D""bananas",
}

合并后:

{'Option A': True, 'Option B': 13, 'Option C': 7, 'Option D''bananas'}
  • 语义分析文档

https://docs.python.org/3/whatsnew/3.9.html#dictionary-merge-update-operators

  1. defaultdicts 或 setdefault

假设您想从一个 dict 列表创建一个列表的 dict。一个简单的方法可能是创建一个占位符 dict,然后在循环的每一步都检查是否需要创建一个新的 key。

pets = [
    {"name""Fido""type""dog"},
    {"name""Rex""type""dog"},
    {"name""Paul""type""cat"},
]

pets_by_type = {}

不推荐的写法:

for pet in pets:
    # 如果类型还不是一个关键字
    # 需要用一个空列表来创建它
    if pet["type"] not in pets_by_type:
        pets_by_type[pet["type"]] = []

    # 现在我们可以安全地调用 .append()
    pets_by_type[pet["type"]].append(pet["name"])

assert pets_by_type == {'dog': ['Fido''Rex'], 'cat': ['Paul']}

一种更简洁的方法是创建默认字典。

在下面的代码中,当我试图读取一个不存在的键时,它会自动创建一个默认值为空列表的键。

pets_by_type = defaultdict(list)

for pet in pets:
    pets_by_type[pet["type"]].append(pet["name"])

缺点是你需要导入 defaultdict,而且如果你想在最后得到一个真正的 dict,你需要执行 dict(pets_by_type)。

另一种方法是使用普通 dict,并使用名称奇怪的 .setdefault()

pets_by_type = {}

for pet in pets:
    pets_by_type.setdefault(pet["type"], []).append(pet["name"])

将 "设置默认值 "理解为 "获取,但在需要时设置默认值"。

提示:你可以使用 defaultdict(lambda: None) 创建一个在键不存在时返回 None 的 dict。

  • 语义分析文档 default dict👇

https://docs.python.org/3/library/collections.html#collections.defaultdict

  1. 用于...类型 dict 的 TypedDict

如果你想为你的 dict 的值定义类型,你可以使用以下方法

class Config(TypedDict):
    port: int
    name: str

config: Config = {
    'port': 4000,
    'name''David',
    'unknown': True,  # warning, wrong type
}

port = config["poort"]  
# warning, what's a poort?

根据你的集成开发环境(我用的是 PyCharm),你会得到正确的自动完成建议(类型不只是为了健壮代码,也是为了偷懒,减少输入字符)。

alt

我发现这对于向来自其他来源的字典中添加类型特别有用。如果我想为自己创建的对象添加类型,我很少会使用 dict。

  • 语义分析文档 TypedDict👇 https://docs.python.org/3/library/typing.html#typing.TypedDict

15、a // b 并不总是返回 int

假设有一个函数可以将一个列表分割成一定数量的批次。你能发现这段代码中的潜在错误吗?

def batch_a_list(the_list, num_batches):
    batch_size = len(the_list) // num_batches
    batches = []

    for i in range(0, len(the_list), batch_size):
        batches.append(the_list[i : i + batch_size])

    return batches

my_list = list(range(13))

batched_list = batch_a_list(my_list, 4)

错误将引发 TypeError:batch_a_list(my_list,4)

出现问题的原因是,当 num_batches 是一个浮点数时,len(the_list)``// num_batches 返回的也是一个浮点数,这不是一个有效的索引,因此会引发错误。

具体地说,如果 // 的任意一边都是浮点数,那么两边都将转换为浮点数,结果也将是浮点数。

文档👇

https://docs.python.org/3.3/reference/expressions.html#:~:text=of%20their%20arguments.-,The%20numeric%20arguments%20are%20first%20converted%20to%20a%20common%20type,-.%20Division%20of%20integers

int(a / b) 是更安全的选择。

  • 语义分析文档中提到了这一点,但并不是特别清楚。
  1. 循环引用可以不使用 "from"

你可以让两个模块分别导入另一个模块,这并不是错误。事实上,我觉得这样很好。

只有当其中一个模块从另一个模块导入某些内容时,才会出现问题。因此,如果出现循环引用错误,请考虑从有问题的导入中删除 from。

编程常见问题: 在模块中使用 import 的 "最佳实践 "是什么?

  1. 使用 or 设置默认值

假设有一个带有可选参数的函数。默认值应该是空列表,但不能在函数签名中设置(所有对函数的调用都将共享同一个列表),因此需要在函数体中设置默认值。

你不需要像我经常看到的那样对 None 进行两行检查:

def make_list(start_list: list = None):
    if start_list is None:
        start_list = []
    ...

您可以直接使用 or

def make_list(start_list: list = None):
    start_list = start_list or []
    ...

如果 start_list 是真实的(非空 list),就会被使用,否则就会被设置为空 list。

只有在调用函数时不会使用 bool(value) == False 的值时,这种方法才是合理的。

  • 语义分析文档:

https://docs.python.org/3/reference/expressions.html#boolean-operations

  1. 使用 default_timer 作为......默认计时器 在 Python 中有很多获取时间的方法 default timer。

如果您的计划是计算两个时间点之间的差值,下面是一些不正确的方法:

# 错误
start_time = datetime.now()
start_time = datetime.today()
start_time = time.time()
start_time = time.gmtime()
start_time = time.localtime()

错误较少,但在 Windows 上会失败

# 错误较少,但在 Windows 上会失败
start_time = time.clock_gettime(1)
start_time = time.clock_gettime(time.CLOCK_MONOTONIC)

同理你并不希望时间倒退,但上述前五种方法允许出现这种情况(夏令时、闰秒、时钟调整等)。

由于认为时间不会倒退而导致的错误很少见,但确实存在,而且很难追查。

最好的方法是:

start_time = timeit.default_timer()

这个方法很容易记住,而且能给出一个不会倒退的时间。

从 Python 3.11 开始,它指向 time.perf_counter,所以还有两个值得一提的方法:

start_time = time.perf_counter()
start_time = time.perf_counter_ns() # 纳秒
  • 语义分析文档

文档中的 default_timer https://docs.python.org/3/library/timeit.html#timeit.default_timer

  1. 解释器中的' _':最后的结果

如果你执行了某些操作,输出了一个值,现在你想对输出结果做一些事情,这就很方便了。

get_some_data() 
# 运行需要一段时间
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16、
       17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
       34, 35, 36, 37, 38, 39])
_.mean()

19.5

type(_) 是我经常使用的另一种类型。

但要注意的是,你只能使用一次,因为你将会有一个新的输出,这就是 _ 所指向的内容。对于 IPython 用户,可以输入 _4 来指代 Out[4]

代码展示了 '_' 在 Python 交互式解释器中的一些常见用法。

首先,执行一个函数 get_some_data(),它返回一个数组。这个数组被打印出来。

然后,我们想基于这个数组再做一些操作。通常我们需要把数组赋值给一个变量,然后在变量上操作。但是 '_' 允许我们直接引用最后一个打印的输出。

所以我们调用 _.mean() 来直接计算刚刚那个数组的平均值。

这样可以避免定义一个临时变量来存储之前的输出'_' 总是引用最后一个输出值。

另外,使用 type(_) 可以快速查看最后一个输出的类型。

'_ _',双下划线:还可以用于一些其他特殊用途,比如数字字面量中的分隔符(1_000_000),或者作为占位变量名:

for _ in range(10)

总之, '' 在交互式编程中非常方便,可以避免定义不必要的临时变量。需要注意它只引用最近的一个输出,后面新的输出会覆盖之前的 ''。

  • 语义分析文档

_ 还有其他作用,更多内容请参见词法分析文档,以及下一节...

https://docs.python.org/3/reference/lexical_analysis.html#reserved-classes-of-identifiers

  1. *_ 用来收集不需要的元素 如果您调用的函数返回一个元组中的多个值,但您只想要第一个值,您可以在调用时追加 [0],或者使用 *_ 忽略其他返回值:

def get_lots_of_things(): return "Puffin", (0, 1), True, 77

bird, *_ = get_lots_of_things()

  • 表示迭代解包。单个下划线是未使用变量的约定(当变量名为 _ 时,大多数类型/样式检查程序不会给出 "未使用变量 "警告)。
  • 语义分析文档

PEP 3132 中定义了这一行为。

21.dict.key 键不必是字符串

各种各样的东西都可以成为 dict 键:函数、元组、数字--任何可散列的东西。

比方说,你想用 dict 表示一个图Graph,其中每个键都是一对节点,而值则描述它们之间的边。

你可以用元组来表示,但如果你想让(a, b) 返回与(b, a))相同的值,你就需要一个集合。

集合不可散列,但frozen_set可以,因此我们可以使用


graph = {
    frozenset(["a""b"]): "a 和 b 之间的边",
    frozenset(["b""c"]): "b 和 c 之间的边"
        }

assert graph[frozenset(["b""a"])] == graph[frozenset(["a""b"])]

很明显,如果你想为实数做这件事,你应该做类似扩展 dict 这样的事情:

class OrderFreeKeys(dict):
    def __getitem__(self, key):
        return super().__getitem__(frozenset(key))

    def __setitem__(self, key, value):
        return super().__setitem__(frozenset(key), value)

graph = OrderFreeKeys()

graph["A""B"] = "A 和 B 之间有一条边"

assert graph["B""A"] == "A 和 B 之间有一条边"

print(graph["A""B"])

第二个示例中的 A 和 B 使用了大写字母,因为多样性是生活的调味品。

本文由 mdnice 多平台发布

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

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

相关文章

IPC进程间通信探索——管道的原理与特点

&#x1f923; 爆笑教程 &#x1f449; 《看表情包学Linux》 &#x1f525; CSDN 累计订阅量破千的火爆 C/C 教程的 2023 重制版&#xff0c;C 语言入门到实践的精品级趣味教程。了解更多&#xff1a; &#x1f449; "不太正经" 的专栏介绍 ← 试读第一章订阅链接&am…

Babel编译与Webpack

目录 Babel初识BabelBabel 使用方式使用 Babel 前的准备工作 WebpackWebpack介绍Webpack初体验Webpack核心概念入口&#xff08;entry&#xff09;出口&#xff08;output&#xff09;加载 (loader)插件&#xff08;plugins&#xff09; Babel Babel官网: https://babeljs.io/…

贝锐蒲公英:没有公网IP,多分支企业如何高效远程访问OA系统?

贝锐蒲公英&#xff1a;没有公网IP&#xff0c;多分支企业、移动办公人员如何高效远程访问OA系统&#xff1f; 国内某大型美妆公司&#xff0c;旗下产品覆盖美容护肤品、彩妆、美容仪器、健康食品、SPA美容会所及等多类服务&#xff0c;致力于为客户提供高品质的产品和完善的服…

Centos7搭建Apache Storm 集群运行环境

文章目录 1. 安装 Java2. 下载并解压 Storm3. 配置环境变量4. 配置 ZooKeeper5. 配置 Stormstorm.yaml自定义 storm.yamlstorm-env.shlogback/cluster.xml 6. 启动 Storm 集群7. 验证 1. 安装 Java Storm 运行在 Java 平台上&#xff0c;因此需要先安装 Java。你可以使用以下命…

C++ 类的友元

【例1】 将数据与处理数据的函数封装在一起&#xff0c;构成类&#xff0c;既实现了数据的共享又实现了隐藏&#xff0c;无疑是面向对象程序设计的一大优点。但是封装并不总是绝对的。现在考虑一个简单的例子&#xff0c;就是Point类&#xff0c;每一个Point类的对象代表一个“…

《零基础入门学习Python》第075讲:GUI的终极选择:Tkinter12

Tkinter 的基本组件我们已经介绍得七七八八了&#xff0c;剩下的一些我们在这节课全部都会讲解完毕。 &#xff08;一&#xff09;Message组件 Message&#xff08;消息&#xff09;组件是 Label 组件的变体&#xff0c;用于显示多行文本消息。众所周知&#xff0c;我们的Lab…

简单的Kubernetes集群二进制方式部署

Kubernetes二进制方式部署 一&#xff1a;操作系统初始化配置&#xff08;所有机子&#xff09;关闭防火墙关闭selinux关闭swap根据规划设置主机名在master添加hosts调整内核参数时间同步 二&#xff1a;部署 etcd 集群1.准备签发证书环境#准备cfssl证书生成工具生成Etcd证书编…

在SIP 语音呼叫中出现单通时要怎么解决?

在VoIP的环境中&#xff0c;特别是基于SIP通信的环境中&#xff0c;我们经常会遇到一些非常常见的问题&#xff0c;例如&#xff0c;单通&#xff0c;注册问题&#xff0c;回声&#xff0c;单通等。这些问题事实上都有非常直接的排查方式和解决办法&#xff0c;用户可以按照一定…

Quartz中集群模式源码级解析

文章目录 案例搭建 案例搭建 创建一个JOB实现类 package org.quartz.examples.example13;import org.quartz.*;import java.util.Date;/*** This job has the same functionality of SimpleRecoveryJob except that this job implements is stateful, in that it* will have …

Spring框架——IOC配置文件方式

Spring框架的概述和入门 目录 Spring框架的概述和入门 什么是Spring框架 Spring框架的特点 Spring框架的IOC核心功能快速入门 Spring框架中的工厂&#xff08;了解&#xff09; Spring 创建Bean对象的三种方式 Spring框架的Bean管理的配置文件方式 Spring框架中标签的配…

Token与Cookie、Session登录机制

Cookie 背景 Web 的兴起&#xff08;所谓交互式就是你不光可以浏览&#xff0c;还可以登录&#xff0c;发评论&#xff0c;购物等用户操作的行为&#xff09;&#xff0c;单纯地浏览 web 已经无法满足人们的要求&#xff0c;比如随着网上购物的兴起&#xff0c;需要记录用户的…

寻找丢失数字:数学与位运算的解密之旅

本篇博客会讲解力扣“268. 丢失的数字”的解题思路&#xff0c;这是题目链接。 注意进阶中的描述&#xff1a;你能否实现线性时间复杂度、仅使用额外常数空间的算法解决此问题&#xff1f;这里我会讲解两种思路&#xff0c;它们的时间复杂度是O(N)&#xff0c;空间复杂度是O(1)…

STM32F1基于标准库ST7735 1.8‘‘LCD显示DHT11数据

STM32基于标准库ST7735 1.8‘’LCD显示DHT11数据 &#x1f4cd;HAL库驱动可以参考&#xff1a;《STM32基于HAL工程读取DHT11数据》&#x1f33c;显示效果&#xff1a; &#x1f33b;ST7735 128x160 1.8’LCD屏幕 &#x1f4cc;屏幕资料和相关驱动可以参考《1.8寸TFT LCD128…

JDK各版本重要变革

各版本更新详情 JDK8(LTS)--2014/3 语法层面 lambda表达式(重要特色之一) 一种特殊的匿名内部类,语法更加简洁允许把函数作为一个方法的参数,将代码象数据一样传递&#xff0c;即将函数作为方法参数传递基本语法: <函数式接口> <变量名> (参数...) -> { 方法…

迷你主机中的战斗机 Intel NUC 12 Serpent Canyon拆解

千呼万唤始出来&#xff0c;新一代游戏和创作者性能怪兽 mini主机 NUC 12 Serpent Canyon&#xff08;巨蛇峡谷终于发售了&#xff0c;以超紧凑的 2.5 升尺寸提供用户所需的所有性能和创新功能。NUC 12 Enthusiast 还首次将 Intel Deep Link 引入桌面&#xff0c;使 CPU 和 GPU…

类的继承和super关键字的使用(JAVA)

继承 所有的OOP语言都会有三个特征&#xff1a; 封装&#xff08;点击可跳转&#xff09;&#xff1b;继承&#xff1b;多态 为什么会有继承呢&#xff1f;可以先看下面的例子&#xff1a; 上面这两个类中的代码很相似因为它们只有最后一个方法不同其它的都相同&#xff0c;这样…

DbVisualizer Pro Crack

DbVisualizer Pro Crack DbVisualizer是适用于开发人员、DBA和分析师的通用数据库工具。它是最终的解决方案&#xff0c;因为相同的工具可以在访问各种数据库的所有主要操作系统上使用。支持的数据库Amazon Redshift、DB2 LUW、Exasol、H2、Informix、JavaDB/Derby、Microsoft …

【项目 进程10】2.21 alarm函数 2.22setitimer定时器函数

2.21 alarm函数 #include <unistd.h> unsigned int alarm(unsigned int seconds);功能&#xff1a;设置定时器&#xff08;闹钟&#xff09;。函数调用&#xff0c;开始倒计时&#xff0c;当倒计时为0的时候&#xff0c; 函数会给当前的进程发送一个信号&#xff1a;SIG…

C++中内存的动态管理

我们在C语言中了解到可以在栈区动态开辟空间&#xff0c;并且用完要进行释放&#xff0c;防止内存泄漏。 引入 C中也有可以进行动态开辟空间和释放空间的操作符new 、delete&#xff0c;虽然C中也可以用malloc、calloc、realloc、free函数&#xff0c;但是C中引入了类&#x…

宋浩概率论笔记(二)随机变量

本章节内容较多&#xff0c;是概率论与数理统计中最为重要的章节&#xff0c;对于概率密度和分布函数的理解与计算要牢牢掌握&#xff0c;才能在后期的学习中更得心应手。