首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【一天一大 lee】 合并二叉树 (难度:简单)-Day20200923

你需要将他们合并为一个的二叉树。合并的规则是如果两个节点重叠,那么将他们的相加作为节点合并,否则不为 NULL 的节点将直接作为二叉树的节点。...思路 同步遍历两个二叉树,并且将到的节点相加,和作为二叉树的节点 每次遍历将的二叉树作为子树追加到上一次生成的的二叉树中 特殊情况 两个二叉树,其中任意一个为 null,直接返回另外一个 深度优先遍历...,这样省略了每层生成树的逻辑 var mergeTrees = function(t1, t2) { if (t1 == null) return t2 if (t2 == null) return...t2 待遍历节点 var mergeTrees = function(t1, t2) { if (t1 == null) return t2 if (t2 == null) return t1..., t1 中做累计 var mergeTrees = function(t1, t2) { if (t1 == null) return t2 if (t2 == null) return t1

53910

Javascript一些优雅实现

= +new Date() sleep(3000).then(()=>{ const t2 = +new Date() console.log(t2 - t1) }) 这种方式不会阻塞...,无负载问题,使用时代码量不多,但Promise内部的代码出错需要层层判断后catch,还是有些麻烦。...= +new Date() await sleep(3000) const t2 = +new Date() console.log(t2 - t1) }() 各个函数都是非嵌套结构,现在开始要拥抱这种写法...= +new Date() sleep.msleep(3000) const t2 = +new Date() console.log(t2 - t1) 现在开始异步请求都要试着Promise的基础上拥抱...暂不考虑对象字面量,函数等引用类型的去重,也不考虑 NaN, undefined, null等特殊类型情况 普通版 只说下思路,这种复杂度为平方的不再上代码,整体就是对这个数组每个元素取出来放到另一个数组中,放入之前检验这个数组中是否已有这个

791110
您找到你想要的搜索结果了吗?
是的
没有找到

高并发编程-HashMap深入解析

HashMapJDK1.8及以后的版本中引入了红黑树结构,若桶中链表元素个数大于等于8时,链表转换成树结构;若桶中链表元素个数小于等于6时,树结构还原成链表。...假设插入的第四个元素a4,通过Hash算法计算出的数组下标也是2,当插入时则需要扩容,此时有两个线程T1T2同时插入a4,则T1T2同时进行扩容操作,它们各自新建了一个Entry数组newTable...T2线程执行到transfer方法的Entry next = e.next;时被挂起,T1线程执行transfer方法Entry数组如下图: ?...T1线程没返回新建Entry数组之前,T2线程恢复,因为T2挂起时,变量e指向的是a1,变量next指向的是a2,所以T2恢复执行完transfer之后,Entry数组如下图: ?...可以看到T2执行完transfer方法,a1元素和a2元素形成了循环引用,此时无论将T1的Entry数组还是T2的Entry数组返回作为扩容数组,都会存在这个环形链表,当调用get方法获取该位置的元素时就会发生死循环

50820

免费开放阅读 | 数据库管理系统的事务原理(上)

不可重复读现象:事务 T1 t0时刻先读取 row的旧,事务 T2 t1时刻对 row进行了修改(更新或删除)然后提交事务使得修改生效,此时row因更新变为了或因删除而不再存在。...接下来,事务 T1 t3时刻再次读取 row对象的但是 row的已经是或者不存在了。...脏写现象:按照时间顺序,事务 T1 t0时刻对 row进行了修改(更新),事务 T2 t1时刻对 row进行了修改(更新),如果没有并发控制,T2对 row的修改会生成,但是 T1 t3时刻回滚使得...丢失更新现象:按照时间顺序,事务 T2 t1时刻对 row进行了修改(更新),事务 T1 t2时刻对 row进行了修改(更新),如果没有并发控制,T1对 row的修改会生成,但是 T1 t3时刻提交使得...事务 T1 t2时刻进行判断:如果在打电话的值班医生个数大于等于2 人则请Alice停止打电话。事务 T2 t3时刻进行判断:如果在打电话的值班医生个数大于等于 2人则请 Bob停止打电话。

1.6K81

深入理解CAS算法原理

imageMogr2/auto-orient/strip|imageView2/2/w/320/format/webp 注:t1t2线程是同时更新同一变量56的 因为t1t2线程都同时去访问同一变量...56,所以他们会把主内存的值完全拷贝一份到自己的工作内存空间,所以t1t2线程的预期都为56。...假设t1t2线程竞争中线程t1能去更新变量的,而其他线程都失败。(失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次发起尝试)。t1线程去更新变量值改为57,然后写到内存中。...变量前面追加上版本号,每次变量更新的时候把版本号加一,那么A-B-A 就会变成1A-2B-3A。...这个类的compareAndSet方法作用是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的设置为给定的更新

52310

你可能还不知道 golang 的高效编码细节

计算量很小的时候,可能看不出使用 临时 struct 和 map 的耗时差距,但是数量起来了,差距就明显了,且会随着数量越大,差距越发明显 当我们遇到键和都可以是固定的时候,我们选择 struct 比...为什么上述差距会那么大,原因是 我们可以确定字段的情况下,我们使用 临时的 Struct 在运行期间是不需要动态分配内容的, 可是 map 就不一样,map 还要去检查索引,这一点就非常耗时了 字符串如何拼接是好...我们的工具暂时提供如下几种: 使用 + 的方式 使用 fmt.Sprintf() 的方式 使用 strings.Join 的方式 使用 buffer 的方式 看到这里,也许我们各有各的答案,不过我们还是来实操一遍,看看他们相同字符串拼接情况下...,各自的处理耗时如何 用 + 的方式 我们来计算循环追加 50 万 次字符串,看看耗时多少 func main() { t1 := time.Now().UnixNano() / 1e6 fmt.Println...t1 == ", t2-t1) } 程序运行查看效果: # go run main.go t1 == 1634378977361 t2 == 1634379240292 t2 - t1 ==

20930

Netty源码实战(十) - 性能优化

默认为2 看看的构造器的 radio 参数 默认8 两倍CPU核心数 自然该为7 1.2.3 回收对象到 Recycler 1.2.3.1 同线程回收 客户端开始调用...那么它为何要定义成一个 map 结构呢,假设有3个线程T1/2/3; T1创建的对象肯可能跑到T3中回收,T2中创建的对象也可能到了T3回收. 那么元素就是T1以及T2的WOQ....假设当前T2中,接下呢就通过get(this)拿到T1的WOQ,其中的 this 指的就是T1的 Stack....其中的 this 即为 stack,是T1中维护的,thread 即表示当前线程T2. allocat就是为了给当前线程T2分配一个T1中的Stack 对应的一个WOQ....创建完,拿到其写指针,即 tail 的长度(0).所以 tail 节点也已经又有了足够的存储空间,将 handle 追加进去.再将该 handle 的 stack 指针重置为 null,因为已经不属于原来的

48930

不要再问我 in,exists 走不走索引了...

有没有发现, t1 表哪种情况都不会走索引,而 t2 表是有索引的情况下就会走索引。为什么会出现这种情况? 其实,上一小节说到了 exists 的执行流程,就已经说明问题了。...我这里,用的是自定义函数来循环插入,语句参考如下,(没有把表名抽离成变量,因为我没有找到方法,尴尬) -- 传入需要插入数据的id开始和数据量大小,函数返回结果为最终插入的条数,此正常应该等于数据量大小...我去查看它们分别在查询优化器中优化的 sql 。 以 select * from t1 where id in (select id from t2); 为例,顺序执行以下两个语句。...但是和 explain 一块儿使用,就会显示出优化的sql。需要注意使用顺序。 show warnings; 结果 Message 里边就会显示我们要的语句。 ?...PS: 这里我们也可以发现,select * 最终会被转化为具体的字段,知道为什么我们不建议用 select * 了吧。 同样的,以 t2 大表为外表的查询情况,也查看优化的语句。

1.8K20

硬核干货 | 突破底层基础架构瓶颈,揭秘TDSQL存储核心技术

事务T2再去拿commit_ts:6,再将A=15写回数据存储中。事务T1也拿到了commit_ts:7,再把A=15写回数据存储。最终会产生两个A的新版本,但是其value都等于15。...我们回顾上述过程会发现T2T1错误地覆盖了:T1读取到了T2更新前的,然后覆盖了T2更新。...因此要想得到正确的结果有两个方法,要么T1应该读取到T2更新再去覆盖T2更新,要么T1获取到T2更新前的的基础上去覆盖T2更新时应该失败。...怎么保证T1获取到T2更新前的再去覆盖T2更新时应该失败呢,我们引入了一个的规则:事务提交前需要做一次冲突检测。...最终的结果是虽然事务T1执行前后总余额都是20,但是事务T2查询到的总余额却等于15,少了5元。

60631

【C#】分享带等待窗体的任务执行器一枚

这里就表示等待窗体是执行任务时才传进去的,任务执行完成,WaitUI会销毁等待窗体,这是为了让WaitUI作为一个静态类,尽量短暂的持有对象,节约内存。...当用户发起终止请求,WaitUI的UserCancelling会变为true,在任务中你可以根据这个来做出终止任务的处理,但是终止之前,还得麻烦你设置一个标记,千万别忘记,就是让WaitUI.Cancelled...= true,这等于告诉执行器任务确实终止了,设置完标记,最好紧跟终止代码,不要再做其它事,让Cancelled与事实一致。...如果任务有返回的话;②任务产生异常,RunXXX会原样抛出该异常;③任务被终止,抛出WorkCancelledException异常(后面有关于为什么选择抛异常这种方式的说明)。...而为什么我仍然选择接口,也恰恰是因为要保证灵活,就是要允许编写者从其它第三方Form继承,设计美观的等待窗体,如果设计为基类,那就堵死了这种可能,等于灵活性和健壮性之间选择了前者。

1.7K30

那些让我印象深刻的bug--05

背景: 有一个缓存服务cache-services,里面提供了一个对外的接口,可以根据id进行查询,返回一系列的数据,其中有一个字段的返回客户端会根据这个字段的做一些校验处理,比如字段为A的时候...下面再来简单的讲一下缓存的加载设计: 假设现在有两张表,t1t2,他们通过一个叫id的字段进行关联。...假设数据库表设计如下: t1 t2 id id type source name createTime createTime updateTime updateTime 由于t1表是之前就已经存在的...最近,由于开发的功能,加入了t2的表,换了一个人开发,设计的时候,开发设计的是:t2表里面有数据的时候,新增/更新数据时,把对应的字段source追加到之前对应id的数据的缓存中。...问题解决的措施: 加载主表缓存的时候,同时把其他附属表的相关字段也重新加载一遍。

31220

NOT IN子查询中出现NULL对结果的影响你注意到了吗

,都是查询t1表中c2列t2表的c2列中不存在的记录。...,也就是左外连接时没有关联上右表的数据,表达了这个含义“t1表中c2列t2表的c2列中不存在的记录”。...NULL的记录,结果集会怎样呢,两个表都存在c2列为NULL的数据,那么t1表这条NULL数据能否出现在最终结果集中呢?...左外left join 与 not exists相同,左表的NULL右表中关联不上数据,所以要返回(3,NULL)这条数据。这里要注意NULL 不等于 NULL。...想象一下,如果关联的两个表关联字段上都存在很多NULL记录,关联的结果集对NULL记录的关联是以笛卡尔积的形式体现的,严重影响效率,严格来说关联字段都为NULL不能算作能匹配上。

7510

DM 分库分表 DDL “悲观协调” 模式介绍丨TiDB 工具分享

从用户的角度来讲,数据库的用途主要的是查询,分库分表合并前后,查询的结果应该是相同的(不考虑 LIMIT 等算子以及不确定性查询)。也就是说,各分表查询结果的并集应当等于迁移的查询结果。...容易得到一个满足此要求的充分条件:各分表数据的并集应当等于迁移的表数据。考虑到同步延迟的影响,也就是当前时刻下游表的数据等于各分表在过去某时刻数据的并集。...此时我们可以保证下游表的 DDL 产生的影响等于所有分表都进行了 DDL(不考虑非确定性 DDL,例如 DDL 新增列默认为 current_timestamp)。...某些情况下,t1t2 可能位于一个 binlog 流之中,因此上图中看似独立的流的暂停与恢复,实际实现为同一个 binlog 流中跳过事件及回滚同步位置。...,我们将在后续的文章中具体介绍,希望大家能够深入了解两种协调模式的原理和使用限制,根据场景选择合适的模式进行分库分表的合并迁移。

31030

【Python编程导论】第五章- 结构化类型、可变性与高阶函数

# tuple类型的字面量形式是位于小括号之中的由逗号隔开的一组元素 t1=() t2 = (1,) #注意当元组中只有一个元素时,加逗号 t3 = (1, 'two', 3) print(t1,t2...t1 = (1, 'two', 3) t2 = (t1, 3.25)#,这个元组中有一个绑定了名称t1的元组和一个浮点数3.25。...这是可行的,因为元组也是一个对象 print(t2) print((t1 + t2)) print((t1 + t2)[3]) print((t1 + t2)[2:5]) ('a',2,'a',2,'a...但不可变类型的对象是不能被修改的,相比之下,list类型的对象创建完成可以被修改。...它会创建一个 列表,其中的每个元素都是一个序列中的(如另一个列表中的元素)应用给定操作的结果 mixed = [1, 2, 'a', 3, 4.0] print([x**2 for x in mixed

1.3K30

java多线程与高并发:LockSupport、淘宝面试题与源码阅读方法论

我们来分析一下代码的执行过程,首先我们使用lombda表达式创建了线程对象 " t " ,然后通过 " t " 对象调用线程的启动方法start(),然后我们再看线程的内容,for循环中,当 i 的等于...5个对象,唤醒了t2线程,重点在于小程序3我们说过notify()方法是不会是释放锁的,所以notify()以后,又紧接着调用了wait()方法阻塞了t1线程,实现了t2线程的实时监控,t2线程执行结束...,不同点在于没有了锁,采用了await()方法替换了t2线程和t1线程中的wait()方法,执行流程是创建门闩对象latch,t2线程开始启动,判断到对象不等于5,调用await()方法阻塞t2线程,t1...很简单,t1线程调用unpark()方法唤醒t2线程的时候,紧接着调用park()方法使t1线程阻塞,然后t2线程打印信息结束调用unpark()方法唤醒t1线程,至此程序结束,具体实现,我们往下看...因为当LinkedList集合中“馒头”数等于最大的时候,if判断了集合的大小等于MAX的时候,调用了wait()方法以后,它不会再去判断一次,方法会继续往下运行,假如在你wait()以后,另一个方法又添加了一个

38220

数据库并发控制理论

下面调度,是可串行化的,T1T2前执行,但T2先提交,所以不满足可恢复性。可以想象如果发生崩溃,T2的提交记录到达磁盘,而T1没有到达,那么恢复T2都处于提交状态,而T1会回滚。...如下,T2读取了T1更新的,T3读取了T2更新的,那么T1回滚,为了避免数据不一致,所以T2和T3必须回滚。A指Abort。...遵循严格封锁调度有两个特性符合ACA的也符合strictness,因为由于锁的存在无法读取或修改其他未提交事务修改的是可串行化的可以看到下面的例子,只有当T1 Commit,才会释放B的写锁,所以T2...要等到T1 Commit,才能获取到B的读锁;假设T1回滚,也不会造成T2回滚,这样就避免了级联回滚了。...版本的组织方式有以下几种append-only storage追加方式:新版本直接追加写入到同一个表空间中time-travel storage时间线方式:老版本单独存储一个表空间中delta storage

13710
领券