有个东西不知道咋搞,就是执行程序200毫秒后执行下一个程序

python编程遇到点困难,就是运行一串代码200毫秒接着运行下一行代码

可以用time.sleep(200):

import time

print("输出1")
time.sleep(0.2)   # 200毫秒后输出2
print("输出2")

import time
import signal

def handler(signum, frame):
    print("程序超时退出!")
    exit(1)

signal.signal(signal.SIGALRM, handler)
signal.alarm(0.2)

start_time = time.time()
while True:
    # 循环执行的代码
    current_time = time.time()
    if current_time - start_time > 0.2:
        break
#执行下一段程序
...

  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7682198
  • 这篇博客你也可以参考下:一篇文章教会你利用Python网络爬虫实现妖怪信息的分类采集!
  • 除此之外, 这篇博客: 【面试记录】Python常见面试200题及答案总结中的 百度一下,你就知道 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 中的地址 a=“张明 98 分”,用 re.sub,将 98 替换为 100

    89. 正则表达式匹配中(.*)和(.*?)匹配区别?

    (.*)是贪婪匹配,会把满足正则的尽可能多的往后匹配
    
    (.*?)是非贪婪匹配,会把满足正则的尽可能少匹配
    
    import re
    s= str("<a>哈哈</a><a>啦啦</a>")
    res1 = re.findall("<a>(.*)</a>",s)
    print(res1)
    res2 = re.findall("<a>(.*?)</a>",s)
    print(res2)
    

    90. 写一段匹配邮箱的正则表达式

    合法邮箱的例子:
    1234@qq.com(纯数字)
    wang@126.com(纯字母)
    wang123@126.com(数字、字母混合)
    wang123@vip.163.com(多级域名)
    wang_email@outlook.com(含下划线 _)
    wang.email@gmail.com(含英语句号 .)
    
    根据对以上邮箱的观察,可将邮箱分为两部分(“@”左边和右边部分)来进行分析:
    
    1 左边部分可以有数字、字母、下划线(_)和英语句号(.),因此可以表示成:[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*。
    2 右边部分是域名,按照域名的规则,可以有数字、字母、短横线(-)和英语句号(.),另外顶级域名一般为 2 ~ 6 个英文字母(比如“cn”、“com”、“site”、“group”、“online”),故可表示为:([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}。
    
    要注意两点:
    1 考虑到匹配邮箱时字符串的一头一尾不能有其它字符,故要加上开始标志元字符 ^ 和结束标志元字符 $。
    2 英语句号(.)是正则表达式的元字符,因此要进行转义(\.)。
    
    email = /^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
    

    其他内容

    91.解释一下 python 中 pass 语句的作用?

    92.简述你对 input()函数的理解

    93.python 中的 is 和==

    94. Python 中的命名空间和作用域

    命名空间(Namespace)是从名称到对象的映射,大部分的命名空间都是通过Python字典来实现的。
    
    命名空间提供了在项目中避免名字冲突的一种方法。各个命名空间是独立的,没有任何关系的,所以一个命名空间中不能有重名,但不同的命名空间是可以重名而没有任何影响。
    
    一般有三种命名空间:
    1、内置名称(built-in names),Python语言内置的名称,比如函数名 abs、char 和异常名称BaseException、Exception 等等。
    2、全局名称(global names),模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。
    3、局部名称(local names),函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量。(类中定义的也是)
    
    命名空间查找顺序:
    假设我们要使用变量runoob,则 Python 的查找顺序为:局部的命名空间去 -> 全局命名空间 -> 内置命名空间。
    如果找不到变量 runoob,它将放弃查找并引发一个 NameError 异常:
    NameError: name 'runoob' is not defined。
    
    命名空间的生命周期:
    命名空间的生命周期取决于对象的作用域,如果对象执行完成,则该命名空间的生命周期就结束。
    因此,我们无法从外部命名空间访问内部命名空间的对象。
    
    作用域就是一个Python程序可以直接访问命名空间的正文区域。
    
    在一个python程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。
    
    Python中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
    
    变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。
    
    Python的作用域一共有4种,分别是:
    L(Local):最内层,包含局部变量,比如一个函数/方法内部。
    E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。
    比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
    G(Global):当前脚本的最外层,比如当前模块的全局变量。
    B(Built-in): 包含了内建的变量/关键字等。,最后被搜索
    规则顺序: L –> E –> G –>gt; B。
    在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。
    
    注意:Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问,
    

    95.三元运算写法和应用场景?

    96.了解 enumerate 么?

    97.列举 5 个 Python 中的标准模块

    98.如何在函数中设置一个全局变量

    99.pathlib 的用法举例

    100.Python 中的异常处理,写一个简单的应用场景

    101.Python 中递归的最大次数,那如何突破呢?

    102.什么是面向对象的 mro

    103.isinstance 作用以及应用场景?

    104.什么是断言?应用场景?

    105.lambda 表达式格式以及应用场景?

    106.新式类和旧式类的区别

    107.dir()是干什么用的?

    108.一个包里有三个模块,demo1.py, demo2.py, demo3.py,但使用 from tools import *导入模块时,如何保证只有 demo1、demo3 被导入了。

    109.列举 5 个 Python 中的异常类型以及其含义

    110.copy 和 deepcopy 的区别是什么?

    111.代码中经常遇到的*args, **kwargs 含义及用法。

    112.Python 中会有函数或成员变量包含单下划线前缀和结尾,和双下划线前缀结尾,区别是什么?

    113.w、a+、wb 文件写入模式的区别

    114.举例 sort 和 sorted 的区别

    115.什么是负索引?

    116.pprint 模块是干什么的?

    117.解释一下 Python 中的赋值运算符

    118.解释一下 Python 中的逻辑运算符

    119.讲讲 Python 中的位运算符

    120.在 Python 中如何使用多进制数字?

    121.怎样声明多个变量并赋值?

    算法和数据结构

    122.已知:

    (1) 从 AList 和 BSet 中 查找 4,最坏时间复杂度那个大?

    (2) 从 AList 和 BSet 中 插入 4,最坏时间复杂度那个大?

    123.用 Python 实现一个二分查找的函数

    124.python 单例模式的实现方法

    125.使用 Python 实现一个斐波那契数列

    126.找出列表中的重复数字

    127.找出列表中的单个数字

    128.写一个冒泡排序

    129.写一个快速排序

    130.写一个拓扑排序

    131.python 实现一个二进制计算

    132.有一组“+”和“-”符号,要求将“+”排到左边,“-”排到右边,写出具体的实现方法。

    133.单链表反转

    134.交叉链表求交点

    135.用队列实现栈

    136.找出数据流的中位数

    137.二叉搜索树中第 K 小的元素

    爬虫相关

    138.在 requests 模块中,requests.content 和 requests.text 什么区别

    139.简要写一下 lxml 模块的使用方法框架

    140.说一说 scrapy 的工作流程

    141.scrapy 的去重原理

    142.scrapy 中间件有几种类,你用过哪些中间件

    143.你写爬虫的时候都遇到过什么?反爬虫措施,你是怎么解决的?

    144.为什么会用到代理?

    145.代理失效了怎么处理?

    146.列出你知道 header 的内容以及信息

    147.说一说打开浏览器访问 百度一下,你就知道 获取到结果,整个流程。

    148.爬取速度过快出现了验证码怎么处理

    149.scrapy 和 scrapy-redis 有什么区别?为什么选择 redis 数据库?

    150.分布式爬虫主要解决什么问题

    151.写爬虫是用多进程好?还是多线程好? 为什么?

    152.解析网页的解析器使用最多的是哪几个

    153.需要登录的网页,如何解决同时限制 ip,cookie,session(其中有一些是动态生成的)在不使用动态爬取的情况下?

    154.验证码的解决(简单的:对图像做处理后可以得到的,困难的:验证码是点击,拖动等动态进行的?)

    155.使用最多的数据库(mysql,mongodb,redis 等),对他的理解?

    网络编程

    156.TCP 和 UDP 的区别?

    157.简要介绍三次握手和四次挥手

    158.什么是粘包? socket 中造成粘包的原因是什么? 哪些情况会发生粘包现象?

    并发

    159.举例说明 conccurent.future 的中线程池的用法

    160. 说一说多线程,多进程和协程的区别。

    1、进程是操作系统分配的最小单位,线程是CPU调度的最小单位,协程既不是进程也不是线程,协程仅仅是一个特殊的函数,协程和进程、线程不是一个维度的。
    
    2、一个进程由一个或者多个线程组成,线程是一个进程中代码的不同执行路线,协程是属于一种操作,是由用户自己去操作线程的切换(在用户态进行切换),这样的话,就可以大大降低线程切换(在内核态切换)的花销。
    
    3、切换进程需要的花销(时间、资源等)比切换线程要大,切换线程也是需要花销的,协程与进程一样,切换是存在上下文切换问题的。
    
    4、一个进程可以包含多个线程,一个线程可以包含多个协程。
    
    5、一个线程内的多个协程虽然可以切换,但是多个协程是串行执行的,只能在一个线程内运行,没法利用CPU多核能力。
    
    
    # 多进程执行多任务
    import os
    import time
    from multiprocessing import Pool
    
    
    # multiprocessing模块提供了一个Pool进程池的方式批量创建子进程。
    
    
    def long_time_task(name):
        print('Run task %s (%s)...' % (name, os.getpid()))
        start = time.time()
        time.sleep(1)  # 线程推迟执行的时间
        end = time.time()
        print('Task %s runs %0.2f seconds.' % (name, (end - start)))
    
    
    if __name__ == '__main__':
        print('Parent process %s.' % os.getpid())
        p = Pool(5)  # Pool对象,参数5表示调用多少个并行进程进行程序运行,pool的默认容量为CPU的计算核数量
        for i in range(10):
            p.apply_async(long_time_task, args=(i,))  # p.apply_async()函数给进程池添加进程任务,它的参数包括待运行程序和程序的传入参数。
            print('Waiting for all subprocess done ...')
            p.close()  # 对Pool对象调用join()方法会等待所有子进程执行完毕,调用join()之前必须先调用close(),调用close()之后就不能继续添加新的Process了。
            p.join()  # join()方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步。
            print('All subprocesses done.')
    
    # 多线程执行多任务
    import time
    import threading
    # threading模块
    
    
    # 新线程执行的代码:
    
    def loop():
        print('thread %s is running...' % threading.current_thread().name)
        # threading.current_thread()永远返回当前线程的实例
        n = 0
    
        while n < 5:
            n = n + 1
    
            print('thread %s >>> %s' % (threading.current_thread().name, n))
    
            time.sleep(1)
    
        print('thread %s ended.' % threading.current_thread().name)
    
    
    print('thread %s is running...' % threading.current_thread().name)
    
    t = threading.Thread(target=loop, name='LoopThread')  # 用LoopThread命名子线程
    
    t.start()
    
    t.join()
    
    print('thread %s ended.' % threading.current_thread().name) 
    

    161. 简述 GIL

    • 预备知识
    并行与并发的理解:
    
    并发:交替处理多个任务的能力; 
    并行:同时处理多个任务的能力; 
    
    并发的关键是你有处理多个任务的能力,不一定要同时。
    并行的关键是你有同时处理多个任务的能力,强调的是同时.
    
    最大的区别:是否是『同时』处理任务。
    
    • GIL(全局解释器锁)
    通过代码可以发现多进程可以充分使用cpu的两个内核而多线程却不能充分使用cpu的两个内核 
    
    问题:通过验证我们发现多线程并不能真正的让多核cpu实现并行。 
    
    原因: 
    cpython解释器中存在一个GIL(全局解释器锁),其作用就是保证同一时刻只有一个线程可以执行代码, 
    这造成使用多线程的时候无法实现并行。
    
    结论: 
    1.在处理像科学计算这类需要持续使用cpu的任务的时候单线程会比多线程快,可以使用多进程利用多核的CPU资源。
    2.在处理像IO操作等可能引起阻塞的这类任务的时候多线程会比单线程,因为遇到IO阻塞会自动释放GIL锁 
    
    解决方案法: 
    1:更换解释器比如使用jpython(java实现的python解释器) 
    2:使用多进程完成多任务的处理
    

    162. 进程之间如何通信

    Process之间肯定是需要通信的,操作系统提供了很多机制来实现进程间的通信。Python的multiprocessing模块包装了底层的机制,提供了Queue、Pipes等多种方式来交换数据。
    
    from multiprocessing import Process, Queue
     
    import os, time, random
     
     
    # 写数据进程执行的代码:
     
    def write(q):
     
        print('Process to write: %s' % os.getpid())
     
        for value in ['A', 'B', 'C']:
     
            print('Put %s to queue...' % value)
     
            q.put(value)
     
            time.sleep(random.random())
     
     
    # 读数据进程执行的代码:
     
    def read(q):
     
        print('Process to read: %s' % os.getpid())
     
        while True:
     
            value = q.get(True)
     
            print('Get %s from queue.' % value)
     
     
    if __name__=='__main__':
     
        # 父进程创建Queue,并传给各个子进程:
     
        q = Queue()
     
        pw = Process(target=write, args=(q,))
     
        pr = Process(target=read, args=(q,))
     
        # 启动子进程pw,写入:
     
        pw.start()
     
        # 启动子进程pr,读取:
     
        pr.start()
     
        # 等待pw结束:
     
        pw.join()
     
        # pr进程里是死循环,无法等待其结束,只能强行终止:
     
        pr.terminate()
    

    163.IO 多路复用的作用?

    164.select、poll、epoll 模型的区别?

    165.什么是并发和并行?

    166.一个线程 1 让线程 2 去调用一个函数怎么实现?

    167.解释什么是异步非阻塞?

    168. threading.local 的作用?

    内部自动为每个线程维护一个空间(字典),用于当前存取属于自己的值。保证线程之间的数据隔离。
    
    {
    线程ID: {...}
    线程ID: {...}
    线程ID: {...}
    线程ID: {...}
    }
    

    Git 面试题

    169.说说你知道的 git 命令

    170.git 如何查看某次提交修改的内容

  • 您还可以看一下 王涛老师的150讲轻松学习Python网络爬虫课程中的 课程总结和实习僧爬虫作业介绍小节, 巩固相关知识点