面试问题待解决
vector矢量队列,支持添加、删除、修改、遍历等功能 。实现了RandomAccess接口,提供了随机访问功能。可以通过元素的序号快速获取元素对象。
和ArrayList不同,Vector中的操作是线程安全的。
1.vector实际是用数组来保存数据,默认容量大小是10
2.vector容量不足以容纳全部元素时,vector的容量会增加,容量系数>0,则增加相应的容量系数,否则增加一倍大小
3.vector的克隆函数,即是将全部元素克隆到一个数组中。
推荐系统
sparkstreaming调优:
spark.yarn.maxAppAttempts=4 重新运行应用程序的尝试次数
spark.yarn.am.attemptFailuresValidityInterval=1h 应用程序运行数周或更长时间运行,那么每小时重置重试次数是有必要的,否则4次尝试机会将很块被用完。
spark.yarn.max.executor.failures={8 * num_executors}默认情况下是max{2*numexecutors,3}设置executor的最大失败次数,使用于批处理作业,但不适用于长时间运行的作业。该属性配合
相应的有效期间一起使用:spark.yarn.executor.failuresValidityInterval=1h
--queue realtime_queue指定yarn队列,若没有yarn队列,长时间运行的工作迟早要被大量Hive查询抢占。
概念科普:幂等操作---即是用户对同一操作发起的一次请求或多次请求结果是一致的。不会因为多次点击产生了副作用。
推测执行启用条件:只有在spark操作是幂等的情况下,才能启用推测执行。推测执行,启用推测执行时,批处理时间更加稳定。spark.speculation=true
安全管理:将Kerberos主体和keytab作为spark-submit命令传递
--principal user/hostname@domain \ --keytab /path/to/foo.keytab
、
Spark+Kafka的Direct方式将偏移量发送到Zookeeper的实现:
Apache Spark 1.3.0引入了Direct API,使用consumerAPI从kafka集群中读取数据,并且在streaming系统中维护kafka的读偏移量。这种方式相比receiver模式的优点是:实现零数据丢失必Receiver模式更高效一些。
因为streaming系统自己维护kafka的读偏移量,streaming系统没有将此读偏移量发送到zookeeper中,这样会导致kafka集群监控软件(如:KafkaWebConsole,KafkaOffsetMonitor)失效。以下是解决此问题的方案,达到我们编写的streaming程序能够在每次接收到数据之后自动更新zookeeper中kafka的偏移量:
从spark官网了解到,spark内部维护kafka偏移量信息存储在HasOffsetRanges类的offsetRanges中,可以在streaming程序里获取这些信息:
val offsetList=rdd.asInstanceOf[HasOffsetRanges].offsetRanges.这样就可以从offsetList中获取分区消费信息。只需要遍历OffsetsList,然后将这些信息发送到zookeeper即可更新kafka的消费偏移量。完整的代码片段如下:
KafkaUtils.createDirectorStream[String,String,StringDecoder,StringDecoder](ssc,kafkaParams,topicSet){ messages.foreachRDD(rdd=>{ val offsetsList=rdd.asInstanceOf[HasOffsetRanges].offsetRanges val kc=new KafkaCluster(KafkaParams) for(offsets < -offsetsList){ val topicAndPartition=TopicAndPartition("test-topic",offsets.partition) val o=kc.setConsumerOffsets(args(0),Map((topicAndPartion,offsets.untilOffset))) if(o.isLeft){ println(s"Error updating the offset to kafka cluster:${o.left.get}") } } } ) }
KafkaCluster类是用于建立和Kafka集群的连接相关的操作工具类,可以对Kafka的Topic每个分区设置其相应的偏移量Map((topicAndPartition,offsets.untilOffset)).然后调用KafkaCluster类的setConsumerOffsets方法去更新Zookeeper里面的信息。之后就可以更新Kafka的偏移量,再最后我们就可以通过KafkaOffsetMonitor软件去监控Kafka中相应的Topic的信息
ioc---inversion of control,即“控制反转”,是一种设计思想,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。对应Spring来说,就是由Spring来负责控制对象的生命周期和对象间的关系。并由容器来管理对象的生命周期
传统javase是我们直接在对象内部通过new创建对象,是程序主动创建依赖对象,Ioc有专门的一个容器来管理这些对象,即由ioc来控制对象的创建,主要控制了外部资源获取(不止对象也包括文件)。
传统应用程序有我们自己在对象中主动控制直接获取依赖对象,也就是正转。反转是由容器来帮忙创建及注入依赖对象。因为是容器帮助我们查找及注入依赖对象,对象只是被动接收依赖对象,所以是反转,以前是对象控制其他对象,现在是对象都被Spring控制,所以是反转。
在IOC/DI思想里:应用程序被动地等待IOC容器创建并注入它所需要的资源。
DI---DependencyInjection,通过反射来实现的注入 ,组件之间的依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系,注入到组件中,目的是提高组件的重用效率。
谁依赖谁:应用程序依赖IOC容器
为什么需要依赖:应用程序需要容器提供的对象的外部资源来完成自己的业务逻辑。
谁注入谁:IOC容器注入应用程序某个对象,应用程序需要依赖的对象。
注入了什么:注入了某个对象所需要的外部资源(包括对象,资源,常量数据)。
IOC和DI:是同一个概念的不同角度的描述,IOC描述了容器控制对象,DI描述了被注入对象依赖IOC容器配置依赖对象。
IOC的一个特点是在系统运行中,动态向某个对象它所需要的其他对象,这一点是通过DI来实现的。
AOP(Aspect-Oriented Programming)由java反射实现,是javaOOP的补充和完善,oop由“抽象”、“封装”、“继承”、“多态”。
oop描述了一个事物自上而下的完整关系,具体到细粒度的内部,oop就显的无能为力了,比如日志功能,日志代码往往水平散落在对象层次关系中,与它散布到对象的核心功能毫无关系,其他很多类似功能,如事务管理,权限控制等。这样导致了大量代码的重复使用。不利于模块的重用。AOP技术恰恰相反,它利用一种横切的技术,能够剖解开封装对象的内部,并将那些影响了多个类,
jvm的jconsle.、kafka的webui、spark的webui、spark任务task个数如何计算、连接池种类、jar包冗余、多个工程占用多个连接池的问题。