0. 知识点

基础知识点

1、编程语言及他们之间的区别
    C/C++ 很多语言的底层实现都是C,代码执行效率高,自己做内存管理,对代码要求比较高。很多功能都需要手动实现
    Java 比较好的编程语言,很多企业级的应用都会选择java
    C# 是微软开发的编程语言,部署时需要放在windows server上,最大的弊端是windows系统花钱,现已开源,可部署linux,但已被时代抛弃
    PHP 一般用于快速搭建网站
    Python 简洁,入门简单,代码量少,应用广泛,库强大
    Golang 语法和C比较接近,处理并发时比较有优势,内部很多直接调用c语言的功能,io 并发强,docker kubernetes

2、构造函数与析构函数
    构造函数 用于创建对象的函数
    析构函数 用于销毁对象的函数
    class Foo(object):
        def __new__(self, *args, **kwargs):  # 构造函数
            pass

        def __del__(self, *args, **kwargs):  # 析构函数
            pass
    obj = Foo()
    del obj

3、重写和重载的区别
    重载 类里面函数名相同而参数类型/个数/返回值不同,Python 不支持
    class Foo(object):
        def f1(self,int a1):
            return 123
        def f1(self, string a1):
            pass

    重写 在子类中对父类中的方法进行重写
    class Foo(object):
        def f1(self):
            pring(123)
    class Bar(Foo):
        def f1(self):
            pring(666)

4、什么是接口以及和类的区别
    接口是以interface 关键字开头,内部可以定义方法,但方法中不用写具体实现,它的作用是专门用于约束实现它的类,Python中没有接口类型
    interface   Flyanimal{    // java 中定义一个接口
        void fly();
        } // 定义方法,但内部不能写任何代码
    class Ant extendsInsect implements  Flyanimal {  // Ant类实现了Flyanimal接口
        public void fly(){     // 必须有接口中定义的方法
            System.out.println("Ant can  fly");
        }

    Python 的类支持多继承,其他语言不支持,其他语言需要按顺序嵌套继承每个类,在其他语言中可以实现多个接口但不可以继续多个类
    class Foo(Base,NewBase):
        pass

5、抽象类和抽象方法
    # 在Java中,一个没有具体实现的方法的类可以被定义为抽象类。这个类不能被实例化,只能被继承。继承一个抽象类的子类必须实现父类中的抽象方法。
    abstract class Animal {
        // 抽象方法,没有方法体
        abstract void makeSound();

        // 非抽象方法,有方法体
        void sleep() {
            System.out.println("Zzz");
        }
    }

    class Dog extends Animal {
        // 实现抽象方法
        void makeSound() {
            System.out.println("Woof");
        }
    }

    public class Main {
        public static void main(String[] args) {
            Dog dog = new Dog();
            dog.makeSound(); // 输出: Woof
            dog.sleep();     // 输出: Zzz
        }
    }

    # Python 实现
    import abc

    class MyAbstractClass(metaclass=abc.ABCMeta):
        @abc.abstractmethod
        def my_abstract_method(self):
            pass

    # 这将抛出TypeError,因为MyAbstractClass是抽象的,不能被实例化
    # my_object = MyAbstractClass()

    class MyConcreteClass(MyAbstractClass):
        def my_abstract_method(self):
            print("实现了抽象方法")

    # 可以实例化MyConcreteClass,因为实现了所有抽象方法
    my_object = MyConcreteClass()
    my_object.my_abstract_method()

6、三元运算
    三元运算符是一种由三个操作数组成的运算符,通常用于在条件为真和为假之间进行选择。简洁性,方便性,速度
    result = true_value if condition else false_value
    # 定义两个变量
    a = 10
    b = 20

    # 使用三元运算来比较两个变量的值,并输出较大的一个
    print(a if a > b else b)

7、lambda 表达式
    Python中的lambda表达式是一种创建匿名函数的方式,它们可以快速定义单行函数,并且没有具体的名称。Lambda表达式的基本语法如下:
    lambda 参数列表 : 表达式

    f = lambda x: x * x
    print(f(5))  # 输出25

    三目表达式与lambda的运用:
    getMax = lambda a, b: a if a > b else b
    print(getMax(10, 20))       # 输出: 20
    print(getMax(40, 20))       # 输出: 40  

8、yield 关键字
    yield是一个关键字,用于定义生成器函数。生成器函数可以被暂停和恢复,允许逐个生成值而不需要一次性计算所有值。
    当生成器函数执行到yield语句时,它将生成一个值,并保存其状态,然后等待下一次调用来继续执行。

9、进程和线程的区别
    线程和进程的区别: 
        进程: 数据隔离(但是也可以丛进程间的数据共享)  开销大
        线程: 数据共享 开销小
    cpython中多进程可以使用多核(并发编程),多线程不可以使用多核
    通俗来讲: 比如有个4核(cpu)的主机,当使用多进程的时候,系统会自动的根据进程调度算法来分配今晨给资源,然后分别在不同的cpu上面执行,这就是多进程
    当用多线程的时候,由于GIL锁的存在,多线程始终是在一个cpu上面执行,造成闲的cpu闲死,忙的cpu忙死
    进程和线程的区别:  
        调度单位区别: 进程是操作系统资源分配的基本单位,而线程是CPU任务调度和执行的基本单位、线程共享进程的内存/数据和资源
        资源开销区别: 每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小
        包含关系: 一个进程内包含一个或多个线程,线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程
        内存分配区别: 同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的

10、Cookie 和 Session 的区别
    cookie数据存放在客户的浏览器上,session数据放在服务器上。
    cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
    session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
    单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
    可以考虑将登陆信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中。

11、get 和 post 的区别
    根据 HTTP 标准,HTTP 请求可以使用多种请求方法。
    HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD 方法。
    HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。
        序号  方法  描述用途
        1   GET 【获取资源】本质就是发送一个请求来取得服务器上的某一资源。资源通过一组HTTP头和呈现数据(如HTML文本,或者图片或者视频等)返回给客户端。GET请求中,永远不会包含呈现数据。 即GET请求只用来向服务器获取资源,而GET请求本身不应该携带任何呈现数据。
        1. 登录时GET获取服务器数据库用户名和密码进行验证。
        2.下载文本、图片、音视频等时获取服务器资源。

        2   POST    【传输实体文本】向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在POST请求体中。POST 请求可能会导致新的资源的建立或已有资源的修改。
        1. 提交用户注册信息。
        2. 提交修改的用户信息。

        3   HEAD    【获得报文首部】类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头。欲判断某个资源是否存在,我们通常使用GET,但这里用HEAD则意义更加明确。
        1. 向服务器获取某些易过期或丢失大型文件时,可用HEAD方式查询资源是否存在。

        4   OPTIONS 【询问支持的方法】客户端询问服务器可以提交哪些请求方法。这个方法很有趣,它用于获取当前URL所支持的方法。若请求成功,则它会在HTTP头中包含一个名为“Allow”的头,值是所支持的方法,如“GET, POST”。极少使用。

        5   PUT 【传输文件】从客户端向服务器传送的数据取代指定的文档的内容,即指定上传资源存放路径。这个方法比较少见。HTML表单也不支持这个。本质上来讲, PUT和POST极为相似,都是向服务器发送数据,但它们之间有一个重要区别,PUT通常指定了资源的存放位置,而POST则没有,POST的数据存放位置由服务器自己决定。
        如一个用于提交博文的URL,/addBlog。如果用PUT,则提交的URL会是像这样的”/addBlog/abc123”,其中abc123就是这个博文的地址。而如果用POST,则这个地址会在提交后由服务器告知客户端。目前大部分博客都是这样的。显然,PUT和POST用途是不一样的。具体用哪个还取决于当前的业务场景。

        6   PATCH   【局部更新文件】是对 PUT 方法的补充,用来对已知资源进行局部更新。极少使用。

        7   DELETE  【删除文件】请求服务器删除指定的资源。
        基本上这个也很少见,不过还是有一些地方比如amazon的S3云服务里面就用的这个方法来删除资源。

        8   TRACE   【追踪路径】回显服务器收到的请求,客户端可以对请求消息的传输路径进行追踪,TRACE方法是让Web服务器端将之前的请求通信还给客户端的方法。主要用于测试或诊断。极少使用。

        9   CONNECT 【要求用隧道协议连接代理】HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。CONNECT方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL(安全套接层)和TLS(传输层安全)协议把通信内容加密后经网络隧道传输。极少使用。

    GET方法和POST方法本质上的区别:
        GET一般用来从服务器获取数据,POST一般用来向服务器发送数据。由于GET 方式所能够携带的数据是由限制的,其数据大小通常不能超过 4K, 不适于提交大量表单数据, 故而在表单的提交方式中首选 POST 方式。
        GET方法用于信息获取,它携带的数据应该是安全的(安全:指非修改信息,如数据库方面的信息),而POST方法是用于修改服务器上资源的请求。
        GET请求的数据会附在URL之后,而POST方法提交的数据则放置在HTTP报文实体的主体里,所以POST方法的安全性比GET方法要高。
        GET 请求,没有请求体。POST 请求,如果 form 表单提交的方式为 post,则表单项的数据以请求体的形式发送给服务器,没有大小限制。