使用spark,有时我需要在每个任务中发送一个不可序列化的对象.
常见的模式是@transient lazy val
,例如
class A(val a: Int)
def compute(rdd: RDD[Int]) = {
// lazy val instance = {
@transient lazy val instance = {
println("in lazy object")
new A(1)
}
val res = rdd.map(instance.a + _).count()
println(res)
}
compute(sc.makeRDD(1 to 100, 8))
Run Code Online (Sandbox Code Playgroud)
我发现@transient
这里没有必要.lazy val
可以在执行每个任务时创建非序列化.但人们建议使用@transient
.
有什么好处,如果我们在序列化时设置@transient
非初始化lazy val
?
val
为序列化创建一个非初始化瞬态是否有意义,知道没有任何序列化,就像上面的例子一样?
如何@transient lazy val
序列化?它被视为一种方法还是其他什么?
有关序列化@transient lazy val
和编译的java字节码的一些细节非常棒.
serialization scala transient lazy-initialization apache-spark
以下代码让我困惑:
Object[] arr1 = new String[]{"a", "b", "c"};
Object[] arr2 = {"a", "b", "c"};
String[] a = (String[]) arr1; // ok
String[] b = (String[]) arr2; // ClassCastException
System.out.println(arr1.getClass().getName()); // [Ljava.lang.String;
System.out.println(arr2.getClass().getName()); // [Ljava.lang.Object;
Run Code Online (Sandbox Code Playgroud)
我试图理解为什么两个初始化彼此不同.第一个是帖子声明,第二个是捷径.这两个都被宣布为Object[]
我天真的理解是:
Object[] arr2 = {"a", "b", "c"}; // is a syntax sugar of
Object[] arr2 = new Object[] {"a", "b", "c"};
Run Code Online (Sandbox Code Playgroud)
因此运行时类型arr2
正好Object[]
无法转换为String[]
.
但是,事情就变得怪怪的,因为Java数组是协变:
String[]
是的子类Object[]
,并arr2
确切地是String[]
,从后面投射Object[]
到String[]
上arr2
应该工作.
对此的任何解释都非常感谢.
根据scala doc,TypeTag包含的信息比ClassTag更多.在我看来,TypeTag可以比ClassTag做更多的事情,比如将编译时的类型参数信息带到运行时等.
但是,以下示例显示ClassTag可以完成工作,而TypeTag则不能.我想了解原因.
import scala.reflect.ClassTag
import scala.reflect.runtime.universe.TypeTag
// def func[T](o: Any): Unit = {
// def func[T : TypeTag](o: Any): Unit = {
def func[T : ClassTag](o: Any): Unit = {
o match {
case x: T => println(Some(x))
case _ => println(None)
}spark
}
func[Map[Int, Int]](List(1, 2, 3))
Run Code Online (Sandbox Code Playgroud)
只有ClassTag会引导模式匹配None
(这是预期的行为),前两个注释行将提出Some
分支.
似乎ClassType可以在运行时反映对象的类型,而Type Tag则不能.但TypeTag不是ClassTag的超集吗?我想尽可能详细地了解解释.谢谢.
可以编译以下代码而不会出现错误.
val a: Int = 1
val b = a.asInstanceOf[AnyRef]
Run Code Online (Sandbox Code Playgroud)
这让我感到困惑,因为Int扩展了AnyVal,它不是子类,而是AnyRef的兄弟.
但是,如果使用ascription如下:
val a: Int = 1
val b: AnyRef = a
Run Code Online (Sandbox Code Playgroud)
它不起作用.
error: type mismatch;
found : Int
required: AnyRef
Note: an implicit exists from scala.Int => java.lang.Integer, but
methods inherited from Object are rendered ambiguous. This is to avoid
a blanket implicit which would convert any scala.Int to any AnyRef.
You may wish to use a type ascription: `x: java.lang.Integer`.
val b: AnyRef = a
Run Code Online (Sandbox Code Playgroud)
我的理解是:
asInstanceOf
在运行时执行,它迫使编译器相信val …
我想为我的main函数编写一个单元测试,其中有一个 readLine()
循环.
我尝试过以下基于java的.我想readLine()
可能需要System.in
作为inputStream
.但它不起作用.ScalaTest在readLine()
等待输入时被阻止.
"readLine" should "work" in {
val in = new ByteArrayInputStream("abc".getBytes)
System.setIn(in)
readLine() === "tester"
}
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?谢谢.
我试图理解以下代码。
//文件:LambdaTest.java
package test;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
public class LambdaTest implements Ops {
public static void main(String[] args) {
new LambdaTest().job();
}
public void job() {
SparkConf conf = new SparkConf()
.setAppName(LambdaTest.class.getName())
.setMaster("local[*]");
JavaSparkContext jsc = new JavaSparkContext(conf);
List<Integer> lst = Arrays.asList(1, 2, 3, 4, 5, 6);
JavaRDD<Integer> rdd = jsc.parallelize(lst);
Function<Integer, Integer> func1 = (Function<Integer, Integer> & Serializable) x -> x * x;
Function<Integer, Integer> func2 = x …
Run Code Online (Sandbox Code Playgroud) 我正在检查scala代码库.
令我困惑的是Int类:
它是一个final abstract
类,因此子类的所有成员方法都无法实现.此外,所有这些成员方法都是抽象def,没有具体实现.
我无法理解为什么这些抽象方法有效.我在哪里可以找到这些方法的具体定义?
scala ×5
apache-spark ×2
java ×2
casting ×1
inputstream ×1
lambda ×1
mocking ×1
reflection ×1
serializable ×1
transient ×1