小E正在训练场进行射击练习,靶有10个环,靶心位于坐标**(0, 0)**。每个环对应不同的得分,靶心内(半径为1)得10分,依次向外的每个环分数减少1分。若射击点在某个半径为**i**的圆内,则得**11-i**分。如果射击点超出所有的环,则得0分。
根据给定的射击坐标**(x, y)**,请计算小E的射击得分。
测试样例
样例1:
输入:**x = 1, y = 0** 输出:**10**
样例2:
输入:**x = 1, y = 1** 输出:**9**
样例3:
输入:**x = 0, y = 5** 输出:**6**
样例4:
输入:**x = 3, y = 4** 输出:**6**
def solution(x: int, y: int) -> int:
# write code here
# print(11 - ((x * x) + (y * y)) ** (1/2))
return int(11 - ((x * x) + (y * y)) ** (1/2))
# return 0
if __name__ == '__main__':
print(solution(1, 0) == 10)
print(solution(1, 1) == 9)
print(solution(0, 5) == 6)
print(solution(3, 4) == 6)
RPC
RPC 需要解决的问题
- 函数映射
- 数据转换成字节流
- 网络传输
完整过程
- IDL文件:描述接口(proto)
- 生成代码:把IDL转换成对应语言的静态库 (protoc)
- 编解码
- 通信协议
- 网络传输
RPC 带来的问题
- 服务宕机
- 网络异常,如何保证可达性
- 请求量突增
分层设计
数据格式
- 语言特定的格式,java.io.Serializable 不能用于其他语言
- 文本格式 json, xml, csv 人类可读,描述不严谨,没有模型约束,性能差
- 二进制编码 protobuf等
TLV 编码
- Tag:标签,也可以理解为类型
- Lenght:长度
- Value:值,Value 也可以是个TLV 结构
选型
- 兼容性,添加新的字段不影响老的服务
- 通用型,支持跨平台,跨语言
- 性能,从空间和时间两个维度来考虑,也就是编码后数据大小和编码耗费时长。
协议层-概念
特殊结束符
一个特殊字符作为每个协议单元结束的标示
变长协议
以定长加不定长的部分组成,其中定长的部分需要描述不定长的内容长度
关键指标
稳定性
- 熔断
- 限流
- 超时控制
- 请求成功率
- 负载均衡
- 重试
- 长尾请求--传输时长超过百分之99的数据包 -- TCP99
- Backup Request
- 注册中间件
易用性
- 开箱即用:合理默认参数、丰富的文档
- 周边工具:生成代码工具、脚手架工具
扩展性
- middleware
- option
- 编解码层
- 协议层
- 网络传输层
- 代码生成工具插件扩展
观测性
Log、metric、tracing
内置观测性服务
高性能
企业实践
自研网络库-背景
- 原生库无法感知连接状态 : 池中存失效连接
- 原生库存在 goroutine 暴涨的风险
Netpoll
- 解决无法感知连接状态问题:引入 epoll 主动监听机制,感知连接状态
- 解决gotoutine暴涨的风险:建立gotoutine 池,复用goroutine
- 提升性能:引入 Nocopy Buffer, 向上层提供NoCopy的调用接口,编解码层面零拷贝
网络库优化
合并部署
微服务过微,传输和序列化开销越来越大
将亲和性强的服务实例尽可能调度到同一个物理机上,远程RPC 调用优化为本地IPC调用
红包运气排行榜-问题描述
小C参与了一场抢红包的游戏,现在他想要对所有参与抢红包的人进行一次运气排名。排名规则如下:抢到的金额越多,排名越靠前;如果两个人抢到的金额相同,则按照他们抢红包的顺序进行排名。比如,如果小C和小U抢到的金额相同,但小C比小U先抢,则小C排在小U前面。
测试样例
样例1:
输入:**n = 4 ,s = ["a", "b", "c", "d"] ,x = [1, 2, 2, 1]**
输出:**['b', 'c', 'a', 'd']**
样例2:
输入:**n = 3 ,s = ["x", "y", "z"] ,x = [100, 200, 200]**
输出:**['y', 'z', 'x']**
样例3:
输入:**n = 5 ,s = ["m", "n", "o", "p", "q"] ,x = [50, 50, 30, 30, 20]**
输出:**['m', 'n', 'o', 'p', 'q']**
:::success 有的人不止抢了一次
:::
def solution(n: int, s: list, x: list) -> list:
count = {}
# 创建包含每个人信息的列表
people = []
for i in range(n):
v = count.get(s[i], -1)
if v == -1:
people.append(((s[i], x[i], i)))
count[s[i]] = len(people)-1
else:
people[v] = (s[i], people[v][1] + x[i], people[v][2])
# people = [(s[i], x[i], i) for i in range(n)]
# 按照规则排序
people.sort(key=lambda p: (-p[1], p[2]))
# 提取排序后的名字
result = [p[0] for p in people]
return result
if __name__ == '__main__':
print(solution(4, ["a", "b", "c", "d"], [
1, 2, 2, 1]) == ['b', 'c', 'a', 'd'])
print(solution(3, ["x", "y", "z"], [100, 200, 200]) == ['y', 'z', 'x'])
print(solution(5, ["m", "n", "o", "p", "q"], [
50, 50, 30, 30, 20]) == ['m', 'n', 'o', 'p', 'q'])