V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  lxdlam  ›  全部回复第 2 页 / 共 7 页
回复总数  121
1  2  3  4  5  6  7  
不同意 #14 的说法,实际上 #14 所需要的只是 Composable 的 interface ,而并不是所谓的 duck typing 。

引用原文:

> - Don't implement Interfaces preemptively.

在这里提到的 case 实际上是因为,Java 由于无法对任意 External Type 实现 Internal interface ,所以如果原始的行为 Contract 没有被声明为 Interface ,我们既不能实现我们自己的替代品(有 interface 的情况下,实现一个 Adapter 不就可以了?),也无法使用我们的 interface 去将其替代;而这个限制在 Rust 中已经被放宽到不允许使用 External struct 去实现 External trait ( https://doc.rust-lang.org/book/ch10-02-traits.html#implementing-a-trait-on-a-type )。

而 Go 这种 Duck typing ,实际上比起 Java 的显式声明,是另一种推卸责任。举个例子,假定我存在两个 interface:

```go
type Visitor interface {
Saw() bool // If we have seen this node
}

type Sawyer interface {
Saw() bool // Can sawyer saw?
}
```

当我实现 `func (???) Saw() bool` 的时候,我究竟在实现谁?这大大加剧了误用几率,反而在工程上是一个 bad practice 。(这种 case 一定存在,参考 Hyrum's Law - https://www.hyrumslaw.com/ ,一个行为只要被足够多的人观察,无论是否跟你的设计和想法保持一致,一定会有人在依赖这个行为)。

如何回避上述行为?一种方案是实现一个空的 method ,限定其在特定 namespace 下面,比如:

```go
type Visitor interface {
Saw() bool

IsVisitorImpl()
}
// ...
```

但这跟 Java 的 `implements XXX` 相比,无非是把这个 Tag 下推到 `interface` 内部了,本质是完全一样的。

而如果实现细粒度的 `interface`,#40 提出了一个很好的例子,我们甚至可以:

```java
public interface Putter {
String put(Item item);
}

public interface Getter {
Item get(String key);
}

public class Storage {
private Putter putter;
private Getter getter;
}
```

虽然有点累赘,一样实现了类似的细粒度接口组合,并未有任何功能上的差异。
看 op 应该是 Oracle

猜测 union 查询命中了联合索引,所以不需要对 `datetime` 排序,只需要决定起始位置就可以直接 fetch 数据;而 IN list 先对命中三个条件的数据进行 merge ,然后 sort 后再筛选,无论是合并、排序操作还是需要扫描的行数( 8989K > 2123K+180K )都远比前一个查询计划大。

一种可行的优化可以尝试 over partition 拆成三个子表排序再重新 where 一下,不确定优化效果,需要再 explain 一下看看,参考 https://use-the-index-luke.com/sql/partial-results/window-functions
214 天前
回复了 um1ng 创建的主题 机械键盘 24 年了大家在用什么键盘
家里 Apex Pro TKL Wireless
公司 宁芝 Micro84
@lxdlam 补一句,通过 template + if constexpr + static_assert 可能可以将这个 `to_runtime` 自动化生成出来,不过我也好久没写过 C++ 了,如果不行当我没说。
本质的核心问题是 C++ 没有真正的 exhaustive 的 enum ,导致编译器无法限定 `E` 的值在一个可优化的 immedate value 范围内,无法将其在 comptime 求出来,所以将其放到参数里无法做编译期生成。

为什么 `to_runtime` 又能 work 了?因为在当前场景下,编译器推导出来对于 `consteval` 函数 `flattern`,可行的值是有限的,所以能够正常编译。把最后一个分支改为 `f(_e)`,编译器会报错 `f` 为一个 `consteval function`,但是参数是 comptime unknown 的。

对于有 exhaustive enum 的语言( rust 、zig 等),要实现这种需求应该是 trivial 的。
237 天前
回复了 lucasj 创建的主题 程序员 推荐几个你一直在用的开源项目工具
DuckDB ,非常好用的 in memory OLAP 数据库,跟 sqlite 一样,而且可以统一连接 csv 、parquet 、mysql 、postgres 数据源,python 包可以兼容 pandas/polars/arrow ,纯粹开箱即用,非常方便
253 天前
回复了 Mianmiss 创建的主题 程序员 是否应该把程序日志写入到 Mysql 数据库中
@lxdlam 没写完发出去了。补充一下特性第一条:日志绝大部分情况下不会有并发读写,且是 Append only ,我们更多考虑可以读写分离的架构,使用一些缓存、分片的技术难度会大幅下降,且能在合理资源量内得到一个不错的效果。
253 天前
回复了 Mianmiss 创建的主题 程序员 是否应该把程序日志写入到 Mysql 数据库中
日志需要持久化,尤其是有跨天 case 的可能性。使用 MySQL 或者其他 OLTP DB 是一种方案,但是不是最好的方案。

将日志当作事件流,思考日志的使用场景:
- 问题定位:最常见的 case ,通过请求、用户、设备等等维度抽取一个特定的事件流分析,哪一步出现了问题,这种 case 通常需要对一些特定的 field 当作 key ,抽取查询相关联的事件。
- 数据分析:通过对特定事件进行聚合,计算出来一些业务或者技术指标,诸如平均响应时间、订单完成延迟等。这种场景一定程度上会被 metric 所替代,但是在错误日志聚合上仍然有价值。

同时,日志有一些自己的特性:
- Append only:日志绝大部分情况下不会有并发读写,且是 Append only ,我们更多考虑
- 丢失冗余:根据日志量的关系,其实允许一定程度的日志丢失和冗余,也就是没有严格事务要求。
- 量级和查询需求:很多日志都是大海捞针,允许一定的查询延迟和一定延长的运行时间

从上面的角度,其实使用一个 OLAP 系统或者更加专门的系统更好。OLAP 常规的选型可以选择诸如 ELK 、ClickHouse 这样的系统,搭配 Kafka 之类将日志落进去;而比较完善的日志系统现在比较流行的就是 Loki + Promtail/Grafana Agent ;如果量小,使用 fluentd 采集并发送到 S3 使用一些脚本去分析也是 OK 的。
265 天前
回复了 Yadomin 创建的主题 程序员 Redis 更换了开源协议
Redis 这次换其实是比较强盗逻辑的。

背景是 Redis 之前开发了很多附加组件,如时序数据扩展 Timeseries ,JSON 扩展 RedisJSON ,然后这一系列扩展统称为 Redis Stack ,所有 RedisStack 就是按 SSPL 分发的,同时保持原有的代码为 3-Clause BSD 。

> In fact, more than 50% of redis.io downloads – from Redis 6 and beyond – come from Redis Stack. We now believe that extending this licensing to Redis itself will enable us to continue to evolve the most holistic set of data models, processing engines, and developer capabilities for our users.

根据原文,他们觉得既然有超过 50% 的用户下载 Redis 都是从 Redis Stack 过来的,那为什么不把这俩合一呢?是否合理、怎么合并暂且不提,单纯因为这个原因把 core Redis 的 License 换成 RSAL+SSPL ,就纯粹是在绑架那一批完全用不到 Redis Stack 的用户了。而显然,这虽然看起来是 Redis 跟托管云的斗争,但是实际上这部分成本总会以各种形式转嫁到 end user 上。
我的桌面是 Windows ,用一对 PreSouns Eris 3.5 ,但是接了个外置声卡走的平衡输出。
266 天前
回复了 xinbaoCode 创建的主题 程序员 如何简单 100%安全存放自己的密码?
介绍一下另一种形式,并非由一个 committee 来决定的形式:[终身仁慈独裁者]( https://en.wikipedia.org/wiki/Benevolent_dictator_for_life),从 Python 之父开始的一个特定名称,被他毙掉的 PEP 不计其数。一个非常著名的提案是 PEP-572 ,就是 Python 3.8 引入的赋值(海象)操作符 `:=`,社区对这个提案一直比较两极化,但是 Guido 下场了,最终通过这个提案。

Disclaimer:我并没有说这个提案通过跟 Guido 下场有直接关系,现象如此,而且我也经常使用海象操作符。
将一个接口 wrap 进一个 db transaction 本身只保证了 db 操作的“原子性”,这还建立在本身 db 的 txn 处于正确的 isolation level 下。

所谓的接口原子性要考虑的问题远比这个复杂,如果使用了其他的后端服务,诸如 Redis 写入、第三方系统 API 调用,当非原子操作产生时,这些服务是否均支持回滚?是否保证回滚时的一致性?这样就需要从业务逻辑去考虑,然后落实到技术层面去解决,比如 Redis 是否需要 transaction 去配合?对于不支持原子的操作技术上如何取消?无法取消的事务如何在业务跟技术层面去做补偿?
我可能是极少数买了 Mathematica for Home&Hobby 的,今年他把 Cloud access 整合之后估计就继续按年续 Service plan 了
310 天前
回复了 stimw 创建的主题 Python pdm 还是 dev container?
目前主用 rye ,只能说非常舒服
@lxdlam 当然,进阶还有更多话题,比如备份经常还有可能备份错,所以多天 snapshot 之类做回滚也是常见需求;根据 321 原则,是否在合理价格内支持两地、多地同步 etc ,这些大部分也都会算在成本点里面
感觉很多东西楼主没考虑到:

- 流量费用如何计算? Ingress 跟 Egress 各自怎么计算?
- SLA 如何保证?数据取回是否会有延迟?全球上传和下载平均速度如何?
- 安全和合规如何保证?不是所有人、所有存储方案都适合用 borg ,如果直接使用 S3 跟 WebDAV etc ,平台怎么保证安全性?如果有监管部门审计需求会如何响应?

在加密备份领域业界最好的方案应该是 Tarsnap ,当然也不便宜;跟你这个方案类似的是 rsync.net ,他们提供的安全性和方式支持非常完善,供参考。
并没有找工作,只是很好奇一件事:你们对 Elixir 的态度如何?
1  2  3  4  5  6  7  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1215 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 33ms · UTC 23:54 · PVG 07:54 · LAX 15:54 · JFK 18:54
Developed with CodeLauncher
♥ Do have faith in what you're doing.