天道酬勤,学无止境

可以强制存在量化类型变量只有一个类型吗?(Can an existentially quantified type variable be forced to have only a single type?)

问题

考虑以下代码

trait Foo[T] {
  def one: Foo[_ >: T]
  def two: T
  def three(x: T)
}

def test[T](f: Foo[T]) = {
  val b = f.one
  b.three(b.two)
}

方法测试无法进行类型检查。 它说:

 found   : (some other)_$1(in value b)
 required: _$1(in value b)
     val x = b.three(b.two)

如果我正确解释了这一点,编译器会认为方法 test 中的 b 有一个看起来像这样的类型(不是合法的语法,但希望更清楚):

trait Foo {
   def two: X where ∃ X >: T
   def three(x: X where ∃ X >: T)
}

我希望它有这样的类型:

∃ X >: T such that trait Foo {
   def two: X
   def three(x: X)
}

目的是虽然不知道确切的类型 X,但编译器知道它的相同未知类型由“二”返回并由“三”预期。 这似乎与普通通用量化泛型发生的情况不同。 以下编译,但公开了我想隐藏的类型参数 X,因为它会因 Foo 的实例而异:

trait Foo[T] {
  def one[X >: T]: Foo[X]
  def two: T
  def three(x: T)
}

def test[T, X >: T](f: Foo[T]) = {
  val b = f.one[X]
  b.three(b.two)
}

有没有办法让我们在普遍量化时获得的存在量化泛型具有相同的行为?

回答1

def one: Foo[_ >: T]等价于

def one: Foo[U >: T] forSome {type U >: T}

这个反而有效

def one: Foo[U forSome {type U >: T}]

然而,我不明白为什么这会有所作为。 对我来说似乎不应该。 (耸肩)

回答2

问题是编译器认为

b.two: _>:T
b.three(_>:T)

即二是 T 的超类型,三需要 T 的超类型。但是 T 的超类型不一定与 T 的另一个超类型赋值兼容,如下例所示:

A >: B >: C
def get:A
def put(B)
put(get) // type mismatch

因此,如果我们拥有的所有信息都是它们是 T 的超类型,那么我们就不能安全地做到这一点。 我们必须明确告诉编译器它们是 T 的相同超类型。

trait Foo[T] {
  type U <: T
  def one: Foo[U]
  def two: T
  def three(x: T)
}

然后在实现特性时设置U

val x = new Foo[Dog]{
  type U = Mammal
  ...

由于更简洁的语法以及这是核心 Scala 并且不需要导入该功能的事实,我更喜欢这种方法而不是存在类型。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 什么是存在类型?(What is an existential type?)
    问题 我通读了Wikipedia文章存在类型。 我发现由于存在运算符(∃),它们被称为存在类型。 不过,我不确定它的意义是什么。 之间有什么区别 T = ∃X { X a; int f(X); } 和 T = ∀x { X a; int f(X); } ? 回答1 当有人定义通用类型∀X他们的意思是:您可以插入所需的任何类型,我不需要知道任何有关该类型的内容即可完成工作,我只会不透明地将其称为X 当有人定义了存在类型∃X他们的意思是:我将在此处使用所需的任何类型; 您对类型一无所知,因此只能将其不透明地称为X 通用类型使您可以编写如下内容: void copy<T>(List<T> source, List<T> dest) { ... } copy函数不知道T实际是什么,但不需要知道。 现有类型可以让您编写如下内容: interface VirtualMachine<B> { B compile(String source); void run(B bytecode); } // Now, if you had a list of VMs you wanted to run on the same input: void runAllCompilers(List<∃B:VirtualMachine<B>> vms, String source) { for (∃B
  • Haskell / GHC中的“ forall”关键字有什么作用?(What does the `forall` keyword in Haskell/GHC do?)
    问题 我开始了解在这样的所谓“现有类型”中如何使用forall关键字: data ShowBox = forall s. Show s => SB s 但是,这只是forall用法的一个子集,我根本无法在这样的事情上forall地使用它: runST :: forall a. (forall s. ST s a) -> a 或解释为什么这些不同: foo :: (forall a. a -> a) -> (Char, Bool) bar :: forall a. ((a -> a) -> (Char, Bool)) 或整个RankNTypes东西... 我倾向于使用清晰,无术语的英语,而不是学术环境中通常使用的那种语言。 我试图阅读的大多数解释(通过搜索引擎可以找到的解释)都存在以下问题: 他们不完整。 他们解释了该关键字使用的一部分(例如“ existential types”),这使我感到高兴,直到我阅读了以完全不同的方式使用它的代码(例如上述的runST , foo和bar )。 假设我在本周流行的离散数学,范畴论或抽象代数的任何分支中都读到了最新的东西,他们的想法密密麻麻。 (如果我从来不读的话“咨询文件无论执行的细节”再次,这将是太快了。) 它们的编写方式经常将甚至是简单的概念变成曲折而破碎的语法和语义。 所以... 到实际的问题。 有人能用清晰
  • GHC 的类型家族是 F-omega 系统的一个例子吗?(Are GHC's Type Famlies An Example of System F-omega?)
    问题 我正在阅读有关 Lambda-Cube 的信息,我对 System F-omega 尤其感兴趣,它允许“类型运算符”,即类型取决于类型。 这听起来很像 GHC 的类型家族。 例如 type family Foo a type instance Foo Int = Int type instance Foo Float = ... ... 其中实际类型取决于类型参数a 。 我认为类型系列是类型运算符 ala system F-omega 的一个例子是否正确? 还是我在左外野? 回答1 系统 F-omega 允许通用量化、抽象和应用在更高的种类上,所以不仅在类型上(在种类* ),而且在种类k1 -> k2 ,其中k1和k2本身是从*和->生成的种类。 因此,类型级别本身变成了简单类型的 lambda 演算。 Haskell 提供的性能略低于 F-omega,因为类型系统允许在更高类型上进行量化和应用,但不允许抽象。 更高种类的量化是我们如何拥有这样的类型 fmap :: forall f, s, t. Functor f => (s -> t) -> f s -> f t 与f :: * -> * 。 相应地,像f这样的变量可以用更高级的类型表达式来实例化,比如 Each Either String 。 缺乏抽象使得通过支持 Hindley-Milner
  • null是否为Object?(Is null an Object?)
    问题 Java中的null是Object吗? 回答1 如果Object为null,它将支持java.lang.Object的方法,例如equals() 。 但是,事实并非如此-对null的任何方法调用都会导致NullPointerException 。 这是Java语言规范在该主题上必须说的: 还有一个特殊的null类型,即表达式null的类型,它没有名称。 由于null类型没有名称,因此无法声明null类型的变量或将其强制转换为null类型。 空引用是空类型表达式的唯一可能的值。 空引用始终可以转换为任何引用类型。 在实践中,程序员可以忽略null类型,而假装null只是可以是任何引用类型的特殊文字。 我认为这可以归结为“ null is special”。 回答2 根据Java规范, null是可以分配给对象变量的类型(如注释中所述的值)。 但是,您无法实例化或创建此类型的变量,必须使用编译器提供的原义null 。 回答3 绝对不会: null instanceof Object返回false。 回答4 JRL(及其他)写道: 不,这不对, ... 通常,这取决于您从哪里看,谁会相信更多。 根据JLS,是的。 特别是如果您将问题改写为:“是Object类型的null文字吗?”。 除了上面迈克尔·伯格沃德(Michael Borgwardt)引用的JLS 4.1: 参见JLS 3
  • JavaScript是非类型化语言吗?(Is JavaScript an untyped language?)
    问题 我发现有人将JavaScript称为“动态,弱类型”语言,但有人甚至说“未类型”? 到底是哪一个? 回答1 JavaScript未输入类型: (来源:gd) 甚至布伦丹·艾希(Brendan Eich)也是这样。 在Twitter上,他回复了一个与此问题相关的话题: 学术类型使用“无类型”来表示“没有静态类型” 因此,问题在于untyped有一些不同的定义。 在上面的答案之一中已经讨论了一个定义-运行时不标记值,而只是将每个值视为位。 JavaScript会标记值,并基于这些标记具有不同的行为。 因此,JavaScript显然不适合此类。 另一个定义来自编程语言理论(Brendan所指的学术东西)。 在此域中,无类型只是意味着所有内容都属于一种类型。 为什么? 因为一种语言只有在可以证明类型对齐时才会生成程序(又称Curry-Howard对应;类型是定理,程序是证明)。 这意味着使用非类型化的语言: 程序总是生成因此类型总是匹配的因此,只能有一种类型 与输入语言相反: 程序可能无法生成因为类型可能不匹配因为程序可以包含多种类型 因此,在PLT中, untyped仅表示动态类型,而typed仅表示静态类型。 在此类别中,JavaScript绝对是没有类型的。 也可以看看: 辩论类型系统之前要了解的内容在学术CS世界中,“未打字”是否还意味着“动态打字”? 回答2 可以考虑强
  • 什么是skolems?(What are skolems?)
    问题 eek! GHCi在我的代码中找到了Skolems! ... Couldn't match type `k0' with `b' because type variable `b' would escape its scope This (rigid, skolem) type variable is bound by the type signature for groupBy :: Ord b => (a -> b) -> Set a -> Set (b, [a]) The following variables have types that mention k0 ... 这些是什么? 他们想要我的程序什么? 他们为什么要逃脱(忘恩负义的小家伙)? 回答1 首先,上下文中的“刚性”类型变量是指由该上下文外部的量词绑定的类型变量,因此无法与其他类型变量统一。 这非常像由lambda绑定的变量那样工作:给定lambda (\x -> ... ) ,从“外部”,您当然可以将其应用于您喜欢的任何值; 但在内部,您不能简单地确定x的值应为某个特定值。 在lambda中为x一个值听起来很愚蠢,但这就是“无法匹配等等,刚性类型变量,等等等等”的错误。 请注意,即使不使用显式的forall量词,任何顶级类型签名对于提到的每个类型变量都具有隐式的forall 。 当然,这不是您得到的错误
  • 为什么不依附类型?(Why not be dependently typed?)
    问题 我已经看到一些消息来源回应了这样的观点,即“ Haskell正在逐渐成为一种依赖类型的语言”。 这似乎意味着随着越来越多的语言扩展,Haskell朝着这个总体方向发展,但目前还没有。 我想知道的基本上有两件事。 首先,很简单,“成为一种依赖类型的语言”实际上是什么意思? (希望不要太过专业。) 第二个问题是...缺点是什么? 我的意思是,人们知道我们正朝着这个方向前进,因此必须有一定的优势。 但是,我们还没有到那儿,因此必须存在一些不利因素,阻止人们一路前进。 我觉得问题是复杂性急剧增加。 但是,我不确定是否真正了解依存类型是什么。 我所知道的是,每当我开始阅读有关依赖类型的编程语言的内容时,文本都是完全难以理解的……大概就是问题所在。 (?) 回答1 依赖类型实际上只是值和类型级别的统一,因此您可以对类型进行参数化(在Haskell中已经可以使用类型类和参数多态性进行参数化),并且可以对值进行类型化(严格地说,在Haskell中尚不可行) ,尽管DataKinds非常接近)。 编辑:显然,从现在开始,我错了(请参阅@pigworker的评论)。 我将其余的内容记录下来,作为我被喂饱的神话的记录。 :P 据我所知,转向完全依赖类型的问题在于,它将打破类型和值级别之间的相位限制,从而使Haskell可以编译为具有擦除类型的高效机器代码。 在我们目前的技术水平下
  • 如何在Pandas的DataFrame中的行上进行迭代(How to iterate over rows in a DataFrame in Pandas)
    问题 我有一个来自Pandas的DataFrame : import pandas as pd inp = [{'c1':10, 'c2':100}, {'c1':11,'c2':110}, {'c1':12,'c2':120}] df = pd.DataFrame(inp) print df 输出: c1 c2 0 10 100 1 11 110 2 12 120 现在,我要遍历该框架的行。 对于每一行,我希望能够通过列名访问其元素(单元格中的值)。 例如: for row in df.rows: print row['c1'], row['c2'] 熊猫有可能做到这一点吗? 我发现了这个类似的问题。 但这并不能给我我所需要的答案。 例如,建议在那里使用: for date, row in df.T.iteritems(): 或者 for row in df.iterrows(): 但是我不知row对象是什么以及如何使用它。 回答1 DataFrame.iterrows是一个生成器,它同时生成索引和行(作为系列): import pandas as pd df = pd.DataFrame({'c1': [10, 11, 12], 'c2': [100, 110, 120]}) for index, row in df.iterrows(): print(row['c1']
  • 1-java的变量和数据类型的转换
    变量概述 变量:常量是固定不变的数据,那么在程序中可以变化的量称为变量。 变量:计算机要进行运算必须能够保持住参加运算的数据,首先数据要进入内存存放在内存中,为了方便找到并使用这些数据,那么必须要对它们进行标示,这种标识符所表示的数据就成为变量。因此变量用来标示内存中的一份数据。变量表示的数据可以在程序执行过程中进行改变,变量一旦改变就使用改变后的值。 变量的使用: 1.变量的声明:指明变量的名称及所属的数据类型。基本语法:数据类型 变量名; 2.变量的赋值,把一份数据指定给某个变量去表示,赋值可以改变变量的值。基本语法:变量名=值; 规范:JAVA语言是“强类型的语言”,它要求变量必须具有明确的数据类型,主要是因为在编译期需要给变量精确的分配内存,也需要确定表达式的精确的结果类型等。 数据类型:就是对程序中所使用数据的分类,数据就是用来标示信息的。作为信息的描述来看,不同种类的信息表达方式是不同的,比如人的 名称应归类为 字符串,比如菜的重量归类为小数,人的年龄应归类为正数等。 Java的数据类型分为两大类: 基本数据类型:包括 整数 、 浮点数 、 字符 、 布尔 。 引用数据类型 有四种:包括 类类型 、 接口类型 、类型变量(泛型) 、数组类型、还有一个特殊的空类型。 null类型,即表达式的类型null,没有名称。 由于空类型没有名称
  • 如何在Pandas的DataFrame中的行上进行迭代(How to iterate over rows in a DataFrame in Pandas)
    问题 我有一个来自Pandas的DataFrame : import pandas as pd inp = [{'c1':10, 'c2':100}, {'c1':11,'c2':110}, {'c1':12,'c2':120}] df = pd.DataFrame(inp) print df 输出: c1 c2 0 10 100 1 11 110 2 12 120 现在,我要遍历该框架的行。 对于每一行,我希望能够通过列名访问其元素(单元格中的值)。 例如: for row in df.rows: print row['c1'], row['c2'] 在熊猫市有可能做到这一点吗? 我发现了这个类似的问题。 但这并不能给我我所需要的答案。 例如,建议在那里使用: for date, row in df.T.iteritems(): 或者 for row in df.iterrows(): 但是我不明白什么是row对象以及如何使用它。 回答1 DataFrame.iterrows是一个生成器,它同时生成索引和行(作为系列): import pandas as pd df = pd.DataFrame({'c1': [10, 11, 12], 'c2': [100, 110, 120]}) for index, row in df.iterrows(): print(row['c1']
  • 如何建立具有依存类型的长度的清单?(How do I build a list with a dependently-typed length?)
    问题 将脚趾浸入依赖类型的水域中,我在规范的“具有静态类型长度的列表”示例中遇到了裂缝。 {-# LANGUAGE DataKinds, GADTs, KindSignatures #-} -- a kind declaration data Nat = Z | S Nat data SafeList :: (Nat -> * -> *) where Nil :: SafeList Z a Cons :: a -> SafeList n a -> SafeList (S n) a -- the type signature ensures that the input list has at least one element safeHead :: SafeList (S n) a -> a safeHead (Cons x xs) = x 这似乎可行: ghci> :t Cons 5 (Cons 3 Nil) Cons 5 (Cons 3 Nil) :: Num a => SafeList ('S ('S 'Z)) a ghci> safeHead (Cons 'x' (Cons 'c' Nil)) 'x' ghci> safeHead Nil Couldn't match type 'Z with 'S n0 Expected type: SafeList ('S n0)
  • 编程语言类型的强弱只是一个形容词,怎能用来对编程语言进行分类
    最近和网友讨论Python到底是强类型,还是弱类型的问题。我还特意写了篇文章《谁告诉的你们Python是强类型语言!站出来,保证不打你!》的文章来论述这个问题。有网友写了另外一篇文章《Python到底是强类型语言,还是弱类型语言?》来驳斥了我的观点。这篇文章我仔细阅读了一下。先不讨论文章的观点是否正确。我先来给出一些文章的片段。 上面截取了《Python到底是强类型语言,还是弱类型语言?》的5段内容。其实这5段内容从文字表达和逻辑上并没有什么问题。其基本中心思想就是:隐式类型转换是判断语言强弱类型的主要标准之一。但并不能认为强类型语言就没有隐式类型转换,部分强类型语言很可能有一些合理的隐式类型转换。 先不管这个结论正确与否,先看第1段、第4段和第5段用红框括起来的内容,这里用了一些词:非常多、非常复杂、非常过分、合理、很少。当然,这些词大家都理解是什么意思,都是一些强调程度的形容词。不过将这些词用在计算机科学中就不太好了。请作者解释下,啥叫非常多、非常复杂、非常过分、合理、很少。要达到什么程度才算是非常多和复杂呢?恐怕100个人就会有100个看法。你说JavaScript用了非常过分的方式进行类型转换,但我认为不过分,这些都只是一种语言应该做的正常行为。例如,"1000" - 1,这个不应该将"1000"转换为1000,然后再与1相减吗? 这才符合人们的认知啊。Java之所以不支持
  • 初始C语言
    C语言概述: 计算机编程语言,应用于底层开发。简易的方式编译,处理地基存储器,产生少量的机器码,不需要任何运行环境支持便能运行的编程语言。良好的跨平台性。是一门面向过程的编程语言。 数据类型 char //字符数据类型 1字节 short //短整型 2字节 int //整型 4字节 long //长整型 4字节 long long //更长的整型 8个字节 float //单精度浮点数 4字节 double //双精度浮点数 8字节 ``注:`存在这么多类型为了更加丰富的表达生活中的值。 变量,常量 常量:不可变的值。 变量:变化的值 变量的分类 全局变量局部变量 注:当全局变量和局部变量同名的时候,局部变量优先使用。 变量的作用域和生命周期 作用域:限定的可用性的代码范围。 (1) 局部变量的作用域是变量所在的局部范围。 (2) 全局变量的作用域是整个工程。生命周期: 变量的生命周期是指变量的创建到变量的销毁的一个时间段 (1) 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。 (2) 全局变量的生命周期是:整个程序的生命周期。 变量的定义 定义变量:分两步: 1:开辟空间 int a;//内存空间就开辟好了 2: 写入对应的数据 a=100; 初始化:空间开辟好,里面的数据与生俱来是某个值 int a = 100; //初始化 赋值:第二次进行主动赋值 a
  • 没有空值的语言的最佳解释(Best explanation for languages without null)
    问题 程序员经常抱怨空错误/异常时,有人会问我们在没有空的情况下该怎么做。 我对选项类型的简洁性有一些基本的想法,但是我没有知识或语言技巧来最好地表达它。 对于以下内容,如何以普通程序员可以接近的方式做出很好的解释,我们可以向该人员指出? 默认情况下,不希望引用/指针为空选项类型如何工作,包括简化检查空值情况的策略,例如模式匹配和一元理解替代解决方案,例如吃零信息 (我错过了其他方面) 回答1 我认为为什么null是不可取的简洁总结是,无意义的状态不应该可表示。 假设我正在建模一扇门。 它可以处于以下三种状态之一:打开,关闭但未锁定以及关闭和锁定。 现在我可以按照 class Door private bool isShut private bool isLocked 很明显,如何将我的三个状态映射到这两个布尔变量中。 但这留下了第四个不希望的状态: isShut==false && isLocked==true 。 因为我选择的表示形式的类型承认这种状态,所以我必须花大力气确保类永远不会进入这种状态(也许通过显式编码不变式)。 相反,如果我使用的语言具有代数数据类型或经过检查的枚举,则可以定义 type DoorState = | Open | ShutAndUnlocked | ShutAndLocked 然后我可以定义 class Door private DoorState
  • 2021年最新java面试题和答案
        欢迎大家搜索“小猴子的技术笔记”关注我的公众号,后台回复“面试题PDF”领取30页更多面试题和答案 什么是线程局部变量? 线程局部变量是局限于线程内部的变量,属于线程自身所有,不在多个线程间共享。Java 提供 ThreadLocal 类来支持线程局部变量,是一种实现线程安全的方式。但是在管理环境下(如 web 服务器)使用线程局部变量的时候要特别小心,在这种情况下,工作线程的生命周期比任何应用变量的生命周期都要长。任何线程局部变量一旦在工作完成后没有释放,Java 应用就存在内存泄露的风险。 JDK 1.8特性 java 8 在 Java 历史上是一个开创新的版本,下面 JDK 8 中 5 个主要的特性: 1.Lambda 表达式,允许像对象一样传递匿名函数 2.Stream API,充分利用现代多核 CPU,可以写出很简洁的代码 3.Date 与 Time API,最终,有一个稳定、简单的日期和时间库可供你使用 4.扩展方法,现在,接口中可以有静态、默认方法。 5.重复注解,现在你可以将相同的注解在同一类型上使用多次。 Serial 与 Parallel GC之间的不同之处? Serial 与 Parallel 在GC执行的时候都会引起 stop-the-world。它们之间主要不同 serial 收集器是默认的复制收集器,执行 GC 的时候只有一个线程,而
  • Java转换规则(Java rules for casting)
    问题 什么时候可以将某个对象投射到另一个对象中? 强制转换的对象是否必须是另一个对象的子类型? 我正在尝试弄清楚规则... 编辑:我意识到我根本没有解释我的问题:基本上我正在将对象转换为接口类型。 但是,在运行时,我得到了一个java.lang.ClassCastException 。 我的对象需要做什么,以便可以将其投射到此接口? 它必须执行吗? 谢谢 回答1 在Java中,引用变量转换有两种类型: 向下转换:如果具有引用子类型对象的引用变量,则可以将其分配给子类型的引用变量。 您必须进行显式转换才能执行此操作,结果是可以使用此新引用变量访问子类型的成员。 向上转换:您可以显式或隐式地将引用变量分配给超类型引用变量。 这是一种本质安全的操作,因为分配限制了新变量的访问能力。 是的,您需要直接或间接实现接口,以将您的类对象引用分配给接口类型。 回答2 假设我们要将d对象强制转换为A, a a =(C)d; 因此,在内部,编译器和JVM检查了3条规则。 编译器在编译时检查前两个规则,而JVM将在运行时检查后一个规则。 规则1(编译时间检查): 'd'和C的类型必须具有某种关系(子代与父代或父代与子代或同一时间)。如果没有关系,我们将得到一个编译错误(不可转换类型)。 规则2(编译时间检查): “ C”必须是“ A”的相同类型或派生类型(子类),否则我们将得到编译错误(不兼容类型)。
  • 需要对 C 中的铸造进行一些说明(Need some clarification regarding casting in C)
    问题 我只是在阅读有关强制转换malloc返回值的不良做法。 如果我理解正确,那么将演员表保留为隐式完成是绝对合法的(并且应该保留,因为它可能会产生其他问题)。 那么我的问题是,我应该什么时候转换我的价值观? 有什么一般规则吗? 例如,此代码使用gcc -W -Wall编译时没有任何错误(未使用的bar除外,但这不是重点): float foo(void) { double bar = 4.2; return bar; } int main(void) { double bar = foo(); return 0; } 我现在很困惑。 关于铸造的良好做法和规则是什么? 谢谢。 回答1 有几种情况需要在 C 中完全有效的强制转换。当心像“强制转换总是糟糕的设计”之类的全面断言,因为它们显然是假的。 严重依赖强制转换的一大类情况是算术运算。 在需要强制编译器解释不同于“默认”类型的算术表达式的情况下,需要进行转换。 如 unsigned i = ...; unsigned long s = (unsigned long) i * i; 以免溢出。 或者在 double d = (double) i / 5; 为了使编译器切换到浮点除法。 或者在 s = (unsigned) d * 3 + i; 以取整部分浮点值。 依此类推(示例无穷无尽)。 另一组有效用途是习语,即完善的编码实践。
  • 2021年JAVA面试题及答案解析,精选133道题轻松搞定大厂面试官
    前言最近针对互联网公司面试问到的知识点,总结出了Java程序员面试涉及到的绝大部分面试题及答案分享给大家,希望能帮助到你面试前的复习且找到一个好的工作,也节省你在网上搜索资料的时间来学习。内容涵盖:Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、Redis、MySQL、Spring、SpringBoot、SpringCloud、RabbitMQ、Kafka、Linux等技术栈。完整版Java面试题地址:JAVA后端面试题整合 作者:超实用小文章链接:https://juejin.cn/post/6952434860753584165/来源:掘金著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 1、Java 中能创建 volatile 数组吗? 能,Java 中可以创建 volatile 类型数组,不过只是一个指向数组的引用,而不是整个数组。我的意思是,如果改变引用指向的数组,将会受到 volatile 的保护,但是如果多个线程同时改变数组的元素,volatile 标示符就不能起到之前的保护作用了。 2、volatile 能使得一个非原子操作变成原子操作吗? 一个典型的例子是在类中有一个 long 类型的成员变量。如果你知道该成员变量会被多个线程访问,如计数器、价格等,你最好是将其设置为 volatile。
  • Java Lambda表达式,转换和比较器(Java lambda expressions, casting, and Comparators)
    问题 我正在查看Map接口的Java源代码,并遇到了以下这段代码: /** * Returns a comparator that compares {@link Map.Entry} in natural order on value. * * <p>The returned comparator is serializable and throws {@link * NullPointerException} when comparing an entry with null values. * * @param <K> the type of the map keys * @param <V> the {@link Comparable} type of the map values * @return a comparator that compares {@link Map.Entry} in natural order on value. * @see Comparable * @since 1.8 */ public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() { return (Comparator<Map.Entry<K, V>>
  • 良好而简单的随机性度量(A Good and SIMPLE Measure of Randomness)
    问题 取长整数序列(例如100,000个整数)并返回该序列有多随机的度量的最佳算法是什么? 该函数应返回一个结果,如果序列不是全部都是随机的,则返回0,如果完全随机,则返回1。 如果序列有些随机,则可以在两者之间给出一些信息,例如0.95可能是一个合理的随机序列,而0.50可能具有一些非随机部分和一些随机部分。 如果我要将Pi的前100,000个数字传递给该函数,则它应给出一个非常接近1的数字。如果我将序列1、2,... 100,000传递给该函数,则它应返回0。 这样,我可以轻松地获取30个数字序列,确定每个数字的随机性,并返回有关其相对随机性的信息。 有这样的动物吗? ….. 2019年9月24日更新:Google可能刚刚迎来了量子霸权时代: “据报道,谷歌的量子计算机能够在3分20秒内解决计算问题-证明随机数发生器产生的数字具有随机性,这将使世界上最快的传统超级计算机Summit大约需要10,000年。这实际上意味着传统计算机无法进行这种计算,这使Google成为第一个展示量子至上性的人。” 因此,显然有一种“证明”随机性的算法。 有谁知道它是什么? 这个算法还能提供一种随机性的度量吗? 回答1 您的问题会自行回答。 “如果我将Pi的前100,000个数字传递给该函数,则它应该给出一个非常接近1的数字”,但Pi的数字不是随机数,因此,如果您的算法无法识别出非常具体的序列为非