获得徽章 1
今天刷掘金无意间发现了可以刷题,刷到第二题我就感觉不对劲了。给定的测试用例就是错误的,我也通过问ai。下面我贴一下豆包给我的反馈模板![[捂脸]](//lf-web-assets.juejin.cn/obj/juejin-web/xitu_juejin_web/img/jj_emoji_28.8981538.png)
题目描述:
小R正在计划一次从地点A到地点B的徒步旅行,总路程需要 N 天。为了在旅途中保持充足的能量,小R每天必须消耗1份食物。幸运的是,小R在路途中每天都会经过一个补给站,可以先购买完食物后再消耗今天的1份食物。然而,每个补给站的食物每份的价格可能不同,并且小R在购买完食物后最多只能同时携带 K 份食物。
测试用例:
输入:n = 5, k = 2, data = [1, 2, 3, 3, 2]
预期输出:9
实际输出:8
解释:
在第2天购买食物会导致更低的总花费。具体计算如下:
- 第1天:购买2份食物,花费1。
- 第2天:购买1份食物,花费2。
- 第3天:不需要购买,花费0。
- 第4天:购买1份食物,花费3。
- 第5天:购买1份食物,花费2。
总花费为:1 + 2 + 0 + 3 + 2 = 8
我认为测试用例的预期输出应该是8,而不是9。
搞得我也理解不了题目到底要干嘛了,先搁置吧。也可能是我错误的诱导了豆包,反正现在我对题目是没有了解,希望有大佬指出我的错误
![[捂脸]](http://lf-web-assets.juejin.cn/obj/juejin-web/xitu_juejin_web/img/jj_emoji_28.8981538.png)
题目描述:
小R正在计划一次从地点A到地点B的徒步旅行,总路程需要 N 天。为了在旅途中保持充足的能量,小R每天必须消耗1份食物。幸运的是,小R在路途中每天都会经过一个补给站,可以先购买完食物后再消耗今天的1份食物。然而,每个补给站的食物每份的价格可能不同,并且小R在购买完食物后最多只能同时携带 K 份食物。
测试用例:
输入:n = 5, k = 2, data = [1, 2, 3, 3, 2]
预期输出:9
实际输出:8
解释:
在第2天购买食物会导致更低的总花费。具体计算如下:
- 第1天:购买2份食物,花费1。
- 第2天:购买1份食物,花费2。
- 第3天:不需要购买,花费0。
- 第4天:购买1份食物,花费3。
- 第5天:购买1份食物,花费2。
总花费为:1 + 2 + 0 + 3 + 2 = 8
我认为测试用例的预期输出应该是8,而不是9。
搞得我也理解不了题目到底要干嘛了,先搁置吧。也可能是我错误的诱导了豆包,反正现在我对题目是没有了解,希望有大佬指出我的错误
展开
评论
点赞
#青训营笔记创作活动#
2月27日打卡day46
匿名内部类,也就是没有名字的内部类,正是因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写。
匿名内部类,必须继承一个抽象类或者实现一个接口。
匿名内部类,不能定义任何静态成员和静态方法。
当匿名内部类访问所在方法的参数,或者局部变量时,它们也必须是实际 final 的(这个是实际 final 的表示:被final修饰强制限制不能修改,或者初始化后没有被修改过,编译器就认为这是effectively final,是安全的,编译可以通过,否则编译器会马上报错)。
匿名内部类不能是抽象的,它必须要实现继承的类或者是实现的接口所有抽象方法。
2月27日打卡day46
匿名内部类,也就是没有名字的内部类,正是因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写。
匿名内部类,必须继承一个抽象类或者实现一个接口。
匿名内部类,不能定义任何静态成员和静态方法。
当匿名内部类访问所在方法的参数,或者局部变量时,它们也必须是实际 final 的(这个是实际 final 的表示:被final修饰强制限制不能修改,或者初始化后没有被修改过,编译器就认为这是effectively final,是安全的,编译可以通过,否则编译器会马上报错)。
匿名内部类不能是抽象的,它必须要实现继承的类或者是实现的接口所有抽象方法。
展开
评论
点赞
#青训营笔记创作活动#
2月26日 打卡day45
数据从发送端到接收端,链路很长,任何一个地方都可能发生丢包,几乎可以说丢包不可避免。
平时没事也不用关注丢包,大部分时候TCP的重传机制保证了消息可靠性。
当你发现服务异常的时候,比如接口延时很高,总是失败的时候,可以用ping或者mtr命令看下是不是中间链路发生了丢包。
TCP只保证传输层的消息可靠性,并不保证应用层的消息可靠性。如果我们还想保证应用层的消息可靠性,就需要应用层自己去实现逻辑做保证。
2月26日 打卡day45
数据从发送端到接收端,链路很长,任何一个地方都可能发生丢包,几乎可以说丢包不可避免。
平时没事也不用关注丢包,大部分时候TCP的重传机制保证了消息可靠性。
当你发现服务异常的时候,比如接口延时很高,总是失败的时候,可以用ping或者mtr命令看下是不是中间链路发生了丢包。
TCP只保证传输层的消息可靠性,并不保证应用层的消息可靠性。如果我们还想保证应用层的消息可靠性,就需要应用层自己去实现逻辑做保证。
展开
评论
点赞
#青训营笔记创作活动#
2月24日 打卡day44
我们用几个较为简单的例子和大家一起学习了下三个工厂模式各自的场景和优缺点,实际使用的时候项目一开始需求还没那么明确的时候推荐还是先用简单工厂,等我们业务理解更透彻后如果确实需要再升级到工厂方法也不迟。
抽象工厂也是,如果确定引入产品生态的概念才能更好地进行领域建模,再开始使用抽象工厂也不迟。
如果你觉得今天的文章不错,请多多点赞、在看支持,如果点赞+在看能过百 一周内,狂肝下个设计模式。
2月24日 打卡day44
我们用几个较为简单的例子和大家一起学习了下三个工厂模式各自的场景和优缺点,实际使用的时候项目一开始需求还没那么明确的时候推荐还是先用简单工厂,等我们业务理解更透彻后如果确实需要再升级到工厂方法也不迟。
抽象工厂也是,如果确定引入产品生态的概念才能更好地进行领域建模,再开始使用抽象工厂也不迟。
如果你觉得今天的文章不错,请多多点赞、在看支持,如果点赞+在看能过百 一周内,狂肝下个设计模式。
展开
评论
点赞
#青训营笔记创作活动#
2月23日打卡day43
多线程并发读/写同一个TCP socket是线程安全的,因为TCP socket的读/写操作都上锁了。虽然线程安全,但依然不建议你这么做,因为TCP本身是基于数据流的协议,一份完整的消息数据可能会分开多次去写/读,内核的锁只保证单次读/写socket是线程安全,锁的粒度并不覆盖整个完整消息。因此建议用一个线程去读/写TCP socket。
多线程并发读/写同一个UDP socket也是线程安全的,因为UDP socket的读/写操作也都上锁了。UDP写数据报的行为是"原子"的,不存在发一半包或收一半包的问题,要么整个包成功,要么整个包失败。因此多个线程同时读写,也就不会有TCP的问题。虽然如此,但还是建议用一个线程去读/写UDP socket。
2月23日打卡day43
多线程并发读/写同一个TCP socket是线程安全的,因为TCP socket的读/写操作都上锁了。虽然线程安全,但依然不建议你这么做,因为TCP本身是基于数据流的协议,一份完整的消息数据可能会分开多次去写/读,内核的锁只保证单次读/写socket是线程安全,锁的粒度并不覆盖整个完整消息。因此建议用一个线程去读/写TCP socket。
多线程并发读/写同一个UDP socket也是线程安全的,因为UDP socket的读/写操作也都上锁了。UDP写数据报的行为是"原子"的,不存在发一半包或收一半包的问题,要么整个包成功,要么整个包失败。因此多个线程同时读写,也就不会有TCP的问题。虽然如此,但还是建议用一个线程去读/写UDP socket。
展开
评论
点赞
#青训营笔记创作活动#
2月22日 打卡day42
多线程并发读/写同一个TCP socket是线程安全的,因为TCP socket的读/写操作都上锁了。虽然线程安全,但依然不建议你这么做,因为TCP本身是基于数据流的协议,一份完整的消息数据可能会分开多次去写/读,内核的锁只保证单次读/写socket是线程安全,锁的粒度并不覆盖整个完整消息。因此建议用一个线程去读/写TCP socket。
多线程并发读/写同一个UDP socket也是线程安全的,因为UDP socket的读/写操作也都上锁了。UDP写数据报的行为是"原子"的,不存在发一半包或收一半包的问题,要么整个包成功,要么整个包失败。因此多个线程同时读写,也就不会有TCP的问题。虽然如此,但还是建议用一个线程去读/写UDP socket。
2月22日 打卡day42
多线程并发读/写同一个TCP socket是线程安全的,因为TCP socket的读/写操作都上锁了。虽然线程安全,但依然不建议你这么做,因为TCP本身是基于数据流的协议,一份完整的消息数据可能会分开多次去写/读,内核的锁只保证单次读/写socket是线程安全,锁的粒度并不覆盖整个完整消息。因此建议用一个线程去读/写TCP socket。
多线程并发读/写同一个UDP socket也是线程安全的,因为UDP socket的读/写操作也都上锁了。UDP写数据报的行为是"原子"的,不存在发一半包或收一半包的问题,要么整个包成功,要么整个包失败。因此多个线程同时读写,也就不会有TCP的问题。虽然如此,但还是建议用一个线程去读/写UDP socket。
展开
评论
点赞
#青训营笔记创作活动#
2月22日 打卡day42
limit offset, size 比 limit size 要慢,且offset的值越大,sql的执行速度越慢。
当offset过大,会引发深度分页问题,目前不管是mysql还是es都没有很好的方法去解决这个问题。只能通过限制查询数量或分批获取的方式进行规避。
遇到深度分页的问题,多思考其原始需求,大部分时候是不应该出现深度分页的场景的,必要时多去影响产品经理。
如果数据量很少,比如1k的量级,且长期不太可能有巨大的增长,还是用limit offset, size 的方案吧,整挺好,能用就行。
2月22日 打卡day42
limit offset, size 比 limit size 要慢,且offset的值越大,sql的执行速度越慢。
当offset过大,会引发深度分页问题,目前不管是mysql还是es都没有很好的方法去解决这个问题。只能通过限制查询数量或分批获取的方式进行规避。
遇到深度分页的问题,多思考其原始需求,大部分时候是不应该出现深度分页的场景的,必要时多去影响产品经理。
如果数据量很少,比如1k的量级,且长期不太可能有巨大的增长,还是用limit offset, size 的方案吧,整挺好,能用就行。
展开
评论
点赞
#青训营笔记创作活动#
2月20日 打卡day41
IPV4地址有限,但通过NAT路由器,可以使得整个内网N多台机器,对外只使用一个公网IP,大大节省了IP资源。
内网机子主动连接公网IP,中间的NAT会将内网机子的内网IP转换为公网IP,从而实现内网和外网的数据交互。
普通的NAT技术,只会修改网络包中的发送端和接收端IP地址,当内网设备较多时,将有可能导致冲突。因此一般都会使用NAPT技术,同时修改发送端和接收端的IP地址和端口。
由于NAT的存在,公网IP是无法访问内网服务的,但通过内网穿透技术,就可以让公网IP访问内网服务。一波操作下来,就可以在公司的网络里访问家里的电脑。
2月20日 打卡day41
IPV4地址有限,但通过NAT路由器,可以使得整个内网N多台机器,对外只使用一个公网IP,大大节省了IP资源。
内网机子主动连接公网IP,中间的NAT会将内网机子的内网IP转换为公网IP,从而实现内网和外网的数据交互。
普通的NAT技术,只会修改网络包中的发送端和接收端IP地址,当内网设备较多时,将有可能导致冲突。因此一般都会使用NAPT技术,同时修改发送端和接收端的IP地址和端口。
由于NAT的存在,公网IP是无法访问内网服务的,但通过内网穿透技术,就可以让公网IP访问内网服务。一波操作下来,就可以在公司的网络里访问家里的电脑。
展开
评论
点赞
#青训营笔记创作活动#
2月19日 打卡day40
建表sql里主键边上的AUTO_INCREMENT,可以让主键自增,去掉它是可以的,但这就需要你在insert的时候自己设置主键的值。
建表sql里的 PRIMARY KEY 是用来声明主键的,如果去掉,那也能建表成功,但mysql内部会给你偷偷建一个 ROW_ID的隐藏列作为主键。
由于mysql使用B+树索引,叶子节点是从小到大排序的,如果使用自增id做主键,这样每次数据都加在B+树的最后,比起每次加在B+树中间的方式,加在最后可以有效减少页分裂的问题。
在分库分表的场景下,我们可以通过redis等第三方组件来获得严格自增的主键id。如果不想依赖redis,可以参考雪花算法进行魔改,既能保证数据趋势递增,也能很好的满足分库分表的动态扩容。
并不是所有数据库都建议使用自增id作为主键,比如tidb就推荐使用随机id,这样可以有效避免写热点的问题。而对于一些敏感数据,比如用户id,订单id等,如果使用自增id作为主键的话,外部通过抓包,很容易可以知道新进用户量,成单量这些信息,所以需要谨慎考虑是否继续使用自增主键。
2月19日 打卡day40
建表sql里主键边上的AUTO_INCREMENT,可以让主键自增,去掉它是可以的,但这就需要你在insert的时候自己设置主键的值。
建表sql里的 PRIMARY KEY 是用来声明主键的,如果去掉,那也能建表成功,但mysql内部会给你偷偷建一个 ROW_ID的隐藏列作为主键。
由于mysql使用B+树索引,叶子节点是从小到大排序的,如果使用自增id做主键,这样每次数据都加在B+树的最后,比起每次加在B+树中间的方式,加在最后可以有效减少页分裂的问题。
在分库分表的场景下,我们可以通过redis等第三方组件来获得严格自增的主键id。如果不想依赖redis,可以参考雪花算法进行魔改,既能保证数据趋势递增,也能很好的满足分库分表的动态扩容。
并不是所有数据库都建议使用自增id作为主键,比如tidb就推荐使用随机id,这样可以有效避免写热点的问题。而对于一些敏感数据,比如用户id,订单id等,如果使用自增id作为主键的话,外部通过抓包,很容易可以知道新进用户量,成单量这些信息,所以需要谨慎考虑是否继续使用自增主键。
展开
评论
点赞
#青训营笔记创作活动#
2月18日 打卡day39
纯裸TCP是能收发数据,但它是个无边界的数据流,上层需要定义消息格式用于定义消息边界。于是就有了各种协议,HTTP和各类RPC协议就是在TCP之上定义的应用层协议。
RPC本质上不算是协议,而是一种调用方式,而像gRPC和thrift这样的具体实现,才是协议,它们是实现了RPC调用的协议。目的是希望程序员能像调用本地方法那样去调用远端的服务方法。同时RPC有很多种实现方式,不一定非得基于TCP协议。
从发展历史来说,HTTP主要用于b/s架构,而RPC更多用于c/s架构。但现在其实已经没分那么清了,b/s和c/s在慢慢融合。 很多软件同时支持多端,所以对外一般用HTTP协议,而内部集群的微服务之间则采用RPC协议进行通讯。
RPC其实比HTTP出现的要早,且比目前主流的HTTP1.1性能要更好,所以大部分公司内部都还在使用RPC。
HTTP2.0在HTTP1.1的基础上做了优化,性能可能比很多RPC协议都要好,但由于是这几年才出来的,所以也不太可能取代掉RPC。
2月18日 打卡day39
纯裸TCP是能收发数据,但它是个无边界的数据流,上层需要定义消息格式用于定义消息边界。于是就有了各种协议,HTTP和各类RPC协议就是在TCP之上定义的应用层协议。
RPC本质上不算是协议,而是一种调用方式,而像gRPC和thrift这样的具体实现,才是协议,它们是实现了RPC调用的协议。目的是希望程序员能像调用本地方法那样去调用远端的服务方法。同时RPC有很多种实现方式,不一定非得基于TCP协议。
从发展历史来说,HTTP主要用于b/s架构,而RPC更多用于c/s架构。但现在其实已经没分那么清了,b/s和c/s在慢慢融合。 很多软件同时支持多端,所以对外一般用HTTP协议,而内部集群的微服务之间则采用RPC协议进行通讯。
RPC其实比HTTP出现的要早,且比目前主流的HTTP1.1性能要更好,所以大部分公司内部都还在使用RPC。
HTTP2.0在HTTP1.1的基础上做了优化,性能可能比很多RPC协议都要好,但由于是这几年才出来的,所以也不太可能取代掉RPC。
展开
评论
点赞
#青训营笔记创作活动#
2月17日 打卡day38
事务通过undo日志实现回滚的功能,从而实现事务的原子性(Atomicity)。
多个事务生成的undo日志构成一条版本链。快照读时事务根据read view来决定具体读哪个快照。当前读时事务直接读最新的快照版本。
mysql的innodb引擎通过MVCC提升了读写并发。
2月17日 打卡day38
事务通过undo日志实现回滚的功能,从而实现事务的原子性(Atomicity)。
多个事务生成的undo日志构成一条版本链。快照读时事务根据read view来决定具体读哪个快照。当前读时事务直接读最新的快照版本。
mysql的innodb引擎通过MVCC提升了读写并发。
展开
评论
点赞
#青训营笔记创作活动#
2月16日 打卡day37
加唯一索引可以保证数据并发写入时数据唯一,而且最省事省心。
数据库通过引入一层buffer pool内存来提升读写速度,普通索引可以利用change buffer提高数据插入的性能。
唯一索引会绕过change buffer,确保把磁盘数据读到内存后再判断数据是否存在,不存在才能插入数据,否则报错,以此来保证数据是唯一的。
2月16日 打卡day37
加唯一索引可以保证数据并发写入时数据唯一,而且最省事省心。
数据库通过引入一层buffer pool内存来提升读写速度,普通索引可以利用change buffer提高数据插入的性能。
唯一索引会绕过change buffer,确保把磁盘数据读到内存后再判断数据是否存在,不存在才能插入数据,否则报错,以此来保证数据是唯一的。
展开
评论
点赞
#青训营笔记创作活动#
2月15日 打卡day36
B+树是多叉平衡搜索树,扇出高,只需要3层左右就能存放2kw左右的数据,同样情况下跳表则需要24层左右,假设层高对应磁盘IO,那么B+树的读性能会比跳表要好,因此mysql选了B+树做索引。
redis的读写全在内存里进行操作,不涉及磁盘IO,同时跳表实现简单,相比B+树、AVL树、少了旋转树结构的开销,因此redis使用跳表来实现ZSET,而不是树结构。
存储引擎RocksDB内部使用了跳表,对比使用B+树的innodb,虽然写性能更好,但读性能属实差了些。在读多写少的场景下,B+树依旧YYDS。
2月15日 打卡day36
B+树是多叉平衡搜索树,扇出高,只需要3层左右就能存放2kw左右的数据,同样情况下跳表则需要24层左右,假设层高对应磁盘IO,那么B+树的读性能会比跳表要好,因此mysql选了B+树做索引。
redis的读写全在内存里进行操作,不涉及磁盘IO,同时跳表实现简单,相比B+树、AVL树、少了旋转树结构的开销,因此redis使用跳表来实现ZSET,而不是树结构。
存储引擎RocksDB内部使用了跳表,对比使用B+树的innodb,虽然写性能更好,但读性能属实差了些。在读多写少的场景下,B+树依旧YYDS。
展开
评论
点赞
#青训营笔记创作活动#
2月14日 打卡day35
对于文本类数据我们习惯用mysql做存储,redis做缓存。但属于文件类数据,比如视频图片,则需要使用oss等做对象存储,cdn做缓存。
用了CDN如果发生回源,那实际上会比不用的时候更慢一些。
CDN最大的优势在于,对于来自世界各地的用户,它可以就近分配CDN节点获取数据,并且多次重复获取同一个文件数据的时候,有缓存加速的作用。如果你的服务和对象存储都在内网,并且文件数据也不太会有重复使用的可能性,那其实没必要接入cdn。
2月14日 打卡day35
对于文本类数据我们习惯用mysql做存储,redis做缓存。但属于文件类数据,比如视频图片,则需要使用oss等做对象存储,cdn做缓存。
用了CDN如果发生回源,那实际上会比不用的时候更慢一些。
CDN最大的优势在于,对于来自世界各地的用户,它可以就近分配CDN节点获取数据,并且多次重复获取同一个文件数据的时候,有缓存加速的作用。如果你的服务和对象存储都在内网,并且文件数据也不太会有重复使用的可能性,那其实没必要接入cdn。
展开
评论
点赞