了解函数式编程:从表象到本质,从技法到心法

news2024/9/23 18:34:28

今天看到,《代码整洁之道》(Clean Code)和《架构整洁之道》(Clean Architecture)的作者Robert C. Martin在讨论函数式编程时曾提到:

函数式编程不仅仅是“用函数编程”。函数式编程是没有赋值语句的编程。

一旦你尝试不用赋值语句编程,函数式编程的所有其他特性就水到渠成了。你要处理函数,就必须用递归,所有这些东西在你决定不用赋值的那一刻,就自然而然地形成了。所以说,函数式编程就是这么回事。 ——《函数式设计》,Robert C. Martin

于是,萌发了写一篇聊函数式编程文章的想法。

初识函数式编程

函数式编程(Functional Programming, FP)是一种基于数学函数计算的编程范式。它强调使用纯函数、不可变性和高阶函数来解决问题。本文将通过代码示例和概念解释,带你深入了解函数式编程的核心思想和应用场景。

案例:简单的累加求和

在大部分情况下,循环可以直接用递归来代替:

传统过程式编程实现

def sum_numbers(n):
    sum = 0
    for i in range(1, n + 1):
        sum += i
    return sum

print(sum_numbers(5))  # 输出 15

函数式编程实现

def sum_numbers_functional(n):
    if n == 1:
        return 1
    else:
        return n + sum_numbers_functional(n - 1)

print(sum_numbers_functional(5))  # 输出 15

在这个例子中,通过递归的方式实现了累加求和的功能。没有使用任何赋值语句来更新状态,而是通过每次递归调用自己来逐步累积结果。

案例: 计算斐波那契数列

通常来说,算法都有递推+(iterative)和递归(recursive)两种定义,递推符合我们日常生活的思维模式,递归则是符合函数式编程的思维模式。这两种定义,也对应了下面的传统过程式编程实现和函数式编程实现。

传统过程式编程实现

def fibonacci(n):
    fib = [0, 1]
    for i in range(2, n + 1):
        fib.append(fib[i - 1] + fib[i - 2])
    return fib[n]

print(fibonacci(10))  # 输出 55

函数式编程实现

def fibonacci_functional(n):
    if n <= 1:
        return n
    else:
        return fibonacci_functional(n - 1) + fibonacci_functional(n - 2)

print(fibonacci_functional(10))  # 输出 55

在这个例子中,我们同样没有使用任何赋值语句来更新状态,而是通过递归来实现斐波那契数列的计算。需要注意的是,这种方法虽然展示了函数式编程的思想,但在实际应用中,递归方法可能不是最优的选择,因为它会导致大量的重复计算。为了解决这个问题,我们可以引入尾递归优化或使用辅助函数来缓存中间结果。

使用尾递归优化斐波那契数列

函数式编程实现(带尾递归)
def fibonacci_tail_recursive(n, a=0, b=1):
    if n == 0:
        return a
    elif n == 1:
        return b
    else:
        return fibonacci_tail_recursive(n - 1, b, a + b)

print(fibonacci_tail_recursive(10))  # 输出 55

在这个更复杂的例子中,我们引入了尾递归来优化斐波那契数列的计算。尾递归是一种特殊的递归形式,其中递归调用是函数体中的最后一个操作。这使得编译器或解释器可以在递归调用之前释放当前栈帧,从而防止堆栈溢出。这里使用了两个累积参数 ab 来传递计算的状态,而不是直接修改变量的值。需要注意的是,Python默认并不支持尾调用优化,但在支持尾调用优化的语言中,这种方法可以大大提高程序的效率。


深入函数式编程

函数式编程的几个核心概念:

  1. 纯函数(Pure Functions)

    • 纯函数的输出仅取决于输入参数,没有副作用。相同的输入总是产生相同的输出,并且不修改任何外部状态。
  2. 不可变性(Immutability)

    • 在函数式编程中,一旦创建了一个数据结构,就不能更改它的状态。所有数据都是不可变的,这意味着一旦创建了一个对象或变量,就不能直接修改它的内容,只能通过创建新的数据结构来表示状态的变化。
  3. 高阶函数(Higher-Order Functions)

    • 函数可以作为参数传递给其他函数,也可以作为其他函数的返回值。高阶函数允许我们编写抽象级别更高的代码,使得代码更加模块化和可复用。
  4. 递归(Recursion)

    • 函数式编程中经常使用递归来实现循环逻辑,而不是使用传统的循环结构。递归是一种自然的方式来表达重复的任务,特别是在处理树形结构或分治算法时。
  5. 惰性求值(Lazy Evaluation)

    • 惰性求值是指只有在真正需要的时候才计算表达式的值。这可以提高效率,特别是在处理大量数据时,因为不需要一次性加载所有数据。

为什么能去掉状态的存储?

函数式编程之所以能够去掉状态的存储,主要是因为:

  • 避免了副作用(Side Effects):在函数式编程中,函数不会修改外部状态,这就消除了许多传统编程模式中的不确定性和调试难度。
  • 不变性(Immutability):使用不可变的数据结构可以简化编程模型,因为不必担心数据会在不经意间被修改。
  • 并行性(Concurrency):由于函数式编程中的函数不依赖于外部状态,也不修改外部状态,因此多个函数可以安全地并行执行,无需担心数据竞争条件。

函数式编程的限制

虽然函数式编程有许多优点,但它并不是适用于所有场景的银弹。以下是一些限制和注意事项:

  1. 性能开销

    • 在某些情况下,频繁创建新数据结构可能会导致性能下降。例如,在大规模数据处理中,如果频繁地复制数组或列表,可能会导致内存使用和计算时间的增加。
  2. 递归深度限制

    • 在一些语言中,特别是那些没有尾调用优化(Tail Call Optimization)的语言,如Python,递归可能导致栈溢出。
  3. 学习曲线

    • 对于习惯了命令式编程的开发者来说,理解和掌握函数式编程的概念和技巧可能需要一定的时间。
  4. 调试困难

    • 在某些情况下,由于缺乏显式的状态跟踪,调试函数式程序可能会比调试命令式程序更具挑战性。
  5. 生态系统兼容性

    • 如果你的项目依赖于特定的库或框架,而这些库或框架并没有充分支持函数式编程,那么完全采用函数式编程可能会遇到兼容性问题。

总的来说,函数式编程提供了一种强大的编程范式,可以简化代码、提高代码的可读性和可维护性,但在实际应用中需要根据具体情况权衡其利弊。在实际开发中,结合函数式编程和其他编程范式(如面向对象编程、命令式编程)通常是更灵活的做法。


进一步深入,探讨函数式编程的本质

通过前面几个例子,我们看到许多算法都能转换为函数式编程思想的实现。那么,函数式编程思想的本质是什么?

由于 函数式的优势是:具有不变性从而能避免副作用,具有并行性的优点
因此 函数式编程技术的本质是:为了达到纯函数的要求,利用技术手段将非纯函数转换为纯函数的技术
达到纯函数的技术内涵是问题分解。
因此 函数式编程思想的本质是:问题分解


技术手段实现纯函数

刚刚提到,了达到纯函数的要求,可以利用技术手段将非纯函数转换为纯函数。那么有哪些常见的技术手段将普通函数转换为纯函数呢?

递归实现纯函数

递归是一种非常强大的技术,它通过自我调用来解决更小规模的相同问题,直到达到可以直接解决的基本情况。

  1. 递归实现阶乘

    def factorial(n):
        if n == 0:
            return 1
        else:
            return n * factorial(n - 1)
    
    print(factorial(5))  # 输出 120
    
  2. 递归实现斐波那契数列

    def fibonacci(n):
        if n <= 1:
            return n
        else:
            return fibonacci(n - 1) + fibonacci(n - 2)
    
    print(fibonacci(10))  # 输出 55
    
  3. 递归实现树的遍历

    data Tree a = Leaf | Node a (Tree a) (Tree a)
    
    sumTree :: Tree Int -> Int
    sumTree Leaf = 0
    sumTree (Node value left right) = value + sumTree left + sumTree right
    
    main = print (sumTree (Node 1 (Node 2 Leaf Leaf) Leaf))  -- 输出 3
    

递归与其他形式的问题分解

递归是问题分解的一种常见形式,但问题分解还包括分治法、分批处理等其他形式。

  1. 分治法(Divide and Conquer)

    def merge_sort(arr):
        if len(arr) <= 1:
            return arr
        mid = len(arr) // 2
        left = merge_sort(arr[:mid])
        right = merge_sort(arr[mid:])
        return merge(left, right)
    
    def merge(left, right):
        result = []
        while left and right:
            if left[0] < right[0]:
                result.append(left.pop(0))
            else:
                result.append(right.pop(0))
        result.extend(left or right)
        return result
    
    arr = [3, 1, 4, 1, 5, 9, 2, 6]
    print(merge_sort(arr))  # 输出 [1, 1, 2, 3, 4, 5, 6, 9]
    
  2. 分批处理(Chunk Processing)

    def process_large_data(data, batch_size=1000):
        results = []
        for i in range(0, len(data), batch_size):
            batch = data[i:i + batch_size]
            processed_batch = map(process_item, batch)
            results.extend(processed_batch)
        return results
    
    def process_item(item):
        # 处理单个项的逻辑
        return item * 2
    
    large_data = list(range(1, 1001))
    processed_data = process_large_data(large_data)
    print(processed_data[:10])  # 输出 [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
    

其他技术手段实现纯函数

  1. 高阶函数(Higher-Order Functions)

    numbers = [1, 2, 3, 4, 5]
    squared = map(lambda x: x**2, numbers)
    print(list(squared))  # 输出 [1, 4, 9, 16, 25]
    
  2. 组合函数(Function Composition)

    def square(x):
        return x ** 2
    
    def add_one(x):
        return x + 1
    
    def compose(f, g):
        return lambda x: f(g(x))
    
    composed = compose(square, add_one)
    print(composed(3))  # 输出 16 (因为 (3 + 1)**2 = 16)
    
  3. 柯里化(Currying)

    def curry(f):
        return lambda x: lambda y: f(x, y)
    
    def add(x, y):
        return x + y
    
    curried_add = curry(add)
    add_five = curried_add(5)
    print(add_five(3))  # 输出 8
    
  4. 模式匹配(Pattern Matching)

    sumList [] = 0
    sumList (x:xs) = x + sumList xs
    
    main = print (sumList [1, 2, 3])  -- 输出 6
    
  5. 代数数据类型(Algebraic Data Types)

    data Tree a = Leaf | Node a (Tree a) (Tree a)
    
    depth :: Tree a -> Int
    depth Leaf = 0
    depth (Node _ left right) = 1 + max (depth left) (depth right)
    
    main = print (depth (Node 1 (Node 2 Leaf Leaf) Leaf))  -- 输出 2
    

通过结合递归和其他技术手段,我们可以更好地理解函数式编程的核心思想,并将其应用于实际编程任务中。


函数式编程技巧在我们日常编程活动中也很常见

函数式编程技巧在日常编程活动中非常常见,并且这些技巧不仅限于专门的函数式编程语言。下面通过具体的例子展示如何在日常编程中使用函数式编程技巧,如 mapfilter 等。

使用 map

map 是一种常见的高阶函数,用于将一个函数应用到集合中的每一个元素,并返回一个新的集合。

numbers = [1, 2, 3, 4, 5]

# 使用 lambda 表达式
squared = map(lambda x: x**2, numbers)
print(list(squared))  # 输出 [1, 4, 9, 16, 25]

# 使用定义的函数
def square(x):
    return x**2

squared = map(square, numbers)
print(list(squared))  # 输出 [1, 4, 9, 16, 25]

使用 filter

filter 是另一种常见的高阶函数,用于筛选集合中的元素,只保留满足某个条件的元素。

numbers = [1, 2, 3, 4, 5]

# 使用 lambda 表达式
even_numbers = filter(lambda x: x % 2 == 0, numbers)
print(list(even_numbers))  # 输出 [2, 4]

# 使用定义的函数
def is_even(x):
    return x % 2 == 0

even_numbers = filter(is_even, numbers)
print(list(even_numbers))  # 输出 [2, 4]

使用 reduce(或 fold

reduce 是一个高阶函数,用于将一个函数应用于一个序列中的元素,以将其缩减为单一的输出值。

from functools import reduce

numbers = [1, 2, 3, 4, 5]

# 使用 lambda 表达式
total = reduce(lambda x, y: x + y, numbers)
print(total)  # 输出 15

# 使用定义的函数
def add(x, y):
    return x + y

total = reduce(add, numbers)
print(total)  # 输出 15

使用 list comprehension

列表推导式(List Comprehensions)是一种简洁的语法,用于创建新的列表。

numbers = [1, 2, 3, 4, 5]

# 使用 list comprehension
squared = [x**2 for x in numbers]
print(squared)  # 输出 [1, 4, 9, 16, 25]

函数式编程技巧在日常编程中非常实用,通过使用 mapfilterreduce 以及列表推导式等技巧,我们可以更好地处理数据结构和逻辑运算,从而构建更加健壮和高效的程序。这些技巧不仅适用于纯粹的函数式编程语言,也可以很好地融入到混合编程范式中。


从技法到心法:函数式编程的思维模式

函数式编程不仅涉及具体的编程技法,更是一种思维方式。以下是从具体的编程技法过渡到更深层次的心法的一些要点:

技法:具体编程技巧

  1. 高阶函数(Higher-Order Functions)

    • 使用 mapfilterreduce 等高阶函数可以让你的代码更加简洁和易于理解。这些函数可以将复杂操作分解为更小的、可组合的函数。
  2. 不可变性(Immutability)

    • 使用不可变数据结构可以避免状态的意外改变,从而使代码更容易推理和维护。
  3. 递归(Recursion)

    • 递归是一种自然的问题分解方法,可以将复杂问题简化为更小的子问题,直到达到可以直接解决的基本情况。
  4. 模式匹配(Pattern Matching)

    • 模式匹配可以帮助你根据不同情况执行不同的逻辑,特别是在处理代数数据类型时。
  5. 柯里化(Currying)

    • 柯里化可以将多参数函数转换为一系列单参数函数,从而更容易组合和重用。

心法:思维方式

  1. 纯函数(Pure Functions)

    • 心法:培养“无副作用”的思维方式。纯函数的输出仅依赖于输入参数,不依赖外部状态,也不改变外部状态。这种思维方式有助于构建可预测、易于测试的代码。
  2. 数据为中心(Data-Centric Thinking)

    • 心法:将注意力集中在数据流上,而不是控制流。在函数式编程中,数据通过一系列纯函数流动,而不是通过状态的改变。这种思维方式可以让你更专注于数据处理逻辑,而不是控制逻辑。
  3. 函数组合(Function Composition)

    • 心法:将复杂问题分解为更简单的子问题,并通过组合简单的函数来构建复杂的逻辑。这种思维方式鼓励你从整体到局部逐步构建解决方案。
  4. 惰性求值(Lazy Evaluation)

    • 心法:延迟计算,只在需要时才进行计算。这种思维方式有助于提高效率,特别是在处理大量数据时,可以避免不必要的计算。
  5. 抽象化(Abstraction)

    • 心法:将常见模式抽象化为通用的函数或类型。例如,通过高阶函数将常见的操作抽象化为通用的处理流程。这种思维方式有助于提高代码的复用性和可维护性。
  6. 分治法(Divide and Conquer)

    • 心法:将问题分解为更小的子问题,逐步解决。这种思维方式不仅适用于递归,还可以应用于其他问题解决策略,如分批处理、分治算法等。
  7. 函数作为第一类公民(Functions as First-Class Citizens)

    • 心法:将函数视为与其他数据类型同等重要的实体。这种思维方式鼓励你在编程中充分利用函数的能力,将函数作为参数传递,或将函数作为返回值使用。
  8. 并行思维(Parallel Thinking)

    • 心法:函数式编程中的纯函数和不可变性使得代码更容易并行执行。这种思维方式有助于构建可扩展、高性能的应用程序。

实践案例

示例:使用函数式编程思维处理数据流

假设我们需要从一个列表中筛选出所有的偶数,并计算它们的平方和。

传统过程式编程实现

numbers = [1, 2, 3, 4, 5, 6]

def process_numbers(nums):
    even_numbers = []
    for num in nums:
        if num % 2 == 0:
            even_numbers.append(num)
    squared_sum = sum([num**2 for num in even_numbers])
    return squared_sum

result = process_numbers(numbers)
print(result)  # 输出 56

函数式编程实现

from functools import reduce

numbers = [1, 2, 3, 4, 5, 6]

def process_numbers(nums):
    even_numbers = filter(lambda x: x % 2 == 0, nums)
    squared_numbers = map(lambda x: x**2, even_numbers)
    squared_sum = reduce(lambda x, y: x + y, squared_numbers)
    return squared_sum

result = process_numbers(numbers)
print(result)  # 输出 56

通过掌握函数式编程的思维模式,你可以更自然地运用函数式编程的技法。从具体的编程技巧过渡到更深层次的思维方式,可以帮助你构建更健壮、可维护的代码。函数式编程不仅仅是关于如何编写代码,更是关于如何思考和解决问题。通过培养这些思维方式,你可以更好地应对复杂的编程挑战,并提高代码的整体质量。


总结

函数式编程提供了一种强大的编程范式,通过纯函数、不可变性、高阶函数等核心概念,可以简化代码、提高代码的可读性和可维护性。虽然函数式编程具有一定的学习曲线和性能开销,但在实际开发中结合函数式编程和其他编程范式通常是更灵活的做法。

通过这篇文章,我们了解了函数式编程的基本概念和核心技术,探讨了函数式编程的本质,并通过实际案例展示了如何在日常编程中应用函数式编程技巧。希望本文能够帮助你更好地理解和应用函数式编程,提高编程效率和代码质量。

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

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

相关文章

【常见框架漏洞】ThinkPHP、struts2、Spring、Shiro

一、ThinkPHP 1.环境配置 靶场:vulhub/thinkphp/5-rcedocker-compose up -d #启动环境 访问靶场:http://ip:8080/index.php2.远程命令执行 执行whoami命令 poc: http://47.121.211.205:8080/index.php?sindex/think\app/invokefunction&functioncall_user_func_array&…

物联网(IoT)中基于深度学习的入侵检测系统的综合综述

这篇论文是一篇全面的综述&#xff0c;标题为“A comprehensive survey on deep learning-based intrusion detection systems in Internet of Things (IoT)”&#xff0c;作者是Qasem Abu Al-Haija和Ayat Droos。论文主要探讨了在物联网(IoT)环境中基于深度学习的入侵检测系统…

Python自动化-操作Excel

在数据处理和报表生成过程中&#xff0c;Excel是一个经常使用的工具。Python中的openpyxl库可以让您通过编程方式读取、写入和操作Excel文件&#xff0c;从而实现自动化的数据处理和报表生成。本文将介绍openpyxl库的基本用法和常见操作&#xff0c;帮助您快速上手使用Python处…

蘑菇成熟待收检测系统源码分享

蘑菇成熟待收检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer…

TQRFSOC开发板47DR PS端DDR4测试

本例程实现对PS端的DDR4进行测试&#xff0c;包括内存读写测试&#xff0c;读写眼图测试等。 创建vivado项目与vitis平台项目的流程与hello world相同&#xff0c;我就不在此处重复演示&#xff0c;也可以在hello world 项目基础上添加应用程序项目。在vitis中创建平台项目后新…

隐私计算相关知识

WOE&#xff08; Weight of Evidence&#xff09;编码 一种在数据分析&#xff0c;尤其是信用评分和欺诈检测等领域中常用的特征编码方法。它的主要目的是将分类变量转换为数值变量&#xff0c;从而使得模型能够更好地理解类别与目标变量之间的关系 IV&#xff08; Informatio…

二.python基础语法

目录 1.第一个python实例 2.python编码规范 2.1.编写规则 2.2.命名规范 2.3. 空格 2.4. 缩进 2.5. 注释 3.python关键字和标识符 3.1.标识符 3.2.关键字 4.python变量 4.1. 定义变量 4.2. 变量类型是可变的 4.3. 多个变量指向同一个值 5.python基本数据类型 5.…

通过组态王在ARMxy边缘计算网关上实现设备集成

随着工业4.0和智能制造理念的普及&#xff0c;设备集成已成为提高生产效率、优化资源配置的重要手段之一。ARMxy系列中的BL340边缘计算网关&#xff0c;以其强大的处理能力和丰富的接口资源&#xff0c;成为实现设备集成的理想平台。 1. BL340边缘计算网关概述 BL340系列是AR…

rce漏洞进阶-玩法思路-绕过姿态

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文主要是整理rce的一些绕过&#xff0c;以及思路等 用于实战中对着测漏洞用 偏进阶&#xff0c;不涉及基础的漏洞原理等内容 玩法思路 代码执行转化命令执行 遇到代码执行漏洞&#xff0c;我们可以传递syste…

计算机毕业设计选题推荐-基于python+Django的全屋家具定制服务平台

精彩专栏推荐订阅&#xff1a;在下方主页&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f496;&#x1f525;作者主页&#xff1a;计算机毕设木哥&#x1f525; &#x1f496; 文章目录 一、全屋家具定制…

操作系统 | 学习笔记 | | 王道 | 5.3 磁盘和固态硬盘

5.3 磁盘和固态硬盘 5.3.1 磁盘 磁盘结构 磁盘&#xff1a;磁盘的表面由一些磁性物质组成&#xff0c;可以用这些磁性物质来记录二进制数据 磁道&#xff1a;磁盘的盘面被划分成一个个磁道。这样的一个“圈”就是一个磁道 扇区&#xff1a;一个磁道又被划分成一个个扇区&am…

医院信息化运维监控:确保医疗系统的稳定与安全

在当今数字化时代&#xff0c;医院的信息化水平直接关系到医疗服务的效率和质量。随着医疗信息化的不断推进&#xff0c;医院对信息化运维监控的需求也日益增强。特别是IT软硬件资源监控和机房动环监控&#xff0c;它们在保障医院信息系统稳定运行中发挥着至关重要的作用。 首先…

在windows上使用vs code调试Rust程序

视频参考&#xff1a;https://www.youtube.com/watch?vTlfGs7ExC0A 前置条件 需要安装的软件&#xff1a; rustvs codeMinGW 或者其它能在 Windows 平台上运行 gdb、gcc 和 g 的软件。 需要安装的插件&#xff1a; rust-analyzer CodeLLDB 然后&#xff0c;在 vs code 中…

iPhone锁屏密码忘了怎么解锁?轻松解锁攻略来了

在日常生活中&#xff0c;智能手机已成为我们不可或缺的伙伴。其中&#xff0c;iPhone以其出色的性能和优雅的设计&#xff0c;赢得了全球用户的喜爱。然而&#xff0c;即便是最忠实的iPhone用户&#xff0c;也可能会遇到一些棘手的问题&#xff0c;比如忘记了锁屏密码。面对这…

韦唯湾区升明月演绎经典 震撼演绎传递爱与力量

9月22日晚&#xff0c;《“湾区升明月”2024大湾区电影音乐晚会》为全球观众送上了一场融合电影艺术与音乐魅力的艺术狂欢&#xff0c;晚会中不光有对不同代际经典影视金曲、经典歌曲的全新演绎&#xff0c;更是汇集了来自海峡两岸暨港澳地区的电影人、音乐人、奥运健儿代表。中…

【AI画图】stable-diffusion-webui学习之一《安装部署》

简介 Stable Diffusion是2022年发布的深度学习文本到图像生成模型&#xff0c;它是一种潜在扩散模型&#xff0c;它由创业公司Stability AI与多个学术研究者和非营利组织合作开发。目前的SD的源代码和模型都已经开源&#xff0c;在Github上由AUTOMATIC1111维护了一个完整的项目…

git报错:无法读取远程分支 ‘origin‘ does not appear to be a git repository

问题分析 push上传的时候本地分支和远程分支断开连接 所以重新链接即可 排查问题 1. 查看是否有分支&#xff0c;检查分支是否正确 git branch -v 2. 查看连接是否断开&#xff0c;断开无内容展示 查看远程仓库详细信息&#xff0c;可看到仓库地址 git remote -v 解决…

k8s中pod的创建过程和阶段状态

管理k8s集群 kubectl k8s中有两种用户 一种是登录的 一种是/sbin/nologin linux可以用密码登录&#xff0c;也可以用证书登录 k8s只能用证书登录 谁拿到这个证书&#xff0c;谁就可以管理集群 在k8s中&#xff0c;所有节点都被网络组件calico设置了路由和通信 所以pod的ip是可以…

如何在拥挤的应用商店中脱颖而出

在现在移动应用程序已成为我们日常生活中必不可少的一部分&#xff0c;从通信和娱乐到财务和健康管理&#xff0c;为各种问题提供解决方案。然而&#xff0c;Google Play 和 App Store 等应用商店的竞争每年都变得更加激烈。数以百万计的应用程序争夺用户的注意力&#xff0c;仅…

车间里应用到了不同品牌的PLC,这还能进行无线通讯吗?

自第一台PLC在GM公司汽车生产线上首次应用成功以来&#xff0c;PLC凭借其方便性、可靠性以及低廉的价格得到了广泛的应用。在现代化工厂中&#xff0c;除厂级PLC系统外&#xff0c;还存在很多独立的子系统。比如&#xff0c;各个生产车间的PLC系统、或同一生产车间的不同生产流…