重构不会改变软件可观察的行为 —— 重构之后软件功能一如以往。 为什么要重构 重构有风险,它必须修改运行中的程序,这可能引入一些不易察觉的错误。那么,为什么我们还要重构呢?...异曲同工的类 两个函数做同一件事,却有着相同的签名 不完美的类库 类库往往不可能满足我们所有的工作 纯稚的数据类 它只拥有一些数据字段。...以函数取代参数 让参数接受者去除该项参数,并直接调用前一个函数 当一个函数的返回值作为另一个函数的参数,且另一函数能调用该函数时 引入参数对象 以一个对象取代这些参数 某些参数总是很自然地同时出现时...,用以表示某种错误情况 以测试取代异常 修改调用者,使它在调用函数之前先做检查 面对调用者可以预先检查的条件,你抛出了异常时 处理概括关系 名称 解释 动机 字段上移 将该字段移至超类 子类拥有相同的字段时...超类中的某个函数只与部分子类有关 字段下移 将字段移到需要它的那些子类中去 超类中的某个字段只被部分子类用到 提炼子类 新建一个子类,将上面所说的那一部分特性移到子类中去 类中的某些特性只被某些实例用到
你应该只在必要关头才添加参数,预先添加的参数很可能并不是你所需要的。对于这条规则,有个例外:如果修改接口会对整个程序造成非常痛苦的结果,那么可以考虑保留前人预先加入的参数。...10.Remove setting Method 移除设置函数 类中的某个字段应该在对象创建时被设值,然后就不再改变。去掉该字段的所有设值函数。...动机:如果你为某个字段提供了设值函数,这就暗示这个字段值可以被改变。如果你不希望在对象创建之后此字段还有机会被改变,那就不要为它提供设值函数。...工厂函数也是Change Value to Reference (将值对象改为引用对象)的基础。你也可以令你的工厂函数根据参数的个数和类型,选择不同的构建行为。...15.Replace Exception with Test 以测试取代异常 面对一个调用者可以预先检查的条件,你抛出一个异常。修改调用者,使它在调用函数之前先做检查。
, //不保存,只请求一次。...其他也有效 为什么服务器信任的凭证不需要保存到存储中,原因是服务器信任的凭证总是从服务器下发给客户端的 为什么要有保存策略呢?...NSURLProtectionSpace由服务器响应的信息来构建,而sender则内部构建,然后挑战对象会根据保护空间从凭证存储中获取对应的凭证对象...的函数,如果没有实现则根据凭证对象来调用sender的接受挑战或者失败函数,而如果是我们实现了willSendRequestForAuthenticationChallenge就需要我们自己来处理如何接收挑战了...因此有的时候我们可以在系统中预先植入一些特定服务器的保护空间和凭证,这样我们就不需要去处理willSendRequestForAuthenticationChallenge函数了,这种机制特别有效的用于处理
宽表在BI业务中比比皆是,每次建设BI系统时首先要做的就是准备宽表。有时系统中的宽表可能会有上千个字段,经常因为“过宽”超过了数据库表字段数量限制还要再拆分。 为什么大家乐此不疲地造宽表呢?...灵活性差 宽表本质上是一种按需建模的手段,根据业务需求来构建宽表(虽然理论上可以把所有表的组合都形成宽表,但这只存在于理论上,如果要实际操作会发现需要的存储空间大到完全无法接受的程度),这就出现了一个矛盾...一个事实表会对应多个维表,维表又有维表,而且表之间还可能存在自关联/循环关联的情况,这种结构在数据库系统中很常见,基于这些结构的表构建宽表,尤其要表达多个层级的时候,宽表字段数量会急剧增加,经常可能达到成百上千个...这就是宽表带来的可用性差的问题。 总体来看,宽表的坏处在很多场景中经常要大于好处,那为什么宽表还大量横行呢? 因为没办法。一直没有比宽表更好的方案来解决前面提到的查询性能和业务难度的问题。...在BI业务中绝大部分的JOIN都是等值JOIN,也就是关联条件为等式的 JOIN。SPL把等值关联分为外键关联和主键关联。
我们为什么选择 GraphQL 我们想要构建的 API 能够服务于多种客户端,涵盖 Web 和移动应用。它需要具备高效、强大和灵活的特点。...鉴于以下的原因,GraphQL 是最合适的方案: GraphQL 是数据库无关的技术,能够从任何地方为我们预先定义的业务领域提供数据。...简单来讲,解析器就是由开发人员提供的一个函数,用来解析模式中定义的每个字段并从配置的资源(如数据库、其他 API 或缓存等)中返回值。...在本例中,我们的 Query 类型提供了一个名为 getClassificationInsightsByUser 的字段,它接受 emailAddresses 参数。...该字段的解析器函数很可能会访问一个数据库,并构造和返回 ClassificationInsightByUser 对象的一个列表。
对于可视化的需求 在选择可视化平台之前,便要分析清楚团队的需求。多问自己几个业务相关的问题,比如为什么要使用可视化平台,有哪些人使用,使用频率如何,有哪些痛点要解决,再考虑技术上的方案。...接入的数据源最好支持 JDBC 协议或者是 DB API 协议。 其实满足这些需求的可视化平台很多,当时为什么还是选择了 superset 呢?...superset 在这里定义了字段和指标(Metric)的概念。指标是对字段的某种统计结果,比如字段上值的求和、平均值、最大值、最小值等。...定义好表的字段和指标后,数据分析人员就可以通过选择指标(Metric),分组条件(Group)和过滤条件(Filter)来新建和处理图表了。...最后 使用 superset 构建图表需要有一定的 SQL 使用经验和预先了解数据库表结构,对于非技术人员(例如产品、运营)基本上只能使用预先建好的看板(Dashboard),易用性不是很好;权限体系过于细分
其中就Python而言,自己写过简单的博客(注册,登录,发帖,删帖,评论),写过几个爬虫。 ❈ 新手向,基于Redis构建的分布式爬虫。...结构简介 cooperator 协作模块,用于为Master&Worker模块提供代理IP支持 master 提取满足条件的文章url,并交给Worker进一步处理 Worker 解析文章内容,将符合要求的存入数据库...MySQL中应有名为kybsrc的数据库,且该数据库包含一个名为posts的表,拥有num(INT AUTO_INCREMENT)和post(TEXT)两个字段。 如何启动 0....启动 master/start.py 默认只执行一次 3. 启动 worker/start.py 默认循环监听是否有新的URL待解析 核心点说明 1....由于在验证代理IP和使用封装的get_url()函数的时候网络IO较多,所以使用多线程(效果还是很明显的)。
bindActive:是一个函数,用于将请求参数中的"active"绑定到GetAlertsParams结构体的Active字段,用于过滤只返回活动的警报。...bindInhibited:是一个函数,用于将请求参数中的"inhibited"绑定到GetAlertsParams结构体的Inhibited字段,用于过滤只返回被禁止的警报。...bindReceiver:是一个函数,用于将请求参数中的"receiver"绑定到GetAlertsParams结构体的Receiver字段,用于过滤只返回指定接收者的警报。...bindSilenced:是一个函数,用于将请求参数中的"silenced"绑定到GetAlertsParams结构体的Silenced字段,用于过滤只返回被静默的警报。...bindUnprocessed:是一个函数,用于将请求参数中的"unprocessed"绑定到GetAlertsParams结构体的Unprocessed字段,用于过滤只返回未处理的警报。
我们基于Iceberg构建了我们的湖仓一体架构,在具体介绍B站的湖仓一体架构之前,我觉得有必要先讨论清楚两个问题,为什么Iceberg可以构建湖仓一体架构,以及我们为什么选择Iceberg?...1.为什么基于Iceberg可以构建湖仓一体架构?...DataSkiping效果,比如我们对于某个Iceberg表的数据文件按照字段a进行全局排序后,如果后续查询带有a的过滤条件,查询引擎会通过PredictePushDown把过滤条件下推到文件访问层,我们就可以根据...布隆过滤器实际上是一个很长的二进制向量和多个Hash函数,数据通过多个函数映射到二进制向量的比特位上,布隆过滤器的空间效率和查询时间都非常高效,非常适合用于检索一个元素是否存在于一个集合中。...布隆过滤器的空间效率和查询时间都非常高效,但是在使用上也有局限之处,主要是它能够支持的过滤条件是有限的,只适用于:=、IN、NotNull等等值表达式,对于常见的Range过滤,比如>、>=、的
8、Replace Parameter with Methods 以函数取代参数。 对象调用某个函数,并将所得结果作为参数,传递给另一个函数。而接受该参数的函数本身也能够调用前一个函数。...12、Replace Constructor with Factory Method 以工厂函数取代构造函数。 你希望在创建对象时,不仅仅是简单的构建动作。...面对一个调用者可以预先检查的条件,你抛出了一个异常。...超类中的某个函数只与部分(而非全部)子类有关。将这个函数移到相关的那些子类去。恰好与函数上移相反。 5、Push DOwn Field 字段下移。 超类中的某个字段只被部分(而非全部)子类用到。...恰好与字段上移相反。 6、Extract Subclass 提炼子类。 类中某些特性只被某些(而非全部)实例用到。可以新建一个子类,将上面所说的那一部分特性移到子类中。
或者创建在表 and 视图 上 为什么使用视图(优点) 控制数据访问权限,对相关保密的内容不给相关的人员查询到。...VIEW 视图名称 AS 查询语句 视图更新失败的原因 视图由两个以上的基本表导出,不能更新 视图中的字段来自于函数、表达式、常量等 或者说字段本身不存在的情况,就会更新失败 若视图中含有GROUP...理解 含义 : 存储过程 :就是一组经过预先编译的SQL语句的封装。...执行过程: 存储过程就是将一组SQL语句预先存储在服务器上,需要执行的时候,客户端只需要向服务器端发出调用存储过程的命令。..., 用户完整性就是对表中的字段的限制条件。
一、背景 最近一朋友做社区重构,社区主要功能有发帖、回帖、查看帖子详情,详情页按不同条件展示回帖(除了预先定义的顺序外,可能每个用户看到的顺序都不一样,组合超过100个),大概的效果如下:...字段名 类型 字段说明 id int 主键 tid int 帖子id content text 回复内容 position int 楼层 上述表格是经过简化版的内容。...那为什么只保存在MongoDB里呢,因为MongoDB不支持多表事务,社区的场景插入回复,还有其它逻辑需要处理,所以需要借助Mysql的InnoDB的事务机制保证数据的一致性。...为什么不按分页将每个帖子按页缓存回复呢,因为前面说了整个详情页展示条件非常复杂,可以倒序排,也可升序排,还可以只看作者,有的回复还有权限,如果全部缓存帖子回复列表,则缓存的数据量非常的大。...如果当缓存用,怎么解决帖子详情页多种组合条件的导致缓存数据太大的问题?其实对于社区这样的场景,主要占内存的是回复的内容,只要解决帖子回复内容只缓存一份就可以了。
服务端发送数据时可以配置 Content-Encoding:gzip,用户说明数据的压缩方式 客户端接受到数据后去检查对应字段的信息,就可以根据相应的格式去解码。...: compress Content-Encoding: deflate 客户端在接受到返回的数据后去检查对应字段的信息,然后根据对应的格式去做相应的解码。...客户端在请求时,可以用 Accept-Encoding 字段说明自己接受哪些压缩方法。 Accept-Encoding: gzip, deflate ? 2....该模块可以读取预先压缩的gz文件,这样可以减少每次请求进行gzip压缩的CPU资源消耗。...我们可以利用nginx的反向代理功能实现只保留gz文件。
axios-retry 主要接受两个参数,第一个是 axios 实例,第二个是 axios-retry 的配置 defaultOptions: defaultOptions: { retries...: Function; // 重试的条件,可传入自定义判断函数 retryDelay?: Function; // 重试请求的间隔时间的函数 } 功能配置看起来挺完善的,难怪那么受欢迎。...// 思考:为什么不放到 getCurrentState() 函数内一起设置?...函数,也就是只在 axios 响应阶段发生错误(抛出异常)的时候,才会执行当前拦截器。...另外,axios-retry 中通过 Babel 直接打包,以及其借助 NPM scripts 的生命周期,将测试、更新版本,打包构建、发布、Git push串联起来,也是值得借鉴之处。
当发现扫描的数据集数远大于返回的记录集数时,就需要考虑建立索引来加速查询了,接下来介绍几条常见的优化策略: 在查询条件和排序字段上建立索引 限定返回的结果集skip(),limit(),在这点上mongo...真心很赞,因为在互联网场景下的查询都是数据库分页的 只 查询使用到字段,减少内存消耗,在find()中第一个参数为查询条件,第二参数为所选字段,与SQL中尽量不要使用select * 类似。...需要注意的是该集合只支持insert和update操作,不支持一般的delete,只支持类似于SQL中 truncate的drop操作。...函数名 实例 备注 前提条件 Db.students.insert({classid:1, age:14, name:'Tom'})Db.students.insert({classid:2, age:...=v});return x;} Reduce函数接受的参数类似Group效果,将Map返回的键值序列组合成{key, [value1, value2, value3..]}传递给reduce.
二是对不同存储的查询条件优化,在MySQL中使用where条件查询之所以会很快,是因为MySQL已经帮你建立的索引。...谓语下推是在实际数据读取和SQL实际执行之前预先执行条件语句进行预处理和过滤。 接下来所讲的就是下推优化的具体实现。...第二步是自顶向下查询可优化的操作符并进行优化,数据存储的时候已经预先定义好了可优化的操作符。在遇到不可优化的操作符时,会出现两种情况。...最后一步是将可优化的结点树转为存储可支持的查询条件(ES Query、 HBase Filter等)。 ? (Hive的源码对象) 在有了构建能力之后,还需要支持ES特有的查询。...相关推荐 推荐文章 当Elasticsearch遇见智能客服机器人 Elasticsearch开发实战篇——基于ES的SQL报警引擎 你只知大数据的便利,却不知漏洞——hadoop安全完整解析
至于为什么说前缀索引占用的空间和查询成本更小,我们来直接上个例子: 假设表中存在一个邮箱 email 字段,我们在这个字段上面分别创建普通索引和前缀索引: 1)普通索引,包含了每行 email 记录的的整个字符串...(email(6)); 你可以看到,由于 email(6) 这个索引结构中每个 email 字段都只取前 6 个字节 zhangs,所以占用的空间比普通索引更小,这就是使用前缀索引的优势。...所以我们需要预先设定一个可以接受的区分度损失比例,比如 5%。...对这个超长字段 a 进行 hash(假设命名为 a_hash) 存入数据库,然后对这个 hash 值建立索引,由于 hash 值同样可能存在冲突,也就是说两个不同的 a 通过 Hash 函数得到的结果可能是相同的...---- 最后放上这道题的背诵版: 面试官:前缀索引了解吗,为什么要建前缀索引 小牛肉:前缀索引就是选取字段的前几个字节建立索引。
准备好开启你的 JavaScript 魔法之旅了吗?那我们开始吧! 什么是柯里化? 简单来说,柯里化就是一种函数式编程技巧。它可以把一个需要多个参数的函数,变成一系列只接受单个参数的函数。...想象一下,你有一个函数 f(a, b, c),它需要三个参数 a、b 和 c。使用柯里化后,这个函数可以变成 f(a)(b)(c),每次只接受一个参数。...在实际应用中,这样的好处是,你可以预先设置某些固定参数,例如奶茶的价格,然后在需要的时候再传入数量和折扣,这样代码更加灵活和可复用。 为什么要用柯里化?...柯里化不仅仅是个炫酷的概念,它在实际编程中有很多实用的优势。下面我们来看看柯里化为什么这么受欢迎: 模块化和可重用性 柯里化可以把一个大函数拆分成多个小函数,每个小函数只处理一个参数。...通过将函数拆分成一个个更小的、只接受一个参数的函数,柯里化让我们对函数的组合和部分应用有了更大的控制权。这不仅提升了代码的可读性,还增强了代码的灵活性。
SQL 为什么要支持聚合查询呢? 这看上去是个幼稚的问题,但我们还是一步步思考一下。...当然任何聚合函数都可以跟随查询条件 WHERE,比如: SELECT COUNT(*) FROM test WHERE is_gray = 1 SUM SUM 求和所有项,因此必须作用于数值字段,而不能用于字符串...SELECT MAX(cost) FROM test 多个聚合字段 虽然都是聚合函数,但 MAX、MIN 严格意义上不算是聚合函数,因为它们只是寻找了满足条件的行。...id,而第二条查询的 id 是无意义的,因为不知道归属在哪一行,所以只返回了第一条数据的 id。...所以为什么 HAVING 可以使用聚合条件呢?因为 HAVING 筛选的是组,所以可以对组聚合后过滤掉不满足条件的组,这样是有意义的。
:聚簇索引的数据存储在向MySQL插入一行数据时,默认情况下,会根据主键字段的数据作为索引键值构建B+Tree索引,这个过程会遵循B+Tree的规则。...sql3没有使用索引,走的是全表扫描。首先条件字段并未使用到普通索引,因为不符合「最左匹配原则」。...怎么理解索引失效不论是WHERE条件也好,查询字段也罢,是否使用索引或者使用哪个索引都是「优化器」来决定的,以下几个是优化器工作时索引失效的例子及说明:当索引列的唯一值与总行数的区分度很小,比如索引列的值就是男和女...当优化器看到WHERE条件中有OR关键字时,会看前后两个字段是否都是索引列,因为OR的含义就是两个只要满足一个即可,所以只要有一个不是索引列就会进行全表扫描。...还有大家都知道的索引列使用函数、表达式会失效,为什么?因为B+Tree中的节点存放的是列的原始数据,你拿一个经过函数或者表达式计算的值来查找当然不认识了。5 还有等等索引失效场景。
领取专属 10元无门槛券
手把手带您无忧上云