zoukankan      html  css  js  c++  java
  • 面向对象和网络编程练习题

    1、简述可迭代对象、迭代器、生成器的关系.   注意列表生成式
        可作用于for循环的对象都是可迭代对象。可作用于next()函数并不断返回下一个值的对象称迭代器,表示惰性计算序列。
        可以在循环过程中不断推算后续元素,这种一边循环一边计算的机制,称为生成器。(yeild)
        生成器是迭代器的一种,可迭代对象不一定是迭代器。
        list/dic/str可以使用iter()函数变为迭代器。

    2、闭包的概念和作用
        闭包:内部函数包含对外部作用域而非全局作用域的引用.
        返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得该函数
        无论在何处调用,优先使用自己外层包裹的作用域。装饰器就是闭包的应用
        装饰器的概念和作用
        装饰器(Decorator):在代码运行期间动态增加功能的方式,称之为装饰器。对修改封闭,对扩展开放

    3、Python中两种序列化json和pickle区别
        序列化是把内存的数据类型转变为字符串(bytes类型)。
        json:用于字符串和Python数据类型之间进行转换
        pickle:用于Python特有类型(仅Python认识)和Python数据类型间进行转换。
        shelve:将内存数据通过文件持久化,支持任何pickle支持的数据格式。

    4、简述什么是类和对象
        对象是特征与技能的结合体,类则是一系列对象相似的特征与技能的结合体

    5、简述面向对象的三大特性
        继承:一种创建类的方式,解决代码重用问题。
        多态:一类事物有多种形态,多态性是指在不考虑实例类型的情况下使用实例
        封装:明确区分内外,控制外部对隐藏属性的操作行为,隔离复杂度
        组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合

    6、简述什么是绑定方法和非绑定方法
        (1)绑定到对象的方法:在类中定义没有加装饰器修饰的方法。
            对象.bound_method()  自动将对象当做第一个参数传入
        (2)绑定到类的方法:在类中定义的装饰器@classmethod修饰的方法。
            类.bound_method()   自动将类当第一个参数传入
        (3)非绑定方法:在类中用@staticmethod装饰器装饰的方法。
            没有自动传值,不绑定类和对象,类和对象均可调用。

    7、简述什么是反射以及实现反射的方法
        反射指的是程序可以访问、检测和修改它本身状态或行为的一种能力,也叫做自省。
        hasattr(obj, name):  判断obj对象是否有叫name字符串对应的方法或属性。
        getattr(obj, name):  获取对象中name字符串对应的方法或属性。
        setattr(x,'y',v):给对象赋值x.y=v;  delattr(x,'y'):删除对象属性del x.y

    7.1 什么事领域模型?
        领域模型是对领域内的概念或现实世界中对象的可视化表示,发掘重要的业务领域概念,
        建立业务领域概念之间的关系。

    8、简述TCP/IP各层功能
        应用层:规定应用程序的数据格式。
        传输层:建立端口到端口的通信。
        网络层:引入一套新的地址用来区分不同的广播域/子网,这套地址即网络地址
        数据链路层:定义了电信号的分组方式,分组方式后来形成了统一的标准,即以太网协议ethernet
        物理层:主要是基于电器特性发送高低电压(电信号),高电压对应数字1,低电压对应数字0

    9、简述什么是Socket
        Socket是应用层与传输层TCP/IP协议族通信的中间软件抽象层,它是一组接口。把TCP/IP协议藏在接口内,直接去调用socket,即能符合协议要求。
        在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

    10、编写一个学生类, 要求有一个计数器的属性, 统计总共实例化了多少个学生。
    class Student:
        __count = 0
        def __init__(self, name, age):
            self.name = name
            self.age = age
            Student.__count += 1

        @staticmethod
        def get_count():
            print("总共实例化 %s 人" % Student.__count)

    stu1 = Student('hqs', 20)
    stu2 = Student('egon', 19)
    stu1.get_count()
    Student.get_count()

    10、基于socket和subprocess模块模拟实现循环执行命令。
    ########################server####################
    import socket, subprocess, struct

    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(("127.0.0.1", 9001))  # bind()内为元组,0-65535:0-1024供操作系统使用
    server.listen(5)
    print('starting...')
    while True:
        conn, client_addr = server.accept()
        print(client_addr)

        while True:  # 通讯循环
            try:
                """1、收到客户端的命令"""
                cmd = conn.recv(8096)
                if not cmd:break
                """2、执行命令,拿到结果"""
                obj = subprocess.Popen(cmd.decode('utf-8'), shell=True,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE)
                stdout = obj.stdout.read()
                stderr = obj.stderr.read()
                """3、命令结果返回客户端"""
                # 第一步:制作固定长度的报头
                total_size = len(stdout) + len(stderr)  # 整型
                header = struct.pack('i', total_size)  # 隐患:struct的i 的取值区间是-2147483648~2147483648
                # 第二步:将报头发给客户端
                conn.send(header)
                # 第三步:发送真实数据
                conn.send(stdout)
                conn.send(stderr)

            except ConnectionResetError:
                break
        conn.close()
    server.close()

    #############################client#####################
    import time, socket, struct
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(("127.0.0.1", 9001))
    while True:
        """1、发命令"""
        cmd = input('>>: ').strip()
        if not cmd:continue
        client.send(cmd.encode('utf-8'))
        """2、拿结果"""
        # 第一步:拿到数据的长度——>即先收报头
        header = client.recv(4)
        # 第二步:从报头中解析出对真实数据的描述信息(数据长度)
        total_size = struct.unpack('i', header)[0]  # 解包之后为元组,取第一项即打包的内容
        # 第三步:接收真实的数据
        recv_size = 0
        recv_data = b''
        while recv_size < total_size:
            res = client.recv(1024)    # 最大不能超过操作系统缓存大小,一次收不完,多次收
            recv_data += res
            recv_size += len(res)  # 最后一次收的时候将不是1024,未来如果要查看进度的时候有问题
        print(recv_data.decode('utf-8'))
    client.close()

  • 相关阅读:
    谜题92:双绞线
    谜题91:序列杀手
    谜题90:荒谬痛苦的超类
    谜题89:泛型迷药
    谜题88:原生类型的处理
    谜题87:紧张的关系
    谜题86:有毒的括号垃圾
    谜题85:惰性初始化
    谜题84:被粗暴地中断
    easyUi DataGrid
  • 原文地址:https://www.cnblogs.com/xiugeng/p/8970202.html
Copyright © 2011-2022 走看看