精华内容
下载资源
问答
  • 将上述时间复杂度错略的分为两类:多项式量级和非多项式量级. 其中, 非多项式量级只有两个: 和. 我们把时间复杂度为非多项式量级的算法问题叫做NP问题(Non-Deterministic Polynomial, 非确...

    这是在数据结构与算法之美中的课程

    几种常见时间复杂度实例分析

    复杂度量级(按数量级递增)

    • 常量阶O(1)
    • 对数阶O(logn)
    • 线性阶O(n)
    • 线性对数阶O(nlogn)
    • 平方阶O(n^2)、立方阶O(n^3) \cdots k次方阶O(n^k)
    • 指数阶O(2^n)
    • 阶乘阶O(n!)

    将上述时间复杂度错略的分为两类:多项式量级非多项式量级. 其中, 非多项式量级只有两个: O(2^n)O(n!).

    我们把时间复杂度为非多项式量级的算法问题叫做NP问题(Non-Deterministic Polynomial, 非确定多项式).

    多项量级就是说这个时间复杂度是由n作为底数的O(n) O(nlogn) 

    非多项量级就是n不是作为底数O(2^n) 指数阶级

    展开全文
  • 什么要使用 MongoDB? MongoDB 这个来源英文单词“humongous”,homongous 这个单词的意思是“巨大的”、“奇大无比的”,从 MongoDB 单词本身可以看出它的目标是提供海量数据的存储以及管理能力。MongoDB 是一款...

    为什么要使用 MongoDB?

    MongoDB 这个来源英文单词“humongous”,homongous 这个单词的意思是“巨大的”、“奇大无比的”,从 MongoDB 单词本身可以看出它的目标是提供海量数据的存储以及管理能力。MongoDB 是一款面向文档的 NoSQL 数据库,MongoDB 具备较好的扩展性以及高可用性,在数据复制方面,支持 Master-Slaver(主从)和 Replica-Set(副本集)等两种方式。通过这两种方式可以使得我们非常方便的扩展数据。

    MongoDB 较高的性能也是它强有力的卖点之一,存储引擎使用的内存映射文件(MMAP 的方式),将内存管理工作交给操作系统去处理。MMAP 的机制,数据的操作写内存即是写磁盘,在保证数据一致性的前提下,提供了较高的性能。

    除此之外,MongoDB 还具备了丰富的查询支持、较多类型的索引支持以及 Auto-Sharding 的功能。在所有的 NoSQL 产品中,MongoDB 对查询的支持是最类似于传统的 RDBMS,这也使得应用方可以较快的从 RDBMS 转换到 MonogoDB。

    在 58 同城,我们的业务特点是具有较高的访问量,并可以按照业务进行垂直的拆分,在每个业务线内部通过 MongoDB 提供两种扩展机制,当业务存储量和访问量变大,我们可以较易扩展。同时我们的业务类型对事务性要求低,综合业务这几点特性,在 58 同城使用 MongoDB 是较合适的。

    如何使用 MongoDB?

    MongoDB 作为一款 NoSQL 数据库产品,Free Schema 是它的特性之一,在设计我们的数据存储时,不需要我们固定 Schema,提供给业务应用方较高的自由度。那么问题来了,Free Schema 真的 Free 吗?

    第一:Free Schema 意味着重复 Schema。在 MongoDB 数据存储的时候,不但要存储数据本身,Schema(字段 key)本身也要重复的存储(例如:{“name”:”zhuanzhuan”, “infoid”:1,“infocontent”:”这个是转转商品”}),必然会造成存储空间的增大。

    第二:Free Schema 意味着 All Schema,任何一个需要调用 MongoDB 数据存储的地方都需要记录数据存储的 Schema,这样才能较好的解析和处理,必然会造成业务应用方的复杂度。

    那么我们如何应对呢?在字段名 Key 选取方面,我们尽可能减少字段名 Key 的长度,比如:name 字段名使用 n 来代替,infoid 字段名使用 i 来代替,infocontent 字段名使用 c 来代替(例如:{“n”:”zhuanzhuan”, “i”:1, “c”:”这个是转转商品”})。使用较短的字段名会带来较差的可读性,我们通过在使用做字段名映射的方式( #defineZZ_NAME  ("n")),解决了这个问题;同时在数据存储方面我们启用了数据存储的压缩,尽可能减少数据存储的量。

    MongoDB 提供了自动分片(Auto-Sharding)的功能,经过我们的实际测试和线上验证,并没有使用这个功能。我们启用了 MongoDB 的库级 Sharding;在 CollectionSharding 方面,我们使用手动 Sharding 的方式,水平切分数据量较大的文档。

    MongoDB 的存储文档必须要有一个“_id”字段,可以认为是“主键”。这个字段值可以是任何类型,默认一个 ObjectId 对象,这个对象使用了 12 个字节的存储空间,每个字节存储两位 16 进制数字,是一个 24 位的字符串。这个存储空间消耗较大,我们实际使用情况是在应用程序端,使用其他的类型(比如 int)替换掉到,一方面可以减少存储空间,另外一方面可以较少 MongoDB 服务端生成“_id”字段的开销。

    在每一个集合中,每个文档都有唯一的“_id”标示,来确保集中每个文档的唯一性。而在不同集合中,不同集合中的文档“_id”是可以相同的。比如有 2 个集合 Collection_A 和 Collection_B,Collection_A 中有一个文档的“_id”为 1024,在 Collection_B 中的一个文档的“_id”也可以为 1024。

    MongoDB 集群部署

    MongoDB 集群部署我们采用了 Sharding+Replica-Set 的部署方式。整个集群有 Shard Server 节点(存储节点,采用了 Replica-Set 的复制方式)、Config Server 节点(配置节点)、Router Server(路由节点、Arbiter Server(投票节点)组成。每一类节点都有多个冗余构成。满足 58 业务场景的一个典型 MongoDB 集群部署架构如下所示 [图 2]:

    图 2 58 同城典型业务 MongoDB 集群部署架构

    在部署架构中,当数据存储量变大后,我们较易增加 Shard Server 分片。Replica-Set 的复制方式,分片内部可以自由增减数据存储节点。在节点故障发生时候,可以自动切换。同时我们采用了读写分离的方式,为整个集群提供更好的数据读写服务。

    图 3 Auto-Sharding MAY is not that Reliable

    针对业务场景我们在 MongoDB 中如何设计库和表

    MongoDB 本身提供了Auto-Sharding的功能,这个智能的功能作为 MongoDB 的最具卖点的特性之一,真的非常靠谱吗(图 3)?也许理想是丰满的,现实是骨干滴。

    首先是在 Sharding Key 选择上,如果选择了单一的 Sharding Key,会造成分片不均衡,一些分片数据比较多,一些分片数据较少,无法充分利用每个分片集群的能力。为了弥补单一 Sharding Key 的缺点,引入复合 Sharing Key,然而复合 Sharding Key 会造成性能的消耗;

    第二count 值计算不准确的问题,数据 Chunk 在分片之间迁移时,特定数据可能会被计算 2 次,造成 count 值计算偏大的问题;

    第三Balancer 的稳定性 & 智能性问题,Sharing 的迁移发生时间不确定,一旦发生数据迁移会造成整个系统的吞吐量急剧下降。为了应对 Sharding 迁移的不确定性,我们可以强制指定 Sharding 迁移的时间点,具体迁移时间点依据业务访问的低峰期。比如 IM 系统,我们的流量低峰期是在凌晨 1 点到 6 点,那么我们可以在这段时间内开启 Sharding 迁移功能,允许数据的迁移,其他的时间不进行数据的迁移,从而做到对 Sharding 迁移的完全掌控,避免掉未知时间 Sharding 迁移带来的一些风险。

    如何设计库(DataBase)?

    我们的 MongoDB 集群线上环境全部禁用了 Auto-Sharding 功能。如上节所示,仅仅提供了指定时间段的数据迁移功能。线上的数据我们开启了库级的分片,通过 db.runCommand({“enablesharding”: “im”}); 命令指定。并且我们通过 db.runCommand({movePrimary:“im”, to: “sharding1”}); 命令指定特定库到某一固定分片上。通过这样的方式,我们保证了数据的无迁移性,避免了 Auto-Sharding 带来的一系列问题,数据完全可控,从实际使用情况来看,效果也较好。

    既然我们关闭了 Auto-Sharding 的功能,就要求对业务的数据增加情况提前做好预估,详细了解业务半年甚至一年后的数据增长情况,在设计 MongoDB 库时需要做好规划:确定数据规模、确定数据库分片数量等,避免数据库频繁的重构和迁移情况发生。

    那么问题来了,针对 MongoDB,我们如何做好容量规划?

    MongoDB 集群高性能本质是 MMAP 机制,对机器内存的依赖较重,因此我们要求业务热点数据和索引的总量要能全部放入内存中,即:Memory > Index + Hot Data。一旦数据频繁地 Swap,必然会造成 MongoDB 集群性能的下降。当内存成为瓶颈时,我们可以通过 Scale Up 或者 Scale Out 的方式进行扩展。

    第二:我们知道 MongoDB 的数据库是按文件来存储的:例如:db1 下的所有 collection 都放在一组文件内 db1.0,db1.1,db1.2,db1.3……db1.n。数据的回收也是以库为单位进行的,数据的删除将会造成数据的空洞或者碎片,碎片太多,会造成数据库空间占用较大,加载到内存时也会存在碎片的问题,内存使用率不高,会造成数据频繁地在内存和磁盘之间 Swap,影响 MongoDB 集群性能。因此将频繁更新删除的表放在一个独立的数据库下,将会减少碎片,从而提高性能。

    第三:单库单表绝对不是最好的选择。原因有三:表越多,映射文件越多,从 MongoDB 的内存管理方式来看,浪费越多;同理,表越多,回写和读取的时候,无法合并 IO 资源,大量的随机 IO 对传统硬盘是致命的;单表数据量大,索引占用高,更新和读取速度慢。

    第四:Local 库容量设置。我们知道 Local 库主要存放 oplog,oplog 用于数据的同步和复制,oplog 同样要消耗内存的,因此选择一个合适的 oplog 值很重要,如果是高插入高更新,并带有延时从库的副本集需要一个较大的 oplog 值(比如 50G);如果没有延时从库,并且数据更新速度不频繁,则可以适当调小 oplog 值(比如 5G)。总之,oplog 值大小的设置取决于具体业务应用场景,一切脱离业务使用场景来设置 oplog 的值大小都是耍流氓。

    如何设计表(Collection)?

    MongoDB 在数据逻辑结构上和 RDBMS 比较类似,如图 4 所示:MongoDB 三要素:数据库(DataBase)、集合(Collection)、文档(Document)分别对应 RDBMS(比如 MySQL)三要素:数据库(DataBase)、表(Table)、行(Row)。

    图 4 MongoDB 和 RDBMS 数据逻辑结构对比

    MongoDB 作为一支文档型的数据库允许文档的嵌套结构,和 RDBMS 的三范式结构不同,我们以“人”描述为例,说明两者之间设计上的区别。“人”有以下的属性:姓名、性别、年龄和住址;住址是一个复合结构,包括:国家、城市、街道等。针对“人”的结构,传统的 RDBMS 的设计我们需要 2 张表:一张为 People 表 [图 5],另外一张为 Address 表 [图 6]。这两张表通过住址 ID 关联起来(即 Addess ID 是 People 表的外键)。在 MongoDB 表设计中,由于 MongoDB 支持文档嵌套结构,我可以把住址复合结构嵌套起来,从而实现一个 Collection 结构 [图 7],可读性会更强。

    图 5 RDBMSPeople 表设计

    图 6 RDBMS Address 表设计

    图 7 MongoDB 表设计

    MongoDB 作为一支 NoSQL 数据库产品,除了可以支持嵌套结构外,它又是最像 RDBMS 的产品,因此也可以支持“关系”的存储。接下来会详细讲述下对应 RDBMS 中的一对一、一对多、多对多关系在 MongoDB 中我们设计和实现。

    IM 用户信息表,包含用户 uid、用户登录名、用户昵称、用户签名等,是一个典型的一对一关系,在 MongoDB 可以采用类 RDBMS 的设计,我们设计一张 IM 用户信息表 user:{_id:88, loginname:musicml, nickname:musicml,sign:love},其中 _id 为主键,_id 实际为 uid。IM 用户消息表,一个用户可以收到来自他人的多条消息,一个典型的一对多关系。

    我们如何设计?

    一种方案,采用 RDBMS 的“多行”式设计,msg 表结构为:{uid,msgid,msg_content},具体的记录为:123, 1, 你好;123,2,在吗。

    另外一种设计方案,我们可以使用 MongoDB 的嵌套结构:{uid:123, msg:{[{msgid:1,msg_content: 你好},{msgid:2, msg_content: 在吗}]}}。

    采用 MongoDB 嵌套结构,会更加直观,但也存在一定的问题:更新复杂、MongoDB 单文档 16MB 的限制问题。采用 RDBMS 的“多行”设计,它遵循了范式,一方面查询条件更灵活,另外通过“多行式”扩展性也较高。

    在这个一对多的场景下,由于 MongoDB 单条文档大小的限制,我们并没采用 MongoDB 的嵌套结构,而是采用了更加灵活的类 RDBMS 的设计。

    在 User 和 Team 业务场景下,一个 Team 中有多个 User,一个 User 也可能属于多个 Team,这种是典型的多对多关系。

    在 MongoDB 中我们如何设计?一种方案我们可以采用类 RDBMS 的设计。一共三张表:Team 表{teamid,teamname, ……},User 表{userid,username,……},Relation 表{refid, userid, teamid}。其中 Team 表存储 Team 本身的元信息,User 表存储 User 本身的元信息,Relation 表存储 Team 和 User 的所属关系。

    在 MongoDB 中我们可以采用嵌套的设计方案:一种 2 张表:Team 表{teamid,teamname,teammates:{[userid, userid, ……]},存储了 Team 所有的 User 成员和 User 表{useid,usename,teams:{[teamid, teamid,……]}},存储了 User 所有参加的 Team。

    在 MongoDB Collection 上我们并没有开启 Auto-Shariding 的功能,那么当单 Collection 数据量变大后,我们如何 Sharding?对 Collection Sharding 我们采用手动水平 Sharding 的方式,单表我们保持在千万级别文档数量。当 Collection 数据变大,我们进行水平拆分。比如 IM 用户信息表:{uid, loginname, sign, ……},可用采用 uid 取模的方式水平扩展,比如:uid%64,根据 uid 查询可以直接定位特定的 Collection,不用跨表查询。

    通过手动 Sharding 的方式,一方面根据业务的特点,我们可以很好满足业务发展的情况,另外一方面我们可以做到可控、数据的可靠,从而避免了 Auto-Sharding 带来的不稳定因素。对于 Collection 上只有一个查询维度(uid),通过水平切分可以很好满足。

    但是对于 Collection 上有 2 个查询维度,我们如何处理?比如商品表:{uid, infoid, info,……},存储了商品发布者,商品 ID,商品信息等。我们需要即按照 infoid 查询,又能支持按照 uid 查询。为了支持这样的查询需求,就要求 infoid 的设计上要特殊处理:infoid 包含 uid 的信息(infoid 最后 8 个 bit 是 uid 的最后 8 个 bit),那么继续采用 infoid 取模的方式,比如:infoid%64,这样我们既可以按照 infoid 查询,又可以按照 uid 查询,都不需要跨 Collection 查询。

    数据量、并发量增大,遇到问题及其解决方案

    大量删除数据问题及其解决方案

    我们在 IM 离线消息中使用了 MongoDB,IM 离线消息是为了当接收方不在线时,需要把发给接收者的消息存储下来,当接收者登录 IM 后,读取存储的离线消息后,这些离线消息不再需要。已读取离线消息的删除,设计之初我们考虑物理删除带来的性能损耗,选择了逻辑标识删除。IM 离线消息 Collection 包含如下字段:msgid, fromuid, touid, msgcontent, timestamp, flag。其中 touid 为索引,flag 表示离线消息是否已读取,0 未读,1 读取。

    当 IM 离线消息已读条数积累到一定数量后,我们需要进行物理删除,以节省存储空间,减少 Collection 文档条数,提升集群性能。既然我们通过 flag==1 做了已读取消息的标示,第一时间想到了通过 flag 标示位来删除:db.collection.remove({“flag” :1}}; 一条简单的命令就可以搞定。表面上看很容易就搞定了?!实际情况是 IM 离线消息表 5kw 条记录,近 200GB 的数据大小。

    悲剧发生了:晚上 10 点后部署删除直到早上 7 点还没删除完毕;MongoDB 集群和业务监控断续有报警;从库延迟大;QPS/TPS 很低;业务无法响应。事后分析原因:虽然删除命令 db.collection.remove({“flag” : 1}}; 很简单,但是 flag 字段并不是索引字段,删除操作等价于全部扫描后进行,删除速度很慢,需要删除的消息基本都是冷数据,大量的冷数据进入内存中,由于内存容量的限制,会把内存中的热数据 swap 到磁盘上,造成内存中全是冷数据,服务能力急剧下降。

    遇到问题不可怕,我们如何解决呢?首先我们要保证线上提供稳定的服务,采取紧急方案,找到还在执行的 opid,先把此命令杀掉(kill opid),恢复服务。长期方案,我们首先优化了离线删除程序 [图 8],把已读 IM 离线消息的删除操作,每晚定时从库导出要删除的数据,通过脚本按照 objectid 主键(_id)的方式进行删除,并且删除速度通过程序控制,从避免对线上服务影响。其次,我们通过用户的离线消息的读取行为来分析,用户读取离线消息时间分布相对比较均衡,不会出现比较密度读取的情形,也就不会对 MongoDB 的更新带来太大的影响,基于此我们把用户 IM 离线消息的删除由逻辑删除优化成物理删除,从而从根本上解决了历史数据的删除问题。

    图 8 离线删除优化脚本

    大量数据空洞问题及其解决方案

    MongoDB 集群大量删除数据后(比如上节中的 IM 用户离线消息删除)会存在大量的空洞,这些空洞一方面会造成 MongoDB 数据存储空间较大,另外一方面这些空洞数据也会随之加载到内存中,导致内存的有效利用率较低,在机器内存容量有限的前提下,会造成热点数据频繁的 Swap,频繁 Swap 数据,最终使得 MongoDB 集群服务能力下降,无法提供较高的性能。

    通过上文的描述,大家已经了解 MongoDB 数据空间的分配是以 DB 为单位,而不是以 Collection 为单位的,存在大量空洞造成 MongoDB 性能低下的原因,问题的关键是大量碎片无法利用,因此通过碎片整理、空洞合并收缩等方案,我们可以提高 MongoDB 集群的服务能力。

    那么我们如何落地呢?

    方案一:我们可以使用 MongoDB 提供的在线数据收缩的功能,通过 Compact 命令(db.yourCollection.runCommand(“compact”);)进行 Collection 级别的数据收缩,去除 Collectoin 所在文件碎片。此命令是以 Online 的方式提供收缩,收缩的同时会影响到线上的服务,其次从我们实际收缩的效果来看,数据空洞收缩的效果不够显著。因此我们在实际数据碎片收缩时没有采用这种方案,也不推荐大家使用这种空洞数据的收缩方案。

    既然这种数据方案不够好,我们可以采用 Offline 收缩的方案二:此方案收缩的原理是:把已有的空洞数据,remove 掉,重新生成一份无空洞数据。那么具体如何落地?先预热从库;把预热的从库提升为主库;把之前主库的数据全部删除;重新同步;同步完成后,预热此库;把此库提升为主库。

    具体的操作步骤如下:检查服务器各节点是否正常运行 (ps -ef |grep mongod);登入要处理的主节点 /mongodb/bin/mongo--port 88888;做降权处理 rs.stepDown(),并通过命令 rs.status() 来查看是否降权;切换成功之后,停掉该节点;检查是否已经降权,可以通过 web 页面查看 status,我们建议最好登录进去保证有数据进入,或者是 mongostat 查看; kill 掉对应 mongo 的进程: kill 进程号;删除数据,进入对应的分片删除数据文件,比如: rm -fr /mongodb/shard11/*;重新启动该节点,执行重启命令,比如:如:/mongodb/bin/mongod --config /mongodb/shard11.conf;通过日志查看进程;数据同步完成后,在修改后的主节点上执行命令 rs.stepDown() ,做降权处理。

    通过这种 Offline 的收缩方式,我们可以做到收缩率是 100%,数据完全无碎片。当然做离线的数据收缩会带来运维成本的增加,并且在 Replic-Set 集群只有 2 个副本的情况下,还会存在一段时间内的单点风险。通过 Offline 的数据收缩后,收缩前后效果非常明显,如 [图 9, 图 10] 所示:收缩前 85G 存储文件,收缩后 34G 存储文件,节省了 51G 存储空间,大大提升了性能。

    图 9 收缩 MongoDB 数据库前存储数据大小

    图 10 收缩 MongoDB 数据库后存储数据大小

    MongoDB 集群监控

    MongoDB 集群有多种方式可以监控:mongosniff、mongostat、mongotop、db.xxoostatus、web 控制台监控、MMS、第三方监控。我们使用了多种监控相结合的方式,从而做到对 MongoDB 整个集群完全 Hold 住。

    第一是 mongostat[图 11],mongostat 是对 MongoDB 集群负载情况的一个快照,可以查看每秒更新量、加锁时间占操作时间百分比、缺页中断数量、索引 miss 的数量、客户端查询排队长度(读|写)、当前连接数、活跃客户端数量 (读|写) 等。

    图 11 MongoDB mongostat 监控

    mongstat 可以查看的字段较多,我们重点关注 Locked、faults、miss、qr|qw 等,这些值越小越好,最好都为 0;locked 最好不要超过 10%;造成 faults、miss 原因主要是内存不够或者内冷数据频繁 Swap,索引设置不合理;qr|qw 堆积较多,反应了数据库处理慢,这时候我们需要针对性的优化。

    第二是 web 控制台,和 MongoDB 服务一同开启,它的监听端口是 MongoDB 服务监听端口加上 1000,如果 MongoDB 的监听端口 33333,则 Web 控制台端口为 34333。我们可以通过 http://ip:port(http://8.8.8.8:34333)访问监控了什么 [图 12]:当前 MongoDB 所有的连接数、各个数据库和 Collection 的访问统计包括:Reads, Writes, Queries 等、写锁的状态、最新的几百行日志文件。

    图 12  MongoDB Web 控制台监控

    第三是 MMS(MongoDBMonitoring Service),它是 2011 年官方发布的云监控服务,提供可视化图形监控。工作原理如下:在 MMS 服务器上配置需要监控的 MongoDB 信息(ip/port/user/passwd 等);在一台能够访问你 MongoDB 服务的内网机器上运行其提供的 Agent 脚本;Agent 脚本从 MMS 服务器获取到你配置的 MongoDB 信息;Agent 脚本连接到相应的 MongoDB 获取必要的监控数据;Agent 脚本将监控数据上传到 MMS 的服务器;登录 MMS 网站查看整理过后的监控数据图表。具体的安装部署,可以参考:http://mms.10gen.com。

    图 13 MongoDB MMS 监控

    第四是第三方监控,MongoDB 开源爱好者和团队支持者较多,可以在常用监控框架上扩展,比如:zabbix,可以监控 CPU 负荷、内存使用、磁盘使用、网络状况、端口监视、日志监视等;nagios,可以监控监控网络服务(HTTP 等)、监控主机资源(处理器负荷、磁盘利用率等)、插件扩展、报警发送给联系人(EMail、短信、用户定义方式)、手机查看方式;cacti,可以基于 PHP,MySQL,SNMP 及 RRDTool 开发的网络流量监测图形分析工具。

    最后我要感谢公司和团队,在 MongoDB 集群的大规模实战中积累了宝贵的经验,才能让我有机会撰写了此文,由于 MongoDB 社区不断发展,特别是 MongoDB 3.0,对性能、数据压缩、运维成本、锁级别、Sharding 以及支持可插拔的存储引擎等的改进,MongoDB 越来越强大。文中可能会存在一些不妥的地方,欢迎大家交流指正。

    讲师介绍

    孙玄,极客邦培训专家讲师,58 同城系统架构师、技术委员会架构组主任、产品技术学院优秀讲师,58 同城即时通讯、C2C 技术负责人,负责 58 核心系统的架构以及优化工作。分布式系统存储专家,2007 年开始从事大规模高性能分布式存储系统架构设计实现工作。涉及自主研发分布式存储系统、MongoDB、MySQL、Memcached、Redis 等。前百度高级工程师,参与社区搜索部多个基础系统的设计与实现。

    转载于:https://www.cnblogs.com/duanxz/p/3564680.html

    展开全文
  • CPM(Cost Per Mille) 每千人成本:只要向足够量级的用户展示了广告主的内容,广告主就为此付费。按此计费的广告一般是以品牌展示和产品发布为主,如新闻客户端的GD广告,曝光效果通常比较好。 CPT(Cost Per Time)每...

    广告投放流程主要分为展示和转化,CPC/CPM/CPD/CPT/CPA/CPS等代表的是不同的结算模式

    展示端的结算方式有

    CPM(Cost Per Mille) 每千人成本:只要向足够量级的用户展示了广告主的内容,广告主就为此付费。按此计费的广告一般是以品牌展示和产品发布为主,如新闻客户端的GD广告,曝光效果通常比较好。

    CPT(Cost Per Time)每时间段成本:以固定价格买断一段时间内的广告位展示,如开屏广告、富媒体广告或应用市场的下拉关键词等。

    CPC(Cost Per Click) 每点击成本:根据广告被点击的次数收费。关键词竞价一般采用这种模式,在信息流广告系统中比较常见。


    转化端的结算方式通常可以统称为CPA(Cost Per Action) 每行动成本,按投放实际效果计价的广告,这里的行动成本可以是:

    CPD(CostPer Download)每下载成本:按用户完成APP下载计费,在应用商店、积分墙、流量联盟比较常见

    CPI(Cost Per Install)每安装成本:按用户激活APP计费,渠道按这种模式结算比较少,通常只作为广告主内部衡量广告投放效果的指标之一

    CPS(Cost Per Sales)每销售成本:按完成订单的用户数量结算,高质量垂直渠道、返利网站比较喜欢采用这种模式



    作者:晨夕Solo
    链接:https://www.zhihu.com/question/26506736/answer/149801034
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    展开全文
  • 时间复杂度O(1) O(n)表示什么

    千次阅读 2020-06-21 20:48:44
    在刷面试题中的算法题经常出现时间复杂度O(n),空间复杂度O(1)很多时候不知道是什么意思 空间复杂度与时间复杂度是数据结构的复杂度,在现在储存设备越来越便宜的时代,时间复杂度是决定程序运行速度的重要因素 算法...

    时间复杂度O(1) O(n)表示什么

    在刷面试题中的算法题经常出现时间复杂度O(n),空间复杂度O(1)很多时候不知道是什么意思

    空间复杂度与时间复杂度是数据结构的复杂度,在现在储存设备越来越便宜的时代,时间复杂度是决定程序运行速度的重要因素
    算法时间复杂度是衡量计算性能的指标,反映了程序执行时间随着输入规模的增长而增长的量级,很大程度的反映出算法性能的好坏,这个量级用大写的O加()表示

    从好到坏常用算法复杂度排序如下

    O(1):常数级

    最低复杂程度,使用时间或使用空间与输入数据大小没有关系,无论输入数据多大,使用时间或使用空间不变
    哈希算法就是典型的常熟级算法

    O(log n):对数级

    使用时间或空间随着输入数据增大,复杂度增大为log n倍,log n倍是n为2的几次方的上标值
    二分查找就是对数级算法

    O(n):线性级

    输入数据增大几倍,时间或空间增大几倍
    大部分遍历就是线性级算法

    O(nlog n):线性对数级

    使用时间或空间随着输入数据增大,复杂度增大为nlog n倍,nlog n倍是n为2的几次方的上标值乘以n
    二分查找就是对数级算法

    O(n²):平方级

    输入数据增大几倍,时间或空间增大几的平方倍
    冒泡排序就是平方级算法,不过复杂度是从O(n)->O(n²),冒泡排序在数据错位数量很小时适用

    O(n³):立方级

    输入数据增大几倍,时间或空间增大几的立方倍

    O(2ⁿ):指数级

    输入数据增大几倍,时间或空间增大2的几的次方倍

    如有错误请各位大牛指出,感激不尽

    展开全文
  • 在刷面试题中的算法题经常出现时间复杂度O(n),空间复杂度O(1)很多时候不知道是什么意思 空间复杂度与时间复杂度是数据结构的复杂度,在现在储存设备越来越便宜的时代,时间复杂度是决定程序运行速度的重要因素 算法...
  • 在刷LeetCode-1TwoSum的时候,有个人在论坛留言,大致意思如下: 我的算法击败了90%的人,O(nlgn)算法比O(n)算法快。 我觉得这个人是不懂算法的。让我一步一步解释。 # O的含义 通俗的说,O表示忽略系数的...
  • JavaScript设计模式之享元模式

    万次阅读 2019-12-05 22:42:18
    享元(flyweight)模式是一种用于性能优化的模式,“fly”在这里是苍蝇的意思,意为蝇量级。享元模式的核心是运用共享技术来有效支持大量细粒度的对象。 如果系统中因为创建了大量类似的对象而导致内存占用过高,享...
  • 记得,如果有人问你做数据库优化最有效的方式是什么? SQL优化、分布式集群、分库分表!干就完了~ ...要知道,对于大型互联网项目,数据量级可能不是我们能想到的,每日新增数据量过千万是常有的事儿,想靠
  • 文章目录写在前面1、数学中的log什么意思?2、用T(n)表示程序执行次数3、用O(n)表示时间复杂度4、时间复杂度大小比较 写在前面 时间复杂度是用来干什么的? 时间复杂度可以用来衡量算法的执行效率。 1、数学中的log...
  • 而我们研究的一般是大规模数据,因为对于小规模数据,研究算法其实没什么意思,比如排序,当N小于一个值时,便使用插入排序。 以上是针对数据规模一样的情况,可以选取量级大的那个代表整个算法...
  • Agera 入门

    2016-11-16 18:27:30
    Agera(瑞典文的意思是”采取行动”)是一个超轻量级的Android库,帮助Android应用中有生命周期的组件(比如:Activities)或者组件中的对象(比如:Views)预准备数据。 通过加入函数式响应式编程,Agera可以在 什么时机, ...
  • 在编写和使用数据结构和算法的时候,怎么去比较它们之间的优劣,需要一个评判标准,目前主要的分析维度是两方面,时间和空间,什么意思呢,时间复杂度分析就是这个算法在一定的运算量级下的消耗时间,时间越少越优,...
  • android Agera(瑞典文的意思是”采取行动”)是一个超轻量级的Android库,帮助Android应用中有生命周期的组件(比如:Activities)或者组件中的对象(比如:Views)预准备数据。 通过加入函数式响应式编程,Agera可以在...
  • 浅谈微服务

    2019-08-08 10:21:37
    CSDN首页>业界 浅谈微服务 发表于2019-04-27 23:08|来源互联网|作者互联网 摘要:微服务,顾名思义就是...然后再让我们通过下文来理解为什么要细化到“微”这个量级。 一、单机服务到微服务的演变 微...
  • 微服务概念详细介绍

    2019-04-26 09:50:09
    目录 一、单机服务到微服务的演变 二、微服务的定义 三、微服务为我们解决了哪些问题 四、当前微服务面临的挑战 ...一、单机服务到微服务的演变 ...然后再让我们通过下文来理解为什么要细化到“微”这个量级...
  • 怀 着对大数据的憧憬,哥依然决然来到了吴超老师主办的超人学院进行大数据技术的深造。 有人说大数据技术是第四次技术革命,这...大,意思就是数据的量级很大,不上TB都不好意思说是大数据。数据,狭义上理解就是12345
  • 点云凸包

    2019-11-07 11:07:43
    啥是凸包呢,在网上随便找了一个图哈,大概意思就是每个转角的地方都是凸出去的,这个代码师兄也跟我说很简单很简单,行吧,反正我是想了好久才想出来的,可能师兄的简单==和我的简单不是一个量级吧 //叉乘 ...
  • 身在中国内地,你早该意思到,大多国产软件,只要用户规模达到一定量级,都会被要求提供后门监控用户数据甚至扫描硬盘。这道不是真正出于什么调查的目的,他们就希望有这种超越一切特权的权利,他们享受“有这种权利...
  • Web语义化标准解读

    2020-11-25 23:26:16
    <p>css我就不写了mr10什么意思我猜你已经知道了。。 且不说<code><button class="button button-primary"></button>这种写法中button本身就是一种冗余信息(我当没看见也罢),...
  • 数据库总结

    2019-10-28 15:35:00
    数据库是什么? 字面意思:存数据的仓库。 二. 为啥使用数据库?(***) 之前使用的是Excel来进行管理数据。 Excel的缺点: 1.管理不了大量的数据(10w量级的数据) 2.并发操作同一个数据表格。 3.数据支持高级的操作,...

空空如也

空空如也

1 2
收藏数 22
精华内容 8
关键字:

量级什么意思