在Python中实现的所有算法(用于教育)
这些实现仅用于学习目的。因此,它们的效率可能低于Python标准库中的实现
地址:https://github.com/TheAlgorithms/Python
投稿指南
在您投稿之前,请阅读我们的投稿指南
社区频道
我们在吉特路上!请加入我们
算法列表
请参阅我们的目录
这些实现仅用于学习目的。因此,它们的效率可能低于Python标准库中的实现
地址:https://github.com/TheAlgorithms/Python
在您投稿之前,请阅读我们的投稿指南
我们在吉特路上!请加入我们
请参阅我们的目录
算法 | 操作系统 | 网络 | 面向对象 | 数据库 | Java | 系统设计 | 工具 | 编码实践 | 后记 |
---|---|---|---|---|---|---|---|---|---|
:pencil2: | :computer: | :cloud: | :art: | :floppy_disk: | :coffee: | :bulb: | :wrench: | :watermelon: | :memo: |
笔记内容按照中文文案排版指北进行排版,以保证内容的可读性.
本仓库的内容不是将网上的资料随意拼凑而来,除了少部分引用书上和技术文档的原文(这部分内容都在末尾的参考链接中加了出处),其余都是我的原创.在您引用本仓库内容或者对内容进行修改演绎时,请署名并以相同方式共享,谢谢.
转载文章请在开头明显处标明该页面地址,公众号等其它转载请联系zhengyc101@163.com
了解如何设计大型系统
为系统设计面试做准备
学习如何设计可伸缩的系统将帮助您成为一名更好的工程师
系统设计是一个宽泛的话题。网上有大量关于系统设计原则的资源。
此repo是一个有组织的资源集合,可帮助您了解如何大规模构建系统
这是一个不断更新的开放源码项目
欢迎投稿!
除了对面试进行编码外,系统设计在许多科技公司的技术面试流程中也是必不可少的组成部分
练习常见的系统设计面试问题,并将您的结果与示例解决方案(讨论、代码和图表)进行比较
面试准备的其他主题:
提供的Anki抽认卡套装使用间隔重复来帮助您记住关键的系统设计概念
非常适合在旅途中使用
正在寻找资源来帮助您准备编码面试吗?
请查看姊妹版repo交互式编码挑战,其中包含额外的Anki幻灯片:
向社区学习
请随时提交拉取请求以提供帮助:
需要润色的内容正在开发中
查看投稿指南
各种系统设计主题的摘要,包括优缺点。每件事都是权衡的
每个部分都包含指向更深入资源的链接
根据您的面试时间表(短、中、长)建议复习的主题
问:对于面试,我需要知道这里的一切吗?
A:不,你不需要了解这里的一切来准备面试
你在面试中被问到的问题取决于以下变量:
更有经验的应聘者通常会对系统设计有更多的了解。架构师或团队领导可能会比单个贡献者了解更多。顶级科技公司可能会有一轮或多轮设计面试
从宽泛开始,在几个领域深入研究。它有助于您对各种关键的系统设计主题有所了解。根据您的时间表、经验、您面试的职位以及您面试的公司调整以下指南
Short | Medium | Long | |
---|---|---|---|
Read through the System design topics to get a broad understanding of how systems work | :+1: | :+1: | :+1: |
Read through a few articles in the Company engineering blogs for the companies you are interviewing with | :+1: | :+1: | :+1: |
Read through a few Real world architectures | :+1: | :+1: | :+1: |
Review How to approach a system design interview question | :+1: | :+1: | :+1: |
Work through System design interview questions with solutions | Some | Many | Most |
Work through Object-oriented design interview questions with solutions | Some | Many | Most |
Review Additional system design interview questions | Some | Many | Most |
如何进行撞击系统设计面试题
系统设计面试是一场开放式的谈话。希望你来领导它
您可以使用以下步骤来指导讨论。要帮助巩固此过程,请使用以下步骤完成系统设计面试问题与解决方案部分
收集需求并确定问题范围。提出问题以澄清用例和约束。讨论假设
概述包含所有重要组件的高级设计
深入了解每个核心组件的详细信息。例如,如果您被要求设计一个url缩短服务,请讨论:
在给定约束的情况下,确定并解决瓶颈问题。例如,您是否需要以下内容来解决可伸缩性问题?
讨论潜在的解决方案和权衡。每件事都是权衡的。使用可扩展系统设计原则解决瓶颈问题
你可能会被要求手工做一些估算。有关以下资源,请参阅附录:
请查看以下链接,以更好地了解预期内容:
带有示例讨论、代码和图表的常见系统设计面试问题
链接到解决方案/文件夹中内容的解决方案
Question | |
---|---|
Design Pastebin.com (or Bit.ly) | Solution |
Design the Twitter timeline and search (or Facebook feed and search) | Solution |
Design a web crawler | Solution |
Design Mint.com | Solution |
Design the data structures for a social network | Solution |
Design a key-value store for a search engine | Solution |
Design Amazon’s sales ranking by category feature | Solution |
Design a system that scales to millions of users on AWS | Solution |
Add a system design question | Contribute |
查看练习和解决方案
查看练习和解决方案
查看练习和解决方案
查看练习和解决方案
查看练习和解决方案
查看练习和解决方案
查看练习和解决方案
查看练习和解决方案
常见的面向对象设计面试问题,带有示例讨论、代码和图表
注:此部分正在开发中。
是系统设计的新手吗?
Question | |
---|---|
Design a hash map | Solution |
Design a least recently used cache | Solution |
Design a call center | Solution |
Design a deck of cards | Solution |
Design a parking lot | Solution |
Design a chat server | Solution |
Design a circular array | Contribute |
Add an object-oriented design question | Contribute |
首先,您需要基本了解通用原则,了解它们是什么、如何使用以及它们的优缺点
哈佛大学可伸缩性讲座
可扩展性
接下来,我们来看看高级权衡:
请记住,每件事都是权衡的。
然后,我们将深入探讨更具体的主题,如DNS、CDN和负载均衡器
如果服务以与添加的资源成正比的方式提高性能,则该服务是可伸缩的。通常,提高性能意味着服务更多的工作单元,但也可以处理更大的工作单元,例如当数据集增长时。1
看待性能与可伸缩性的另一种方式:
延迟是执行某种操作或产生某种结果的时间
吞吐量是每单位时间内此类操作或结果的数量
通常,您应该以具有可接受延迟的最大吞吐量为目标
资料来源:复习上限定理
在分布式计算机系统中,您只能支持以下两项保证:
网络不可靠,因此您需要支持分区容错。您需要在一致性和可用性之间进行软件权衡
等待来自分区节点的响应可能会导致超时错误。如果您的业务需求需要原子读写,CP是一个很好的选择
响应返回任何节点上可用的最容易获得的数据版本,该版本可能不是最新版本。在解析分区时,写入可能需要一些时间才能传播
如果业务需要考虑到最终的一致性,或者当系统需要在出现外部错误的情况下继续工作时,AP是一个很好的选择
对于同一数据的多个副本,我们面临着如何对它们进行同步操作的选择,以便客户对数据有一致的看法。回想一下CAP定理中的一致性定义-每次读取都会收到最近的写入或错误
写入后,读取可能会也可能看不到它。采取了尽力而为的方法
这种方法可以在memcached等系统中看到。弱一致性适用于VoIP、视频聊天和实时多人游戏等实时用例。例如,如果您正在打电话,并且在几秒钟内失去接收,那么当您重新连接时,您听不到在连接中断期间所说的话
写入之后,读取最终会看到它(通常在毫秒内)。异步复制数据
在DNS和电子邮件等系统中可以看到这种方法。最终一致性在高可用性系统中运行良好
写入后,Reads将看到它。同步复制数据
这种方法可以在文件系统和RDBMS中看到。强一致性在需要事务的系统中运行良好
支持高可用性有两种互补模式:故障切换和复制
使用主动-被动故障转移时,会在处于备用状态的主动服务器和被动服务器之间发送心跳。如果心跳中断,被动服务器将接管主动服务器的IP地址并恢复服务
停机时间的长短取决于被动服务器是否已经在“热”待机状态下运行,或者它是否需要从“冷”待机状态启动。只有活动服务器才能处理流量
主动-被动故障切换也可以称为主-从故障切换
在主动-主动模式下,两台服务器都在管理流量,在它们之间分担负载
如果服务器是面向公众的,则DNS需要知道两个服务器的公共IP。如果服务器是面向内部的,则应用程序逻辑需要了解这两个服务器
主动-主动故障切换也可以称为主-主故障切换
此主题将在数据库部分进一步讨论:
可用性通常通过正常运行时间(或停机时间)作为服务可用时间的百分比来量化。可用性通常用数字9来衡量–99.99%可用性的服务被描述为有四个9
如果服务由多个容易发生故障的组件组成,则服务的总体可用性取决于这些组件是顺序的还是并行的
Duration | Acceptable downtime |
---|---|
Downtime per year | 8h 45min 57s |
Downtime per month | 43m 49.7s |
Downtime per week | 10m 4.8s |
Downtime per day | 1m 26.4s |
Duration | Acceptable downtime |
---|---|
Downtime per year | 52min 35.7s |
Downtime per month | 4m 23s |
Downtime per week | 1m 5s |
Downtime per day | 8.6s |
当两个可用性<100%的组件按顺序排列时,总体可用性会降低:
如果Foo和Bar都有99.9%的可用性,那么它们的总可用性依次为99.8%
Availability (Total) = Availability (Foo) * Availability (Bar)
当两个可用性<100%的组件并行时,总体可用性会提高:
如果Foo和BAR都有99.9%的可用性,那么它们并行的总可用性将是99.9999%
Availability (Total) = 1 - (1 - Availability (Foo)) * (1 - Availability (Bar))
来源:DNS安全演示
域名系统(DNS)将域名(如www.example.com)转换为IP地址
DNS是分层的,顶层有几个权威服务器。您的路由器或ISP提供有关执行查找时联系哪些DNS服务器的信息。较低级别的DNS服务器缓存映射,这些映射可能会因DNS传播延迟而变得陈旧。您的浏览器或操作系统还可以将DNS结果缓存一段时间,具体取决于生存时间(TTL)
CloudFlare和Route 53等服务提供托管DNS服务。某些DNS服务可以通过各种方法路由流量:
CNAME
(example.com to www.example.com) or to an A
record.来源:为什么使用CDN
内容递送网络(CDN)是全球分布的代理服务器网络,提供来自更靠近用户的位置的内容。一般情况下,静电文件(如html/css/js)、照片和视频都是由云服务提供的,但有些云服务(如亚马逊的云前端)支持动态内容。站点的DNS解析将告诉客户端要联系哪个服务器
从CDN提供内容可以通过两种方式显著提高性能:
每当您的服务器发生更改时,推送CDN都会接收新内容。您负责提供内容、直接上传到CDN、重写指向CDN的URL。您可以配置内容何时过期以及何时更新。只有在内容是新的或更改的情况下才会上载内容,从而最大限度地减少流量,但最大限度地提高存储
流量较小的站点或内容不经常更新的站点可以很好地使用推送CDN。内容只放在CDN上一次,而不是定期重新拉取
拉取CDN在第一个用户请求内容时从您的服务器抓取新内容。您将内容保留在服务器上,并重写URL以指向CDN。这会导致请求速度变慢,直到内容缓存在CDN上
生存时间(TTL)确定缓存内容的时间长度。拉取CDN最大限度地减少了CDN上的存储空间,但如果文件过期并在实际更改之前被拉取,则可能会产生冗余流量
流量大的站点可以很好地使用拉式CDN,因为流量分布更均匀,只有最近请求的内容保留在CDN上
来源:可伸缩系统设计模式
负载平衡器将传入的客户端请求分发到应用程序服务器和数据库等计算资源。在每种情况下,负载均衡器都会将来自计算资源的响应返回到相应的客户端。负载均衡器在以下方面有效:
负载均衡器可以通过硬件(昂贵)或软件(如HAProxy)实现
其他优势包括:
为了防止故障,通常在主动-被动或主动-主动模式下设置多个负载均衡器
负载均衡器可以根据各种指标路由流量,包括:
第4层负载均衡器查看传输层的信息,以决定如何分发请求。通常,这涉及报头中的源IP地址、目的IP地址和端口,但不涉及数据包的内容。第4层负载均衡器转发进出上游服务器的网络数据包,执行网络地址转换(NAT)
第7层负载均衡器查看应用层以决定如何分发请求。这可能涉及标头、消息和Cookie的内容。第7层负载均衡器终止网络流量,读取消息,做出负载平衡决策,然后打开到所选服务器的连接。例如,第7层负载均衡器可以将视频流量定向到托管视频的服务器,同时将更敏感的用户计费流量定向到经过安全强化的服务器
以灵活性为代价,与第7层相比,第4层负载平衡需要更少的时间和计算资源,尽管对现代商用硬件的性能影响可能微乎其微
负载均衡器还可以帮助进行水平扩展,从而提高性能和可用性。与在更昂贵的硬件上纵向扩展单个服务器(称为垂直扩展)相比,使用商用计算机进行横向扩展更具成本效益,并带来更高的可用性。与专门的企业系统相比,在商用硬件上工作的人才也更容易招聘
来源:维基百科
反向代理是集中内部服务并向公众提供统一接口的Web服务器。在反向代理将服务器的响应返回给客户端之前,将来自客户端的请求转发到可以实现该请求的服务器
来源:规模架构系统简介
通过将Web层与应用层(也称为平台层)分开,您可以分别扩展和配置这两个层。添加新API会导致添加应用程序服务器,而不必添加额外的Web服务器。单一责任原则主张共同工作的小型自主服务。拥有小型服务的小型团队可以更积极地规划快速增长
应用程序层中的工作者也有助于启用异步
与此讨论相关的是微服务,可以将其描述为一套可独立部署的小型模块化服务。每个服务都运行一个独特的流程,并通过定义良好的轻量级机制进行通信,以服务于业务目标。1个
例如,Pinterest可以拥有以下微服务:用户档案、追随者、馈送、搜索、照片上传等
诸如Consul、etcd和ZooKeeper这样的系统可以通过跟踪注册的名称、地址和端口来帮助服务找到彼此。运行状况检查有助于验证服务完整性,通常使用HTTP端点来完成。Consul和etcd都有一个内置的键值存储,可用于存储配置值和其他共享数据
来源:向上扩展至您的第一个1000万用户
像SQL这样的关系数据库是以表形式组织的数据项的集合
ACID是关系数据库事务的一组属性
扩展关系数据库有许多技术:主-从复制、主-主复制、联合、分片、反规范化和SQL调优
主机服务于读取和写入,将写入复制到一个或多个仅服务于读取的从机。从属设备还可以以树状方式复制到其他从属设备。如果主机脱机,系统可以继续以只读模式运行,直到将从属提升为主机或调配新主机
来源:可伸缩性、可用性、稳定性、模式
两个主机都提供读写服务,并在写入时相互协调。如果任一主机发生故障,系统可以在读取和写入的情况下继续运行
来源:可伸缩性、可用性、稳定性、模式
来源:向上扩展至您的第一个1000万用户
联合(或功能分区)按功能拆分数据库。例如,您可以拥有三个数据库,而不是一个单一的整体数据库:论坛、用户和产品,从而减少每个数据库的读写流量,从而减少复制延迟。较小的数据库会产生更多可以放入内存的数据,这反过来又会因为改进的高速缓存位置而导致更多的高速缓存命中率。由于没有单个中央主机串行化写入,您可以并行写入,从而增加吞吐量
来源:可伸缩性、可用性、稳定性、模式
分片将数据分布在不同的数据库中,以便每个数据库只能管理数据的一个子集。以用户数据库为例,随着用户数量的增加,集群中会添加更多的分片
与联合的优点类似,分片可以减少读写流量、减少复制和增加缓存命中率。索引大小也会减小,这通常会通过更快的查询提高性能。如果一个碎片发生故障,其他碎片仍可运行,尽管您需要添加某种形式的复制以避免数据丢失。与联合一样,没有单个串行化写入的中央主机,允许您在提高吞吐量的同时并行写入
共享用户表的常见方式是通过用户的姓氏首字母或用户的地理位置
反规格化试图以牺牲一些写入性能为代价来提高读取性能。数据的冗余副本被写入多个表中,以避免昂贵的联接。一些RDBMS(如PostgreSQL和Oracle)支持物化视图,物化视图处理存储冗余信息和保持冗余副本一致的工作
使用联合和分片等技术分发数据后,管理跨数据中心的联接会进一步增加复杂性。反规格化可能会绕过对这种复杂连接的需要。
在大多数系统中,读取的数量可能远远超过写入的数量100:1甚至1000:1。导致复杂数据库联接的读取可能非常昂贵,会花费大量时间进行磁盘操作
SQL调优是一个涉及面很广的主题,很多书都是作为参考编写的
重要的是要进行基准测试和性能分析,以模拟和发现瓶颈
基准测试和性能分析可能会为您提供以下优化
NoSQL是键值存储、文档存储、宽列存储或图形数据库中表示的数据项的集合。数据被反规范化,连接通常在应用程序代码中完成。大多数NoSQL存储缺乏真正的ACID事务,倾向于最终的一致性
BASE通常用来描述NoSQL数据库的属性。与CAP定理相比,BASE选择可用性而不是一致性
CHAR
instead of VARCHAR
for fixed-length fields.
CHAR
effectively allows for fast, random access, whereas with VARCHAR
, you must find the end of a string before moving onto the next one.TEXT
for large blocks of text such as blog posts. TEXT
also allows for boolean searches. Using a TEXT
field results in storing a pointer on disk that is used to locate the text block.INT
for larger numbers up to 2^32 or 4 billion.DECIMAL
for currency to avoid floating point representation errors.BLOBS
, store the location of where to get the object instead.VARCHAR(255)
is the largest number of characters that can be counted in an 8 bit number, often maximizing the use of a byte in some RDBMS.NOT NULL
constraint where applicable to improve search performance.SELECT
, GROUP BY
, ORDER BY
, JOIN
) could be faster with indices.除了在SQL或NoSQL之间进行选择之外,了解哪种类型的NoSQL数据库最适合您的用例也很有帮助。在下一节中,我们将回顾键值存储、文档存储、宽列存储和图形数据库
抽象:哈希表
键值存储通常允许O(1)次读取和写入,并且通常由内存或SSD支持。数据存储可以按字典顺序维护键,从而允许高效地检索键范围。键值存储可允许存储具有值的元数据
键值存储提供高性能,通常用于简单数据模型或快速变化的数据,如内存缓存层。由于它们只提供有限的操作集,因此如果需要额外的操作,复杂性将转移到应用层
键值存储是更复杂系统(如文档存储,在某些情况下还包括图形数据库)的基础
抽象:键值存储,文档存储为值
文档存储以文档(XML、JSON、二进制等)为中心,文档存储给定对象的所有信息。文档存储提供基于文档本身的内部结构进行查询的API或查询语言。请注意,许多键值存储包括用于使用值的元数据的功能,从而模糊了这两种存储类型之间的界限
根据底层实现,文档按集合、标签、元数据或目录进行组织。尽管可以将文档组织或分组在一起,但文档的字段可能彼此完全不同
一些文档存储,如MongoDB和CouchDB,也提供了一种类似SQL的语言来执行复杂的查询。DynamoDB同时支持键值和文档
文档存储具有很高的灵活性,通常用于处理偶尔更改的数据
来源:SQL&NoSQL,简史
抽象:嵌套映射ColumnFamily<RowKey,Columns<ColKey,Value,Timestamp>>
宽列存储的基本数据单位是列(名称/值对)。列可以按列族分组(类似于SQL表)。超级柱族进一步将柱族分组。您可以使用行键单独访问每列,具有相同行键的列形成一行。每个值都包含一个用于版本化和冲突解决的时间戳
Google引入了Bigtable作为第一个宽列存储,它影响了Hadoop生态系统中经常使用的开源HBase,以及Facebook的Cassandra。Bigtable、HBase和Cassandra等存储按字典顺序维护键,从而允许高效地检索选择性键范围
宽列存储提供高可用性和高可伸缩性。它们通常用于非常大的数据集
来源:图表数据库
抽象:图表
在图形数据库中,每个节点是一条记录,每条弧是两个节点之间的关系。对图形数据库进行了优化,以表示具有多个外键或多对多关系的复杂关系
图形数据库为具有复杂关系的数据模型(如社交网络)提供高性能。它们相对较新,尚未广泛使用;可能更难找到开发工具和资源。很多图表只能通过睡觉API访问
来源:从RDBMS过渡到NoSQL
SQL的原因:
使用NoSQL的原因:
非常适合NoSQL的示例数据:
来源:可伸缩系统设计模式
缓存可以缩短页面加载时间,并可以减少服务器和数据库的负载。在此模型中,调度程序将首先查找以前是否已发出请求,并尝试查找要返回的前一个结果,以便保存实际执行
数据库通常受益于跨其分区的读和写的统一分布。受欢迎的项目可能会扭曲分布,造成瓶颈。将缓存放在数据库前面有助于吸收不均匀的负载和流量高峰
缓存可以位于客户端(操作系统或浏览器)、服务器端或位于不同的缓存层中
CDN被认为是一种缓存
反向代理和缓存(如varish)可以直接服务于静电和动态内容。Web服务器还可以缓存请求,无需联系应用程序服务器即可返回响应
您的数据库通常在默认配置中包含某种级别的缓存,针对一般用例进行了优化。针对特定的使用模式调整这些设置可以进一步提高性能
内存缓存(如memcached和redis)是应用程序和数据存储之间的键值存储。由于数据保存在RAM中,因此它比数据存储在磁盘上的典型数据库快得多。RAM比磁盘更有限,因此缓存失效算法(如最近最少使用(LRU))可以帮助使“冷”条目无效,并将“热”数据保留在RAM中
Redis具有以下附加功能:
您可以缓存多个级别,分为两个一般类别:数据库查询和对象:
通常,您应该尽量避免基于文件的缓存,因为这会增加克隆和自动缩放的难度
无论何时查询数据库,都要将查询作为键进行散列,并将结果存储到缓存中。此方法存在过期问题:
将数据视为对象,类似于您对应用程序代码所做的操作。让您的应用程序将数据库中的数据集组装成一个类实例或一个或多个数据结构:
缓存内容的建议:
由于您只能在缓存中存储有限数量的数据,因此您需要确定哪种缓存更新策略最适合您的用例
来源:从缓存到内存中数据网格
应用程序负责从存储中读取和写入。缓存不直接与存储交互。应用程序执行以下操作:
memcached通常以这种方式使用
后续读取添加到高速缓存的数据速度很快。侧缓存也称为惰性加载。仅缓存请求的数据,从而避免使用未请求的数据填满缓存
def get_user(self, user_id):
user = cache.get("user.{0}", user_id)
if user is None:
user = db.query("SELECT * FROM users WHERE user_id = {0}", user_id)
if user is not None:
key = "user.{0}".format(user_id)
cache.set(key, json.dumps(user))
return user
来源:可伸缩性、可用性、稳定性、模式
应用程序使用高速缓存作为主数据存储,对其进行读写数据,而高速缓存负责对数据库进行读写:
应用程序代码:
缓存代码:
由于写入操作,直写操作的总体速度较慢,但后续读取刚写入的数据会很快。用户在更新数据时通常比读取数据时更能容忍延迟。缓存中的数据未过时
set_user(12345, {"foo":"bar"})
来源:可伸缩性、可用性、稳定性、模式
def set_user(user_id, values):
user = db.query("UPDATE Users WHERE id = {0}", user_id, values)
cache.set(user_id, user)
在Write-Back中,应用程序执行以下操作:
来源:从缓存到内存中数据网格
您可以将缓存配置为在任何最近访问的缓存条目到期之前自动刷新
如果缓存可以准确预测将来可能需要哪些项目,则与直读相比,提前刷新可以降低延迟
来源:规模架构系统简介
异步工作流有助于减少代价高昂的操作的请求时间,否则这些操作将以内联方式执行。他们还可以通过提前执行耗时的工作来提供帮助,例如定期聚合数据
消息队列接收、保存和传递消息。如果操作速度太慢而无法以内联方式执行,则可以将消息队列与以下工作流结合使用:
用户不会被阻止,作业将在后台处理。在此期间,客户端可能会选择性地进行少量处理,使其看起来好像任务已经完成。例如,如果发布一条tweet,该tweet可以立即发布到您的时间表上,但可能需要一段时间才能真正将您的tweet发送给您的所有追随者
Redis作为简单的消息代理很有用,但消息可能会丢失
RabbitMQ很流行,但需要您适应‘AMQP’协议并管理您自己的节点
Amazon SQS是托管的,但可能会有很高的延迟,并且可能会传递两次消息
任务队列接收任务及其相关数据,运行它们,然后交付结果。它们可以支持调度,并可用于在后台运行计算密集型作业
芹菜支持调度,并且主要支持python。
如果队列开始显著增长,队列大小可能会大于内存,从而导致缓存未命中、磁盘读取,甚至会降低性能。反压可以通过限制队列大小来提供帮助,从而为队列中已有的作业保持较高的吞吐率和良好的响应时间。一旦队列填满,客户端就会收到服务器繁忙或HTTP 503状态代码,以便稍后重试。客户端可以稍后重试请求,可能会使用指数回退
来源:OSI 7层模型
HTTP是一种在客户端和服务器之间编码和传输数据的方法。它是一种请求/响应协议:客户端发出请求,服务器发出响应,其中包含请求的相关内容和完成状态信息。HTTP是独立的,允许请求和响应流经许多执行负载平衡、缓存、加密和压缩的中间路由器和服务器
基本HTTP请求由谓词(方法)和资源(端点)组成。以下是常见的HTTP谓词:
*可以多次调用,没有不同的结果
HTTP是依赖于较低级别协议(如TCP和UDP)的应用层协议
Verb | Description | Idempotent* | Safe | Cacheable |
---|---|---|---|---|
GET | Reads a resource | Yes | Yes | Yes |
POST | Creates a resource or trigger a process that handles data | No | No | Yes if response contains freshness info |
PUT | Creates or replace a resource | Yes | No | No |
PATCH | Partially updates a resource | No | No | Yes if response contains freshness info |
DELETE | Deletes a resource | Yes | No | No |
来源:如何制作多人游戏
TCP是IP网络上的面向连接的协议。使用握手建立和终止连接。所有发送的数据包都保证按原始顺序到达目的地,并且通过以下方式不会损坏:
如果发送方没有收到正确的响应,它将重新发送数据包。如果存在多个超时,则连接将断开。TCP还实施流量控制和拥塞控制。这些保证会导致延迟,并且通常会导致传输效率低于UDP
为了确保高吞吐量,Web服务器可以保持大量TCP连接处于打开状态,从而导致高内存使用率。在web服务器线程和memcached服务器(比方说)之间具有大量打开的连接可能代价高昂。除了在适用的情况下切换到UDP之外,连接池还可以提供帮助
TCP对于要求高可靠性但对时间要求较低的应用程序很有用。一些示例包括Web服务器、数据库信息、SMTP、FTP和SSH
在以下情况下使用UDP上的TCP:
来源:如何制作多人游戏
UDP是无连接的。数据报(类似于数据包)仅在数据报级别得到保证。数据报可能无序到达目的地,也可能根本没有到达目的地。UDP不支持拥塞控制。如果没有TCP支持的保证,UDP通常更有效
UDP可以广播,向子网中的所有设备发送数据报。这对于DHCP很有用,因为客户端尚未接收到IP地址,因此阻止了TCP在没有IP地址的情况下流式传输
UDP的可靠性较低,但在VoIP、视频聊天、流和实时多人游戏等实时使用案例中运行良好
在以下情况下使用TCP上的UDP:
来源:破解系统设计访谈
在RPC中,客户端导致过程在不同的地址空间(通常是远程服务器)上执行。该过程的编码就好像它是一个本地过程调用,从客户端程序抽象出如何与服务器通信的细节。远程调用通常比本地调用更慢、更不可靠,因此区分RPC调用和本地调用很有帮助。流行的RPC框架包括Protobuf、Thrift和Avro
RPC是一种请求-响应协议:
示例RPC调用:
RPC专注于公开行为。RPC通常用于内部通信的性能原因,因为您可以手工创建本地调用以更好地适应您的用例
在以下情况下选择本机库(也称为SDK):
GET /someoperation?data=anId
POST /anotheroperation
{
"data":"anId";
"anotherdata": "another value"
}
睡觉之后的HTTP接口倾向于更常用于公共接口
睡觉是一种实施客户端/服务器模型的体系结构风格,其中客户端作用于由服务器管理的一组资源。服务器提供资源和动作的表示,这些资源和动作既可以操作资源,也可以获得新的资源表示。所有通信必须是无状态和可缓存的
REST风格的界面有四个特点:
睡觉调用示例:
睡觉专注于数据曝光。它最大限度地减少了客户端/服务器之间的耦合,通常用于公共HTTPAPI。睡觉使用一种更通用、更统一的方法,通过URI公开资源,通过头部表示,通过GET、POST、PUT、DELETE和PATCH等动词进行操作。由于是无状态的,睡觉非常适合水平伸缩和分区
来源:你真的知道为什么你更喜欢睡觉而不是rpc吗?
GET /someresources/anId
PUT /someresources/anId
{"anotherdata": "another value"}
此部分可能需要一些更新。考虑捐款吧!
Operation | RPC | REST |
---|---|---|
Signup | POST /signup | POST /persons |
Resign | POST /resign { “personid”: “1234” } |
DELETE /persons/1234 |
Read a person | GET /readPerson?personid=1234 | GET /persons/1234 |
Read a person’s items list | GET /readUsersItemsList?personid=1234 | GET /persons/1234/items |
Add an item to a person’s items | POST /addItemToUsersItemsList { “personid”: “1234”; “itemid”: “456” } |
POST /persons/1234/items { “itemid”: “456” } |
Update an item | POST /modifyItem { “itemid”: “456”; “key”: “value” } |
PUT /items/456 { “key”: “value” } |
Delete an item | POST /removeItem { “itemid”: “456” } |
DELETE /items/456 |
安全是一个广泛的话题。除非你有相当多的经验,有安全背景,或者正在申请一个需要安全知识的职位,否则你可能不需要知道更多的基础知识:
有时你会被要求做“粗略”的估算。例如,您可能需要确定从磁盘生成100个图像缩略图需要多长时间,或者一个数据结构需要多少内存。每个程序员都应该知道的两个表的幂和延迟数字是很方便的参考资料
基于以上数字的便捷指标:
Power Exact Value Approx Value Bytes
---------------------------------------------------------------
7 128
8 256
10 1024 1 thousand 1 KB
16 65,536 64 KB
20 1,048,576 1 million 1 MB
30 1,073,741,824 1 billion 1 GB
32 4,294,967,296 4 GB
40 1,099,511,627,776 1 trillion 1 TB
Latency Comparison Numbers
--------------------------
L1 cache reference 0.5 ns
Branch mispredict 5 ns
L2 cache reference 7 ns 14x L1 cache
Mutex lock/unlock 25 ns
Main memory reference 100 ns 20x L2 cache, 200x L1 cache
Compress 1K bytes with Zippy 10,000 ns 10 us
Send 1 KB bytes over 1 Gbps network 10,000 ns 10 us
Read 4 KB randomly from SSD* 150,000 ns 150 us ~1GB/sec SSD
Read 1 MB sequentially from memory 250,000 ns 250 us
Round trip within same datacenter 500,000 ns 500 us
Read 1 MB sequentially from SSD* 1,000,000 ns 1,000 us 1 ms ~1GB/sec SSD, 4X memory
HDD seek 10,000,000 ns 10,000 us 10 ms 20x datacenter roundtrip
Read 1 MB sequentially from 1 Gbps 10,000,000 ns 10,000 us 10 ms 40x memory, 10X SSD
Read 1 MB sequentially from HDD 30,000,000 ns 30,000 us 30 ms 120x memory, 30X SSD
Send packet CA->Netherlands->CA 150,000,000 ns 150,000 us 150 ms
Notes
-----
1 ns = 10^-9 seconds
1 us = 10^-6 seconds = 1,000 ns
1 ms = 10^-3 seconds = 1,000 us = 1,000,000 ns
常见的系统设计面试问题,以及有关如何解决每个问题的资源链接
有关如何设计真实系统的文章
来源:Twitter时间表按规模
Question | Reference(s) |
---|---|
Design a file sync service like Dropbox | youtube.com |
Design a search engine like Google | queue.acm.org stackexchange.com ardendertat.com stanford.edu |
Design a scalable web crawler like Google | quora.com |
Design Google docs | code.google.com neil.fraser.name |
Design a key-value store like Redis | slideshare.net |
Design a cache system like Memcached | slideshare.net |
Design a recommendation system like Amazon’s | hulu.com ijcai13.org |
Design a tinyurl system like Bitly | n00tc0d3r.blogspot.com |
Design a chat app like WhatsApp | highscalability.com |
Design a picture sharing system like Instagram | highscalability.com highscalability.com |
Design the Facebook news feed function | quora.com quora.com slideshare.net |
Design the Facebook timeline function | facebook.com highscalability.com |
Design the Facebook chat function | erlang-factory.com facebook.com |
Design a graph search function like Facebook’s | facebook.com facebook.com facebook.com |
Design a content delivery network like CloudFlare | figshare.com |
Design a trending topic system like Twitter’s | michael-noll.com snikolov .wordpress.com |
Design a random ID generation system | blog.twitter.com github.com |
Return the top k requests during a time interval | cs.ucsb.edu wpi.edu |
Design a system that serves data from multiple data centers | highscalability.com |
Design an online multiplayer card game | indieflashblog.com buildnewgames.com |
Design a garbage collection system | stuffwithstuff.com washington.edu |
Design an API rate limiter | https://stripe.com/blog/ |
Design a Stock Exchange (like NASDAQ or Binance) | Jane Street Golang Implementation Go Implemenation |
Add a system design question | Contribute |
在下面的文章中,不要把重点放在具体的细节上,而是:
您面试的公司的架构
您遇到的问题可能来自同一个域
Type | System | Reference(s) |
---|---|---|
Data processing | MapReduce – Distributed data processing from Google | research.google.com |
Data processing | Spark – Distributed data processing from Databricks | slideshare.net |
Data processing | Storm – Distributed data processing from Twitter | slideshare.net |
Data store | Bigtable – Distributed column-oriented database from Google | harvard.edu |
Data store | HBase – Open source implementation of Bigtable | slideshare.net |
Data store | Cassandra – Distributed column-oriented database from Facebook | slideshare.net |
Data store | DynamoDB – Document-oriented database from Amazon | harvard.edu |
Data store | MongoDB – Document-oriented database | slideshare.net |
Data store | Spanner – Globally-distributed database from Google | research.google.com |
Data store | Memcached – Distributed memory caching system | slideshare.net |
Data store | Redis – Distributed memory caching system with persistence and value types | slideshare.net |
File system | Google File System (GFS) – Distributed file system | research.google.com |
File system | Hadoop File System (HDFS) – Open source implementation of GFS | apache.org |
Misc | Chubby – Lock service for loosely-coupled distributed systems from Google | research.google.com |
Misc | Dapper – Distributed systems tracing infrastructure | research.google.com |
Misc | Kafka – Pub/sub message queue from LinkedIn | slideshare.net |
Misc | Zookeeper – Centralized infrastructure and services enabling synchronization | slideshare.net |
Add an architecture | Contribute |
想要添加博客吗?为避免重复工作,请考虑将您的公司博客添加到以下回购中:
有兴趣添加一个部分或帮助完成一个正在进行的部分吗?贡献自己的力量!
在整个回购过程中提供积分和来源
特别感谢:
请随时与我联系,讨论任何问题、问题或评论
我的联系信息可以在我的GitHub页面上找到
我在开放源码许可下向您提供此存储库中的代码和资源。因为这是我的个人存储库,您获得的我的代码和资源的许可证来自我,而不是我的雇主(Facebook)
动机
Anki抽认卡
Copyright 2017 Donne Martin
Creative Commons Attribution 4.0 International License (CC BY 4.0)
http://creativecommons.org/licenses/by/4.0/
Documentation |
---|
TensorFlow是一个端到端的机器学习开源平台。它有一个由工具、库和社区资源组成的全面、灵活的生态系统,使研究人员能够使用ML推动最先进的技术,开发人员可以轻松地构建和部署基于ML的应用程序
TensorFlow最初是由谷歌机器智能研究组织内谷歌大脑团队的研究人员和工程师开发的,目的是进行机器学习和深度神经网络研究。该系统具有足够的通用性,可以广泛应用于其他领域
TensorFlow提供稳定的Python和C++API,以及不保证向后兼容的其他语言API
订阅untify@tensorflow.org,随时了解最新的版本公告和安全更新。查看所有邮件列表
请参阅PIP包的TensorFlow安装指南,要启用GPU支持,请使用Docker容器,并从源代码构建
要安装当前版本(包括对启用CUDA的GPU卡(Ubuntu和Windows)的支持),请执行以下操作:
$ pip install tensorflow
此外,还提供了一个较小的仅限CPU的软件包:
$ pip install tensorflow-cpu
要将TensorFlow更新到最新版本,请在上述命令中添加–upgrade标志
夜间二进制文件可用于在PyPI上使用tf-nighly和tf-nighly-cpu包进行测试
$ python
>>> import tensorflow as tf
>>> tf.add(1, 2).numpy()
3
>>> hello = tf.constant('Hello, TensorFlow!')
>>> hello.numpy()
b'Hello, TensorFlow!'
有关更多示例,请参阅TensorFlow教程
如果您想对TensorFlow做出贡献,请务必查看贡献指南。该项目遵循TensorFlow的行为准则。通过参与,您应该遵守本守则
我们使用GitHub问题来跟踪请求和错误,有关一般问题和讨论,请参阅TensorFlow讨论,并请将具体问题直接指向Stack Overflow
TensorFlow项目致力于遵守开源软件开发中公认的最佳实践:
您可以在TensorFlow SIG build社区构建表中找到更多社区支持的平台和配置
Build Type | Status | Artifacts |
---|---|---|
Linux CPU | PyPI | |
Linux GPU | PyPI | |
Linux XLA | TBA | |
macOS | PyPI | |
Windows CPU | PyPI | |
Windows GPU | PyPI | |
Android | ||
Raspberry Pi 0 and 1 | Py3 | |
Raspberry Pi 2 and 3 | Py3 | |
Libtensorflow MacOS CPU | Status Temporarily Unavailable | Nightly Binary Official GCS |
Libtensorflow Linux CPU | Status Temporarily Unavailable | Nightly Binary Official GCS |
Libtensorflow Linux GPU | Status Temporarily Unavailable | Nightly Binary Official GCS |
Libtensorflow Windows CPU | Status Temporarily Unavailable | Nightly Binary Official GCS |
Libtensorflow Windows GPU | Status Temporarily Unavailable | Nightly Binary Official GCS |
了解有关TensorFlow社区以及如何做出贡献的更多信息
Apache License 2.0
该存储库包含完整的Python数据科学手册,其形式为(免费!)Jupyter笔记本
本书是使用Python3.5编写和测试的,尽管其他Python版本(包括Python2.7)几乎可以在所有情况下运行
本书介绍了在Python中使用数据所必需的核心库:特别是IPython、NumPy、Pandas、Matplotlib、Scikit-Learning和相关包。假设您熟悉Python作为一种语言;如果您需要快速介绍该语言本身,请参阅免费的配套项目-Python旋风之旅:这是针对研究人员和科学家的快速Python语言介绍
请参见Index.ipynb以获取可与文本一起使用的笔记本的索引
书中的代码使用Python 3.5进行了测试,但大多数(但不是全部)也可以在Python 2.7和其他较早的Python版本中正常运行
我用来运行这本书中的代码的包列在Requirements.txt中(请注意,其中一些确切的版本号在您的平台上可能不可用:您可能必须调整它们以供您自己使用)。要使用CONDA安装需求,请在命令行运行以下命令:
$ conda install --file requirements.txt
要使用Python 3.5和所有必需的软件包版本创建名为pdsh的独立环境,请运行以下命令:
$ conda create -n PDSH python=3.5 --file requirements.txt
您可以在Conda文档的管理环境一节中阅读有关使用Conda环境的更多信息
此存储库中的代码,包括上面列出的笔记本中的所有代码示例,都是在MIT许可下发布的。阅读更多关于开放源码计划的内容
本书的文本内容在CC-by-NC-ND许可下发布。在知识共享网站上阅读更多内容
创建名为 helloworld
的新目录,并转到此目录中:
mkdir hello-cloud-develop cd hello-cloud-develop
创建名为 main.py
的文件,并将以下代码粘贴到其中:
import os from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World!' if __name__ == "__main__": app.run(debug=True, host='0.0.0.0', port=8080)
以上代码会创建一个基本的 Web 服务器,并监听 8080
端口。
在项目根目录下,创建一个名为 Dockerfile
的文件,内容如下:
# 使用官方 Python 轻量级镜像 # https://hub.docker.com/_/python FROM python:3.8-slim # 将本地代码拷贝到容器内 ENV APP_HOME /app WORKDIR $APP_HOME COPY . ./ # 安装依赖 RUN pip install Flask gunicorn # 启动 Web 服务 # 这里我们使用了 gunicorn 作为 Server,1 个 worker 和 8 个线程 # 如果您的容器实例拥有多个 CPU 核心,我们推荐您把线程数设置为与 CPU 核心数一致 CMD exec gunicorn --bind :8080 --workers 1 --threads 8 --timeout 0 main:app
添加一个 .dockerignore
文件,以从容器映像中排除文件:
Dockerfile README.md *.pyc *.pyo *.pyd __pycache__ .pytest_cache
你可以选择任何云服务商的云开发服务,这里我选择了腾讯云的CloudBase云托管服务。
在 云托管控制台 的服务列表页面,选择对应的环境,单击【新建服务】。
填写新建服务所需的所有信息默认使用系统推荐的配置即可。
单击【提交】,如果部署成功,便可以看到如下弹框:
单击【新建版本】可立刻开始新建版本并部署,在这里我们选择本地代码,将刚刚写好的文件夹打包为zip文件并上传,端口改为【8080】,流量策略改为【部署完成后自动开启100%流量】,其他配置默认即可:
PS: hello-cloud-develop.zip 可在 Python实用宝典 公众号后台回复:云开发 下载
当然,你也可以选择其他的拉取代码方式,比如代码库或者Docker镜像,按需选择即可。点击开始部署将代码仓库部署为线上服务。
状态变成正常说明部署成功。
部署成功后就可以访问网站了,进入服务配置,找到公网域名:
这个公网域名就是我们部署网站的地址,访问这个公网域名,出现下面页面效果,说明部署成功:
恭喜!你已经成功通过云开发部署一个网站了,准确来讲是云托管服务。这种部署方式实在非常舒服,无需自建服务器、成本降低、运维省事。
那些简单的个人网站、官方网站或者论坛,我认为都可以用云托管的形式去部署,能够大大节省投入成本,站长们可以尝试一下。
本文全部代码和文件可在 Python实用宝典 公众号后台回复:云开发 下载。
我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。
有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。
原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!
Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典
Tqdm 是一个智能进度表。它能够显示所有可迭代对象当前执行的进度。
你只需要用 tqdm 对可迭代对象进行封装后再遍历即可实现进度条功能,比如说:
from tqdm import tqdm for i in tqdm(range(10000)): ...
显示效果如下:
76%|████████████████████████ | 7568/10000 [00:33<00:10, 229.00it/s]
开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。
(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.
(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南
Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:
pip install tqdm
tqdm
非常灵活,可以使用多种方式调用。下面给出了三个主要的形式。
使用tqdm()
封装可迭代的对象:
from tqdm import tqdm from time import sleep text = "" for char in tqdm(["a", "b", "c", "d"]): sleep(0.25) text = text + char
trange(i)
是特殊的关键字,是封装了range的tqdm对象:
from tqdm import trange for i in trange(100): sleep(0.01)
你还能控制进度条显示当前步骤的名称:
pbar = tqdm(["a", "b", "c", "d"]) for char in pbar: sleep(0.25) pbar.set_description("Processing %s" % char)
Processing d: 100%|█████████████████████████████████████████████| 4/4 [00:01<00:00, 3.99it/s]
除了迭代的形式,你可以手动控制进度,加一个tqdm上下文即可:
with tqdm(total=100) as pbar: for i in range(10): sleep(0.1) pbar.update(10)
上述例子中,pbar 是 tpdm 的“进度”,每一次对 pbar 进行 update 10 都相当于进度加10。
Total 的值即是总进度,这里 total 的值是100,那么pbar加到100的时候进度也就结束了。
你也可以选择不使用上下文的形式调用,但要记得结束后对对象进行关闭操作:
pbar = tqdm(total=100) for i in range(10): sleep(0.1) pbar.update(10) pbar.close()
Tqdm 最妙的地方在于能在命令行中结合使用:
$ find . -name '*.py' -type f -exec cat \{} \; | tqdm --unit loc --unit_scale --total 857366 >> /dev/null 100%|█████████████████████████████████| 857K/857K [00:04<00:00, 246Kloc/s]
只需在管道之间插入tqdm
(或python -m tqdm
),即可将进度条显示到终端上。
备份大目录:
$ tar -zcf - docs/ | tqdm --bytes --total `du -sb docs/ | cut -f1` \ > backup.tgz 44%|██████████████▊ | 153M/352M [00:14<00:18, 11.0MB/s]
这可以进一步美化:
$ BYTES="$(du -sb docs/ | cut -f1)" $ tar -cf - docs/ \ | tqdm --bytes --total "$BYTES" --desc Processing | gzip \ | tqdm --bytes --total "$BYTES" --desc Compressed --position 1 \ > ~/backup.tgz Processing: 100%|██████████████████████| 352M/352M [00:14<00:00, 30.2MB/s] Compressed: 42%|█████████▎ | 148M/352M [00:14<00:19, 10.9MB/s]
我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。
有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。
原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!
Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典
PyJNIus 是一个神奇的 Python 第三方模块。它能使用Java本地接口将Java类作为Python类访问的Python模块。
如果你需要在Python中使用Java 类,这个第三方模块是你最好的选择。
开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。
(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.
(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南
Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:
pip install pyjnius
使用Jnius导入Java类特别简单,你只需要引入 autoclass 并引用你所需要的类即可:
>>> from jnius import autoclass >>> autoclass('java.lang.System').out.println('Hello world') Hello world >>> Stack = autoclass('java.util.Stack') >>> stack = Stack() >>> stack.push('hello') >>> stack.push('world') >>> print(stack.pop()) world >>> print(stack.pop()) hello
当你引入类后,你只需要按 Java 的函数操作即可,如上述代码中的 push 和 pop 函数。
最令人惊喜的是,你还能在安卓系统中利用这个模块使用Python调用Java类:
from time import sleep from jnius import autoclass Hardware = autoclass('org.renpy.android.Hardware') print('DPI is', Hardware.getDPI()) Hardware.accelerometerEnable(True) for x in xrange(20): print(Hardware.accelerometerReading()) sleep(.1)
输出结果如下:
I/python ( 5983): Android kivy bootstrap done. __name__ is __main__ I/python ( 5983): Run user program, change dir and execute main.py I/python ( 5983): DPI is 160 I/python ( 5983): [0.0, 0.0, 0.0] I/python ( 5983): [-0.0095768067985773087, 9.3852710723876953, 2.2218191623687744] I/python ( 5983): [-0.0095768067985773087, 9.3948478698730469, 2.2218191623687744] I/python ( 5983): [-0.0095768067985773087, 9.3948478698730469, 2.2026655673980713] I/python ( 5983): [-0.028730420395731926, 9.4044246673583984, 2.2122423648834229] I/python ( 5983): [-0.019153613597154617, 9.3852710723876953, 2.2026655673980713] I/python ( 5983): [-0.028730420395731926, 9.3852710723876953, 2.2122423648834229] I/python ( 5983): [-0.0095768067985773087, 9.3852710723876953, 2.1835119724273682] I/python ( 5983): [-0.0095768067985773087, 9.3756942749023438, 2.1835119724273682] I/python ( 5983): [0.019153613597154617, 9.3948478698730469, 2.2122423648834229] I/python ( 5983): [0.038307227194309235, 9.3852710723876953, 2.2218191623687744] I/python ( 5983): [-0.028730420395731926, 9.3948478698730469, 2.2026655673980713] I/python ( 5983): [-0.028730420395731926, 9.3852710723876953, 2.2122423648834229] I/python ( 5983): [-0.038307227194309235, 9.3756942749023438, 2.2026655673980713] I/python ( 5983): [0.3926490843296051, 9.3086557388305664, 1.3311761617660522] I/python ( 5983): [-0.10534487664699554, 9.4331550598144531, 2.1068975925445557] I/python ( 5983): [0.26815059781074524, 9.3469638824462891, 2.3463177680969238] I/python ( 5983): [-0.1149216815829277, 9.3852710723876953, 2.31758713722229] I/python ( 5983): [-0.038307227194309235, 9.41400146484375, 1.8674772977828979] I/python ( 5983): [0.13407529890537262, 9.4235782623291016, 2.2026655673980713]
为了能实现上述效果,你需要使用:python-for-android.
这是Android上Python应用程序的打包工具。您可以创建自己的Python发行版(包括所需的模块和依赖项),并将其与自己的代码捆绑在APK中。
详细教程可以见GitHub:
https://github.com/kivy/python-for-android
当您使用 autoclass
时,它将发现指定Java类的所有方法和字段并对其进行解析。如果你只想声明和使用所需的内容。可以这么弄:
from time import sleep from jnius import MetaJavaClass, JavaClass, JavaMethod, JavaStaticMethod class Hardware(JavaClass): __metaclass__ = MetaJavaClass __javaclass__ = 'org/renpy/android/Hardware' vibrate = JavaStaticMethod('(D)V') accelerometerEnable = JavaStaticMethod('(Z)V') accelerometerReading = JavaStaticMethod('()[F') getDPI = JavaStaticMethod('()I') # 使用这个新类 print('DPI is', Hardware.getDPI()) Hardware.accelerometerEnable() for x in xrange(20): print(Hardware.accelerometerReading()) sleep(.1)
这种形式支持你只引入你想要使用的类,不会造成资源浪费,代码效率更高。
尤其是对于安卓系统有限的资源而言,推荐使用这种局部引入的方式。
当然,如果你是桌面系统(windows, macOS),资源相对充足,使用autoclass引入的方式是可以接受的。不过,在Windows上,确保 JAVA_HOME
指向你的Java安装路径,以便 PyJNIus 可以找到 jvm.dll
.
我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。
有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。
原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!
Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典
Newspaper 是一个很棒的python库,用于提取和整理文章。
它有以下的优点:
下面是这个开源模块的安装和使用教程。
开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。
(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.
(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南
Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:
pip3 install newspaper3k
遇到任何安装问题,可以在本文下方留言框或Python实用宝典公众号上留言,也可以访问项目官网查看相关安装指南:
https://github.com/codelucas/newspaper
Newspaper 中是以文章为对象实现各种操作的,比如下载指定新闻的HTML:
from newspaper import Article url = 'http://fox13now.com/2013/12/30/new-year-new-laws-obamacare-pot-guns-and-drones/' # 根据url生成Article对象 article = Article(url) # 下载文章 article.download() # 文章的HTML article.html #'<!DOCTYPE HTML><html itemscope itemtype="http://...'
通过解析新闻和文章,你能获得此文章的作者、发布时间、摘要、顶部图像、所有图像、多媒体等:
""" Python 实用宝典 《Newspaper — 一个能下载38种语言新闻文章的 Python 模块》 """ # 解析文章 article.parse() # 获取文章作者 article.authors # ['Leigh Ann Caldwell', 'John Honway'] # 获取文章发布日期 article.publish_date # datetime.datetime(2013, 12, 30, 0, 0) # 获取文章文本 article.text # 'Washington (CNN) -- Not everyone subscribes to a New Year's resolution...' # 获取顶部图像 article.top_image # 'http://someCDN.com/blah/blah/blah/file.png' # 获取文章多媒体资源 article.movies # ['http://youtube.com/path/to/link.com', ...]
除此之外,该模块还附带了 NLP 功能,你能用它来识别文章关键字并自动提取摘要:
# 使用 NLP 解析 article.nlp() # 获取文章关键词 article.keywords # ['New Years', 'resolution', ...] # 获取文章摘要 article.summary # 'The study shows that 93% of people ...'
你看,这个工具不无敌吗?它还能提取某个网站的所有新闻文章,比如我想提取CNN的新闻文章:
import newspaper cnn_paper = newspaper.build('http://cnn.com') for article in cnn_paper.articles: print(article.url) # http://www.cnn.com/2013/11/27/justice/tucson-arizona-captive-girls/ # http://www.cnn.com/2013/12/11/us/texas-teen-dwi-wreck/index.html
在此之上,你还能拿到CNN的其他新闻门户分类:
for category in cnn_paper.category_urls(): print(category) # http://lifestyle.cnn.com # http://cnn.com/world # http://tech.cnn.com # ...
许多中文媒体的文章下载也是支持的:
import newspaper sina_paper = newspaper.build('http://www.sina.com.cn/', language='zh') for category in sina_paper.category_urls(): print(category) # http://health.sina.com.cn # http://eladies.sina.com.cn # http://english.sina.com # ... article = sina_paper.articles[0] article.download() article.parse() print(article.text) # 新浪武汉汽车综合 随着汽车市场的日趋成熟, # 传统的"集全家之力抱得爱车归"的全额购车模式已然过时, # 另一种轻松的新兴 车模式――金融购车正逐步成为时下消费者购 # 买爱车最为时尚的消费理念,他们认为,这种新颖的购车 # 模式既能在短期内 # ... print(article.title) # 两年双免0手续0利率 科鲁兹掀背金融轻松购_武汉车市_武汉汽 # 车网_新浪汽车_新浪网
从上面的例子你可以看到,你可以非常容易地提取中文文章,仅需要在Article的language参数中指定 ‘zh’ :
""" Python 实用宝典 《Newspaper — 一个能下载38种语言新闻文章的 Python 模块》 """ from newspaper import Article url = 'http://www.bbc.co.uk/zhongwen/simp/chinese_news/2012/12/121210_hongkong_politics.shtml' a = Article(url, language='zh') # Chinese a.download() a.parse() print(a.text[:150]) # 香港行政长官梁振英在各方压力下就其大宅的违章建 # 筑(僭建)问题到立法会接受质询,并向香港民众道歉。 # 梁振英在星期二(12月10日)的答问大会开始之际 # 在其演说中道歉,但强调他在违章建筑问题上没有隐瞒的 # 意图和动机。 一些亲北京阵营议员欢迎梁振英道歉, # 且认为应能获得香港民众接受,但这些议员也质问梁振英有 print(a.title) # 港特首梁振英就住宅违建事件道歉
这个工具所支持的所有语言如下:
input code full name ar Arabic be Belarusian bg Bulgarian da Danish de German el Greek en English es Spanish et Estonian fa Persian fi Finnish fr French he Hebrew hi Hindi hr Croatian hu Hungarian id Indonesian it Italian ja Japanese ko Korean lt Lithuanian mk Macedonian nb Norwegian (Bokmål) nl Dutch no Norwegian pl Polish pt Portuguese ro Romanian ru Russian sl Slovenian sr Serbian sv Swedish sw Swahili th Thai tr Turkish uk Ukrainian vi Vietnamese zh Chinese
你可以按需选择自己所需要的语言。
前面我们说过,Newspaper 是一个可以并发下载文章的框架,它是这么玩的:
""" Python 实用宝典 《Newspaper — 一个能下载38种语言新闻文章的 Python 模块》 """ import newspaper from newspaper import news_pool slate_paper = newspaper.build('http://slate.com') tc_paper = newspaper.build('http://techcrunch.com') espn_paper = newspaper.build('http://espn.com') papers = [slate_paper, tc_paper, espn_paper] news_pool.set(papers, threads_per_source=2) # (3*2) = 总计 6 线程 news_pool.join() # 到这一步,你可以假定三个新闻源的文章都下载完成了 print(slate_paper.articles[10].html) # u'<html> ...'
可以看到,作者通过 build 三个新闻源,拿到一个总的新闻源池进行并发请求。
其中,.set 函数起到了调度作用,它能通过指定 threads_per_source 的值设定每个新闻源的线程。最后再 join 起来开始并发请求新闻源并开始下载新闻。
此外,Newspaper 还有一些参数可供你配置,比如:
keep_article_html
,默认为False,“如果要保留正文文本的html,则设置为True”
http_success_only
,默认为True,“设置为False也可以捕获非2XX响应”
MIN_WORD_COUNT
,默认为300,“文章中的单词数量”
MIN_SENT_COUNT
,默认为7,“句子数”
MAX_TITLE
,默认值为200,“文章标题中的字符数”
MAX_TEXT
,默认值为100000,“文章文字中的字符数”
MAX_KEYWORDS
,默认值为35,“文章中的关键词数”
MAX_AUTHORS
,默认值为10,“文章中的作者姓名数量”
MAX_SUMMARY
,默认值为5000,“摘要的字符数”
MAX_SUMMARY_SENT
,默认为5,“摘要中的句子数”
memoize_articles
,默认为True,“运行后缓存并保存运行后的文章”
fetch_images
,默认为True,“如果不需要获取图片,请将其设置为false”
request_timeout
,默认为7,请求7秒后未响应完成则超时
number_threads
,默认值为10,多线程数量
如果你需要使用以上参数,可以设一个Config对象,传入指定的 Article 对象或build 方法中,如:
import newspaper from newspaper import Config, Article, Source config = Config() config.memoize_articles = False cbs_paper = newspaper.build('http://cbs.com', config)
非常简单易懂,而且设置起来的维护成本不算很高。
在做一些舆情分析或者NLP算法训练/测试的时候,这个模块简直就是你的福音。你可以很方便地从网站上提取任意语言的文本数据,拿来测试或者训练都可以。
对于那些想要搞舆情分析,寻找市场热点的同学而言,这个模块也是非常方便,你能搭配邮件发布工具,并使用Newspaper的关键词提取功能,迅速制作一个关键词热点实时告警的工具。
总而言之,这是一个非常值得了解并学习使用的第三方模块,强烈推荐。
我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。
有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。
原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!
Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典
PySnooper 是一个非常方便的调试器。如果您正在试图弄清楚为什么您的Python代码没有按照您的预期去做,您会希望使用具有断点和监视功能的成熟Debug工具,但是许多Debug工具配置起来非常麻烦。
现在,有了PySnooper,您并不需要配置那么复杂的Debug工具,就能够完成对整个代码的分析。它能告诉您哪些代码正在运行,以及局部变量的值是什么。
其实,PySnooper就是替代了一行一行print的重复性工作,给你的代码一个pysnooper装饰器,它能自动识别到语句和变量并将其值print出来:
import pysnooper @pysnooper.snoop() def number_to_bits(number): if number: bits = [] while number: number, remainder = divmod(number, 2) bits.insert(0, remainder) return bits else: return [0] number_to_bits(6)
效果如下:
Source path:... 1.py Starting var:.. number = 6 23:03:35.990701 call 4 def number_to_bits(number): 23:03:35.991699 line 5 if number: 23:03:35.991699 line 6 bits = [] New var:....... bits = [] 23:03:35.991699 line 7 while number: 23:03:35.991699 line 8 number, remainder = divmod(number, 2) Modified var:.. number = 3 New var:....... remainder = 0 23:03:35.991699 line 9 bits.insert(0, remainder) Modified var:.. bits = [0] 23:03:36.004664 line 7 while number: 23:03:36.005661 line 8 number, remainder = divmod(number, 2) Modified var:.. number = 1 Modified var:.. remainder = 1 23:03:36.005661 line 9 bits.insert(0, remainder) Modified var:.. bits = [1, 0] 23:03:36.007657 line 7 while number: 23:03:36.007657 line 8 number, remainder = divmod(number, 2) Modified var:.. number = 0 23:03:36.008655 line 9 bits.insert(0, remainder) Modified var:.. bits = [1, 1, 0] 23:03:36.008655 line 7 while number: 23:03:36.009651 line 10 return bits 23:03:36.009651 return 10 return bits Return value:.. [1, 1, 0] Elapsed time: 00:00:00.020945
可以看到,它将每一行变量的值都输出到屏幕上,方便你调试代码。
仅仅需要写一行代码—使用装饰器就可以实现这个方便的调试功能,比起一行行写print,这可方便多了。
0.安装
使用这个模块,你只需要使用Pip安装PySnooper:
pip install pysnooper
接下来讲讲这个模块其他好用的功能:
1.支持日志文件
如果你觉得print到屏幕上不方便,还可以将其输出到log文件中,你只需要将装饰器那一行改为:
@pysnooper.snoop('/my/log/file.log')
2.读取局外变量或其他表达式
如果你想读取在装饰器作用范围以外的变量或者表达式的值,还可以使用watch参数:
@pysnooper.snoop(watch=('foo.bar', 'self.x["whatever"]'))
3.如果你不想用装饰器,也可以用上下文的形式调试
没错,装饰器有限定的使用条件,使用起来比较局限,因此pysnooper还支持使用 with 的上下文形式:
import pysnooper import random def foo(): lst = [] for i in range(10): lst.append(random.randrange(1, 1000)) with pysnooper.snoop(): lower = min(lst) upper = max(lst) mid = (lower + upper) / 2 print(lower, mid, upper) foo()
效果如下,只有上下文里的代码才会被调试出来:
New var:....... i = 9 New var:....... lst = [681, 267, 74, 832, 284, 678, ...] 09:37:35.881721 line 10 lower = min(lst) New var:....... lower = 74 09:37:35.882137 line 11 upper = max(lst) New var:....... upper = 832 09:37:35.882304 line 12 mid = (lower + upper) / 2 74 453.0 832 New var:....... mid = 453.0 09:37:35.882486 line 13 print(lower, mid, upper) Elapsed time: 00:00:00.000344
当我们只需要调试部分代码的时候,这个上下文形式的调试方法非常方便。
此外,PySnooper还有许多更强大的用法,大家可以看他们的高级使用文档:
https://github.com/cool-RR/PySnooper/blob/master/ADVANCED_USAGE.md
我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。
有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。
原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!
Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典