职业生涯第二课---“前人埋雷,后人踩坑“

前言

在这段半个月的实习生涯中,前几天主动优化自己写的代码,还学到了分布式事物锁,有点沾沾自喜。没想到没过几天就踩到了前人埋下的雷。

正文

事情是这样的,我接手了上个实习生的工作,对原有的程序做扩展多写几个接口,有个接口需要用到高德的poi_id来获取经纬度,我发现前人已经写好了代码,我就直接粘过来用,他是将获取的经纬度作为一个列表返还。
关键代码如下


                        location_split = location.split(",")
                        if len(location_split) == 2:
                            latitude, longitude = map(float, location_split)
                            coordinates_dict[poi_id] = (latitude, longitude)

实际上开发文档

image.png
我看到他的代码后粘过来后改了一下返还了个字典,直接用他的经纬度的变量作为字典经纬度的值。QAQ
结果这个老6经度写成维度,维度写成经度。

我的这个函数在拿到经纬度后向后端发送请求,但后端接到后出现了这样的情况

image.png
省市区后端没有解析出来,因为这个接口前端偷懒了,直接将表单传给了后端,因此这个post请求的负载展开后一千多行(太抽象了QAQ),其中和位置相关的地方采用了双重转码,先将那个地方转为JSON作为值,再将整个对象再转一次JSON。

image.png

导致我看这个数据的时候一脸懵逼。
试了好多次还以为是自己的问题,然后不停地改负载,最后发现了他的位置相关信息的编码是转了两次JSON…蛮抽象的

image.png
为了转码还写了个递归函数

# 处理双重编码的JSON字符串(本接口中的地址部分的value就是双重编码)递归调用深层解码
def decode_double_encoded_json(data):
    if isinstance(data, dict):
        for key, value in data.items():
            if isinstance(value, str):
                try:
                    decoded_value = json.loads(value)
                    data[key] = decoded_value
                except json.JSONDecodeError:
                    pass
            elif isinstance(value, dict) or isinstance(value, list):
                decode_double_encoded_json(value)
            else:
                pass

然后,
就在此时,打印出相关信息进行对比时发现经纬度竟然刚好相反(下图是经纬度改正后的截图)

image.png
也就是说我之前排查错误的方向,什么JSON转码,什么字典中的str是双引号单引号都错了。
然后再测试就ok了,发现经纬度错了后就往前排查调用发现是工具函数的锅,这个bug卡了我两天了,还问了领导,到最后领导都以为是JSON转码的问题。(没敢告诉他是自己省事抄了个工具函数才踩雷的)

然后我就看他的函数的调用,结果发现他的函数的调用每次都是直接调用哪个列表,因为排序是没有错的,他从未单独用过经度或维度,所以他那个三个接口一直没有报错在正常跑着,真的我哭死。。。。。。

多线程监视器的优化

最近还有个想法,去优化我写的一个监视器
源代码关键部分如下

# 登录状态监视器,检查是否是登录状态,若是登录状态则将cookies和headers保存到全局变量中
def monitor_login():
    global cookies,headers,login_flag
    thisflag = login_flag
    while True:
        time.sleep(2)
        # 如果调用了登录接口,尝试获取cookies和headers
        if thisflag != login_flag:
            # 40s后尝试登录
            time.sleep(40)
            is_login = browser_data()
            if not is_login:
                print("当前为未登录状态,20s后重新尝试")
                time.sleep(20)
                is_login = browser_data()
                if not is_login:
                    print("当前为未登录状态,请检查")
            else:
                print("成功获取登录信息")
                time.sleep(5)

登录接口的钩子函数,用来触发监视器

# 发送登录响应后,通过修改全局变量触发监视器
@after_this_request
def post_callback_task(response):
    global login_flag
    login_flag = not login_flag
    return response

注册多线程

# 注册线程函数,启动后台线程来监控登录状态的变化
monitor_thread = threading.Thread(target=monitor_login)
# 守护进程
monitor_thread.daemon = True
monitor_thread.start()

个人感觉此监控器处于长期运转状态,会造成性能浪费。然后我就想能不能每次调用的登录接口的时候短暂唤醒这个线程,然后执行完后再进入沉睡,在调用接口时再唤醒。

优化测试

修改逻辑,只在触发函数后监控器运行一小段时间。能够节省时间。实验逻辑的测试样例如下:

pause_event = threading.Event()
def case1():
    flag =0
    while True:
        flag = flag+1
        print(flag)
        time.sleep(1)
        if flag % 5 == 0:
            # 冻结线程
            pause_event.clear()
            pause_event.wait()

# 注册线程函数,启动后台线程来监控登录状态的变化
monitor_thread = threading.Thread(target=case1)
# 守护进程
# monitor_thread.daemon = True
monitor_thread.start()
time.sleep(7)
#模拟调用接口
while True:
    x = input("请输入")
    if x == "1":
        # 触发解禁
        pause_event.set()

但将相关逻辑嫁接到项目中后主线程被阻塞。

有没有jym有好的想法和建议?

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冷月半明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值