我说我为什么抽不到SSR,原来是加权随机算法在作祟 ★阅读本文需要做好心理准备,建议带着深究到底的决心和毅力进行学习! ” 灵魂拷问 为什么有 50% 的几率获得金币?...方案一、笨笨的办法 所以要设计一个加权算法的程序,你会怎么写呢? 第一个方法把权重所在的位置展开,然后从该列表中随机选择。 假设现在有权重列表 {1, 2, 4, 8}。...方案二、略显聪明 由于总权重为 15(1+2+4+8),我们可以生成一个 [0,15) 的随机整数,然后根据这个数字返回索引。代码如下。...sort.SearchInts sort.Search() 的函数参数需要一个闭包函数,并且这个闭包函数是在 for 循环中使用的,如下。...优化源码中的二分法。 轮盘赌算法,每次都去赌。 内联:编译器的一个名词。我们的代码最终都是经过编译系统转换成可执行二进制文件。汇编阶段读取的是词法、语法单元输出的结果。
再比如 nginx 的配置中,也有权重配置。 解决方案 方案一、笨笨的办法 第一个方法是在我们的候选列表中,包含了基于权重的每个索引的预期数量,然后从该列表中随机选择。...方案一中的列表不是必须的,方案二避免生成大的列表。由于总权重为 15(1+2+4+8),我们可以生成一个 [0,15) 的随机整数,然后根据这个数字返回索引。代码如下。...但是我们必须写很多的 if else 代码,这看起来太难看了,为了避免编写过多的 if else 代码,衍生出了方案三。 不必将 r 与所有的范围进行比较。...方案五、不可思议 方案四中,实际上引入了一个新的耗时步骤,我们必须对 weightedRandom 排序,当这是一个很大的列表时,效率也就被拉低了。 在方案五中,我们考虑使用累积权重,而不是原始权重。...图片 所以目前无法被编译器正确地内联,从而导致了非实质性的性能开销,在方案六中,我们可以编写一个手动内联的版本。
刚刚看了一下一个帧布局的简单Android示例,纠结了半天不知道如何将图片加到resource中的drawable中去。 ...比如在一个TestDemo的Res/drawable文件夹中,新添加一张图片资源要如何添加。 ...我直接将图片复制到bin\res\drawable-hdpi或者bin\res\drawable-mdpi中去,然后在eclipse中刷新图片仍然不显示。 ...上网找到了关于加载图片资源的问题解决办法: 直接拷贝需要添加的图片资源,然后在Res/drawable文件夹 右键点击 选择“粘贴”即可把图片拷贝进去。...代码如下: package com.ccf.birdframe; import android.os.Bundle; import android.os.Handler; import android.os.Message
新的 Python 程序员必须学会避免一些常见的“陷阱”程序员学习这类知识是随机的,来自经验,但本章把它收集在一个地方。了解这些陷阱背后的编程知识可以帮助您理解为什么 Python 有时行为怪异。...图 8-1:在for循环的每一次迭代中,一个新的'red sock'被添加到列表中,clothing在下一次迭代中引用它。这个循环永远重复。 要点是不要在遍历列表时向列表中添加条目。...这样,您可以在遍历列表时从列表中删除项,或者向列表中添加项,只要将它们添加到列表的末尾。例如,输入下面的代码,它从someInts列表中删除偶数整数。...赋值语句cheese = spam使cheese 引用与spam在计算机内存中相同的列表对象。它不会复制列表对象。这就是为什么改变spam也会改变cheese:两个变量引用同一个列表对象。...不要用字符串连接来构建字符串 在 Python 中,字符串是不可变对象。这意味着字符串值不能改变,任何看似修改字符串的代码实际上都是在创建一个新的字符串对象。
但是,当你写了很多程序,写过很多getter和setter,尤其是有些类方法,只有getter和setter时,总会有一天,你会疑惑,我到底为什么要这么干? Why private field?...只要在一个稍具规模的团队工作过,就一定经历过与不同人写的代码进行集成的痛苦。不论设计阶段做的多么详尽,在开发过程中,接口都不可避免的会发生变化。一旦接口变化,所有与它相关的代码都要修改。...如果直接将内部数据字段暴露出来,比如上面这段代码中的name,如果某天有一个新的需求,要求所有名字都用大写字母表示,就只能添加一个新的接口upperName,而使用name的地方,需要修改调用方式。...如果采用文章开始时的代码,即添加getter和setter,有新需求出现时,只需修改getName方法,不需要修改调用处的代码,即可实现。...因为在C#和Python中,property的访问方式和直接将数据字段暴露出来的访问方式完全一样,所以在写代码时可以考虑先将数据暴露出来,避免过多的getter和setter,减少冗余代码。
名副其实 首先还是要强调这一点,我读过的糟糕的代码有一个共同的特点,那就是代码中存在大量随意的,无意义的命名。...list里存的是什么 keys指的是什么,为什么遍历它 常量”1“的意义是什么 这几个问题可能只有写这段代码的人才能解释(没错,就是我写的)。...另一点容易产生误导的是数字和字母相像的情况,比如,我命名一个变量叫做O1,在编辑器里就很难分辨是O1还是01,如果我写一个这样的表达式 O0=l1; 估计别人会以为我发明了什么新的语言吧。...使用可以被搜索的名称 像我们在一开始的那段代码,为什么要把常量“1”写成OrderConstatn.PAID,不仅是为了可读,也是为了可搜索,试想,如果你要找这段代码,去搜索数字1,会有多少结果?...当然更好的方法是定义一个名为Address的类,把这些变量放到类中,事实上我们也都是这样做的。 当然,有时候也不能添加一些无意义的语境。
如果创建了一个新函数,并且将其分配给保存了另外函数的同一个变量,那么就以一个新函数覆盖了旧函数。在某种程度上,回收了旧函数指针以指向一个新函数。而这一切发生在旧函数体的内部。...下面的例子,我们将上面的scareMe()函数以第一类对象的使用方式来使用: 添加一个新的属性 函数对象被分配给一个新的变量。 该函数也以一个方法的形式使用。...; }; }; // 1、添加一个新的属性 scareMe.property = "propertly"; // 2、赋值给另一个不同名称的变量 var prank = scareMe; //...我们来看这段代码,我自以为是的又加了一层,于是,我希望不用我说,你也已经懂了。 最后,再说一下,为什么赋值给一个其它名字的变量以及用对象的方法来使用的时候,重定义永远没有发生。...该模式由一下几部分组成: 可以使用函数表达式定义一个函数(函数声明是不可以的)。 在末尾添加一组括号,这将导致该函数立即执行。 将整个函数包装在括号中(只有不将该函数分配给变量才需要这样做)。
四、自定义函数 函数可以动态定义,也可以分配给变量。如果创建了一个新函数,并且将其分配给保存了另外函数的同一个变量,那么就以一个新函数覆盖了旧函数。在某种程度上,回收了旧函数指针以指向一个新函数。...下面的例子,我们将上面的scareMe()函数以第一类对象的使用方式来使用: 添加一个新的属性 函数对象被分配给一个新的变量。 该函数也以一个方法的形式使用。...; }; }; // 1、添加一个新的属性 scareMe.property = "propertly"; // 2、赋值给另一个不同名称的变量 var prank = scareMe; //...我们来看这段代码,我自以为是的又加了一层,于是,我希望不用我说,你也已经懂了。 最后,再说一下,为什么赋值给一个其它名字的变量以及用对象的方法来使用的时候,重定义永远没有发生。...该模式由一下几部分组成: 可以使用函数表达式定义一个函数(函数声明是不可以的)。 在末尾添加一组括号,这将导致该函数立即执行。 将整个函数包装在括号中(只有不将该函数分配给变量才需要这样做)。
真实案例剖析让我们来看一个真实的代码案例:在上面的示例中, dataList 在 template 中进行渲染。...如果有新的需求需要更新 dataList 的逻辑,在更新之前,我们必须要理清楚更新的逻辑,这样才能避免改动引发。...但是事实却是相反,在我们实践编写代码中,特别是当维护别人的代码(尤其是复杂的代码)时,我们通常不喜欢修改现有的代码,而是在上面添加自己的代码。...首先我们梳理一下,代码中 dataList 的 同步变更 和 异步变更我们无法更改异步变更,因为从业务角度来看, props.id 更新后,就必须要从后端获取新的 dataList 。...但是我们可以将同步变更中的所有代码堆叠到 computed 中。优化后的代码如下:在 template 中,我们不再渲染 dataList 变量,而是渲染 renderDataList 。
代码中需要给按钮设置监听器对象,使用匿名内部类能够在实现父类或者接口中的方法情况下同时产生一个相应的对象,但是前提是这个父类或者接口必须先存在才能这样使用。...,编译器还是会默认添加一个参数,该参数的类型为指向外部类对象的一个引用,所以成员内部类中的Outter this&0 指针便指向了外部类对象,因此可以在成员内部类中随意访问外部类的成员。...根据上图可知,test方法中的匿名内部类的名字被起为 Test$1。 上段代码中,如果把变量a和b前面的任一个final去掉,这段代码都编译不过。...但是新的问题又来了,既然在run方法中访问的变量a和test方法中的变量a不是同一个变量,当在run方法中改变变量a的值的话,会出现什么情况? ...三.内部类的使用场景和好处 为什么在Java中需要内部类?
1.对nil map、nil slice 添加数据 请考虑一下这段代码是否有错,然后运行一遍: 1package main 2 3func main() { 4 var m map[string]...string 5 m["name"] = "zzy" 6} 不出意外的话,这段代码将导致一个panic: 1panic: assignment to entry in nil map 这是因为代码中只是声明了...,也就是说,如果在某个if语句中,不小心用:=而不是=对某个if语句外的变量进行赋值,那么将产生一个新的局部变量,并仅仅在if语句中的这个赋值语句后有效,同名的外部变量会被屏蔽,将不会因为这个赋值语句之后的逻辑产生任何变化...在golang中,array和struct都是值类型的,而slice、map、chan是引用类型,所以我们写代码的时候,基本不使用array,而是用slice代替它,对于struct则尽量使用指针,这样避免传递变量时复制数据的时间和空间消耗...这个报错的意思其实就是不允许修改map中的元素。 即便map中元素没有以上限制,这段代码依然是错误的,想一想,为什么?答案之前已经说过了。
闭包是令人困惑的,因为它是一个“无形的”概念。 当使用对象、变量或函数时,你会想:“在这里我需要一个变量”,然后将其添加到你的代码中。 闭包有各种不同的形式。...很多人在注意到闭包时,实际上他们已经在不知不觉中多次使用过了——可能你也是如此。所以学习闭包不是要去了解什么「新」概念,而是要了解你「已经」接触过的东西。...这段代码有效!但是仔细看,注意 eat 函数在 liveADay 函数的内部。这允许吗?我们真的可以将一个函数放在另一个函数中吗? 在某些语言中,用这种方式写出来的代码是「无效」的。...它有一个 food 局部变量,还包含一个 eat 函数。然后调用 eat 功能。因为 eat 在 liveADay 内部,所以它“看到”了所有变量。这就是为什么它可以读取 food 变量的原因。...因此,如果你想从函数外部读取变量,则必须在 Rust 中选择使用该变量。这是因为在底层,即使在函数调用之后,闭包也可能要求引擎保持外部变量(称为“环境”)。
2、问题的解释 问题就在与,第一种即使用*创建数组时,数组中的每一个元素都是同一个list object,那么往任意一个中添加元素,实际上是往所有的元素中添加,所以会出现之前的结果,而用列表生成式的方法...下面来分析一下这段代码: 1)首先,创建了一个名为will的变量,这个变量指向一个list对象,从第一张图中可以看到所有对象的地址(每次运行,结果可能不同) 2)然后,通过will变量对wilber变量进行赋值...这里需要注意的一点是,str是不可变类型,所以当修改的时候会替换旧的对象,产生一个新的地址39758496。 上面这段代码的过程可以由下面的图进行解释: ?...分析一下这段代码: 1)首先,依然使用一个will变量,指向一个list类型的对象。...分析一下这段代码: 1)首先,同样使用一个will变量,指向一个list类型的对象 2)然后,通过copy模块里面的深拷贝函数deepcopy(),对will指向的对象进行深拷贝,然后深拷贝生成的新对象赋值给
,编译器还是会默认添加一个参数,该参数的类型为指向外部类对象的一个引用,所以成员内部类中的Outter this&0 指针便指向了外部类对象,因此可以在成员内部类中随意访问外部类的成员。...根据上图可知,test方法中的匿名内部类的名字被起为 Test$1。 上段代码中,如果把变量a和b前面的任一个final去掉,这段代码都编译不过。...将这段代码的字节码反编译可以得到下面的内容: 我们看到在run方法中有一条指令: bipush 10 这条指令表示将操作数10压栈,表示使用的是一个本地局部变量。...但是新的问题又来了,既然在run方法中访问的变量a和test方法中的变量a不是同一个变量,当在run方法中改变变量a的值的话,会出现什么情况? ...为了解决这个问题,java编译器就限定必须将变量a限制为final变量,不允许对变量a进行更改(对于引用类型的变量,是不允许指向新的对象),这样数据不一致性的问题就得以解决了。
在 if 主体中,你可以添加另一个 num,这并不令人震惊(新的块级别作用域)。 好的,在 Kotlin 中,inc(1) 输出 2。但是在Java中,等效代码将无法通过编译。 ?...为什么要把名称和类型分隔开?我不知道。不过我知道这会加大使用Kotlin的难度。 第二个问题。在阅读一个方法声明的时候,你最先想知道的应该是方法的名称和返回类型,然后才会去了解参数。...即时在 Intellij 这么优秀的 IDE 中为 Kotlin 输入这样的变量名也十分不易。如果代码中存在很多 Repository,就很难在自动完成列表中找到匹配的那一个。...因此,要让这段代码对空安全,你必须在 let 前添加 ?: ? 现在,比如 Java 和 Kotlin 两个版本的可读性,你更喜欢哪一个?...Kotlin 中的类默认是封闭(final)的。如果你想从某个类扩展,你就必须为它的声明添加 open 修饰符。 继承语法就像这样: ?
这恐怕没有多少程序员能清楚地解释其中的原理,现在就让我来给出一个天衣无缝的解答: 尽管前面给出的两段代码并不复杂,但这里面隐藏的信息量相当的大。在正式解答之前,先给出一些知识点: 1....也就是说,在使用某个函数、类之前必须定义,或者说,函数、类必须在使用前定义。例如,下面的代码是合法的。...而且变量a用var声明,就说明这是hello函数的局部变量,而函数a已经在第1遍扫描中获得了,所以在执行到var a = 99时,js解析器已经知道了函数a的存在,由于变量a和函数a都在同一个作用域,所以可以覆盖...{ // 提升作用域到顶层作用域 } a = 30; // 不处理 } console.log(a); // 不处理 到现在为止,第1遍扫描结束,得到的结果只是在顶级作用域中添加了一个函数...第2遍扫描: // 在第2遍扫描时,其实已经发现在第1遍扫描中存在一个顶层的函数a(作用域被提升的),所以这个变量a其实是覆盖了第1遍扫描时的a函数 // 所以说,不是函数a覆盖了变量a,而是变量a覆盖了函数
可这是为什么呢?为什么多线程代码如此难以正确编写呢? 从根源上思考 关于这个问题,本质上是有一个词语你没有透彻理解,这个词就是所谓的线程安全,thread safe。...关你什么屁事 生活中我们口头上经常说的一句话就是“关你屁事”,大家想一想,为什么我们的屁事不关别人? 原因很简单,这是我的私事啊!...如果你想去饭馆、去公共卫生间那么就必须遵守规则,这个规则就是排队,只有前一个人用完公共资源后下一个人才可以使用,而且不能同时使用,想使用就必须排队等待。 上面这段话道理足够简单吧。...什么是线程安全 我们说一段代码是线程安全的,当且仅当我们在多个线程中同时且多次调用的这段代码都能给出正确的结果,这样的代码我们才说是线程安全代码,Thread Safety,否则就不是线程安全代码,thread-unsafe...只使用线程私有资源 我们来看这段代码: int func() { int a = 1; int b = 1; return a + b; } 这段代码在前面提到过,无论你在多少个线程中怎么调用什么时候调用
如你所知,变量给数据片段一个名称,这样你就可以在程序中使用它。如果你有这段代码: 1 x = 10 然后你创建了一个名为x的数据片段,它等于数字 10。...有了这个想法,让我们逐行分解ex22.py中的代码: 1-2 我从你已经了解的常规命令行参数处理开始。 5 我在一个方便命名为main的函数中开始这段代码的主要部分。这将在脚本末尾调用以启动事务。...尝试添加新变量并再次导入以查看其工作原理。...让我们看一个新的 Python 代码片段: 1 while True: 2 x = 10 要理解这段代码,我们必须预示一个稍后的练习,你将学习关于 while-loop。...当你 JUMP 时,你在告诉计算机将这个索引更改到代码中的一个新位置。在我们的 while 循环代码中(下面),JUMP_ABSOLUTE 在索引 4 处(看左边的 4)。
我的理解是,闭包就是能够读取其他函数内部变量的函数。 由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。...这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。 为什么会这样呢?...这段代码中另一个值得注意的地方,就是“nAdd=function(){n+=1}”这一行,首先在nAdd前面没有使用var关键字,因此 nAdd是一个全局变量,而不是局部变量。...这样在执行完var c=a()后,变量c实际上是指向了函数b,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么?...这段代码中变量h指向了f中的那个匿名函数(由g返回)。
块级作用域 JavaScript 开发者一个常见的 bug 是假设 JavaScript 为每个代码块创建一个新的作用域。虽然这在许多其他语言中是正确的,但在 JavaScript 中不是这样。...为什么? 在大多数其他语言中,上面的代码都会导致类似这样的错误。因为变量 i 的“生命周期”(即作用域)被限制在 for 循环语句中。...但在 JavaScript 中,情况并非如此,即使在 for 循环完成后,变量 i 仍留在作用域中,在退出循环后保留其最后一个值。(这种行为被称为变量提升。) 有一个解决办法。...但是这是为什么呢? 让我们重新更详细地检查这段代码一下,发现: 每个 theThing 对象都包含大小为 1MB 的 longStr 对象。...低效的 DOM 操作 虽然使用 JavaScript 操作 DOM (例如,添加、修改和删除元素)变得相对容易,但却无法提高操作效率。 一个常见的例子是每次添加一个 DOM 元素的代码。
领取专属 10元无门槛券
手把手带您无忧上云