编程范式 | 青训营笔记

169 阅读6分钟

这篇文章将从编程语言、编程范式展开

计算机层次结构可分为如下5层:微程序设计层-机器语言层-操作系统层-汇编语言层-高级语言层

image.png

因此,不同层次的语言也不同。

  • 机器语言:机器语言是最底层的语言,使用二进制编码表示指令和数据,直接由计算机硬件执行,难以阅读和编写,但是具有高效性。(机器语言是由0和1构成)
  • 汇编语言:通过符号化指令和地址来替代二进制编码,相对于机器语言便于阅读和编写,但需要逐行翻译成机器语言才能被计算机执行。

image.png

  • 高级语言:作为程序员与计算机之间的接口,将人类语言转化为计算机可识别的代码。高级语言包括C、Java、Python等,具有更高的抽象程度,可以快速开发复杂的应用程序,具有易于阅读和编写、跨平台等优点,但是执行速度相对较慢,需要编译或解释器转换成机器语言。
//高级语言
C=A+B
//汇编语言
LOAD A
ASS B
STORE C
//机器语言
12234234532450
34523452345234
67896789456768
12234345435645

面向过程(自顶向下、结构化编程)

面向过程是一种以“过程”为中心的编程思想,基于步骤和分解的思考方式。面向过程中,程序运行时从头到尾按照一定顺序执行的,主要考虑数据和函数的流程性和耦合性,通常使用顺序、选择和循环结构来描述问题。

代表语言有C语言、FORTRAN、COBOL等

def add_numbers(n1,n2):
    """计算两个数字的和"""
    result = n1 + n2
    return result
#调用函数并打印结果
sum = add_numbers(5,10)
print(sum) # 15

以上代码定义一个add_numbers函数执行加法操作,接收两个参数,将他们相加并返回结果。然后调用该函数,将结果存储在一个变量中,最后打印结果,以顺序的方式执行。

面向过程存在的问题:

  • 在实现较小规模的任务时比较简单直观,但若系统越复杂的话,会出现以下问题:
    • 缺乏模块化:面向过程编程通常会将所有代码写在一个大函数或一个大模块中,导致代码难以维护、修改和拓展。
    • 代码重复性:由于缺乏模块化,同样的代码可能会在多个地方重复出现,增加维护成本。
    • 难以扩展:当需求发生改变时,需要修改大量代码,而这些修改可能会对其他部分产生意想不到的影响,使得系统难以扩展。
    • 缺乏抽象:面向过程通常使用大量的全局变量和函数调用,导致代码难以理解和维护。

面向对象(封装、继承、多态、依赖注入)

面向对象是一种以“对象”为中心的编程思想,侧重于数据和对象的抽象与封装的思考方式。面向对象中,程序不一定按照顺序执行,而是系统中各个对象之间不断发送消息和相互交互,每个对象都有自己的状态和行为,并且能和其他对象进行关联和交互。

优点:

  • 更适合大型项目和复杂项目的开发,更容易理解与维护。
  • 可以避免重复代码的出现,并且可以更好地维护和扩展代码
  • 具有更好的抽象性与封装性,让程序员关注问题本身而不是底层的实现细节
  • 支持多态性和继承性,使得程序的可复用性和拓展性更强>

代表语言有Java、C++、Python等

class Person{
  name='Tom'
  age=18
  school='school'
  getMessage(){
    return `${this.name} is ${this.age} years old.`
  }
}
const p1=new Person
console.log(p1.getMessage())//Tom is 18 years old.

以上例子创建了一个类Person,然后通过创建一个实例,该实例上就有这个类的属性。

因此面向对象也存在一定的问题。当你创建这个对象实例的时候,这个实例便将这个对象上的所有属性和方法都继承过来了,它总是附带着所有它需要的隐含环境。例如,你只是想要一个面包,得到的却是一个烤箱和所有制作该面包的材料。

函数式语言

一种基于函数调用和函数组合构建软件的编程方式,基本思想是将计算过程看作是函数的重复组合

优势:可缓存、可移植、可测试、可推理、可并行

代表语言:Lisp、Haskell、Scheme等 特点是具有严格的数学基础,允许函数作为参数和返回值,有强大的递归和高阶函数支持。

以下是一些函数式编程简单例子

//将数组中每个元素平方并返回新的数组
function squareAll(arr){
    return arr.map(x=>x**2);
}
//定义一个高阶函数,接收一个函数和一个数组参数,并对数组参数进行函数操作
function applyOperation(operation,arr){
    return operation(arr);
}
const nums=[1,2,3,4,5];
const squareNums=applyOperation(squareAll,nums);
console.log(squareNums);//输出:[1,4,9,16,25]

柯里化:将一个接收多个参数的函数转换成一系列只接收单个参数的函数,这样可以实现对函数的部分应用,也就是提供部分参数并返回一个新的函数,该函数接收剩余的参数。柯里化有利于创建可重用的代码和提高代码的可读性。

function curry(fn){
    const arity=fn.length;
    return function $curry(...args){
        if(args.length<arity){
            return $curry.bind(null,...args)
        }
        return fn.call(null,...args)
    }
}
function add(a,b,c){
    return a + b + c;
}
const add_=curry(add);
const add12=add_(1,2);//已经传入的参数存入闭包
add12(5);//8
add12(4);//7
add12(7);//10

多范式语言

支持多种编程范式,包括面向过程、面向对象、函数式、逻辑、并发等多种范式。这种语言是对于单一范式语言的扩展与拓展

常见语言有Javascript

// 定义一个车辆类 
class Vehicle { 
    constructor(make, model, year) { 
        this.make = make; 
        this.model = model; 
        this.year = year; 
        } 
    getFullDescription() { 
        return `${this.year} ${this.make} ${this.model}`; 
    } 
} 
// 定义一个汽车子类 
class Car extends Vehicle { 
    constructor(make, model, year, numDoors) { 
        super(make, model, year); 
        this.numDoors = numDoors; 
    } 
    getFullDescription() { 
        return `${super.getFullDescription()}, ${this.numDoors} doors`; 
    }
} 
// 创建一个汽车对象并打印描述 
const myCar = new Car('Toyota', 'Camry', 2021, 4); 
console.log(myCar.getFullDescription()); //2021 Toyota Camry, 4 doors
// 使用map函数将数组中的每个数字加倍 
const numbers = [1, 2, 3, 4, 5]; 
const doubledNumbers = numbers.map(num => num * 2); 
console.log(doubledNumbers);//(5) [2, 4, 6, 8, 10]

响应式编程

一种面向数据流和变化传播的编程范式,强调在系统中对事件进行响应和处理。

如:React:一个JavaScript框架,用于构建用户界面,使用了响应式编程的概念,通过将组件声明为可观察的来更新UI。

RxJava:RxJava实在Java平台上是响应式编程的库,提供一些操作符,如map、filter、reduce等,用于处理来自各种来源的数据流。

以上是上了青训营课程后整理的笔记,如果存在问题或有什么缺乏的点,希望大家予以批评指正。