各种技术&大数据相关

大数据相关题目:

1、相关题目:
https://blog.csdn.net/luanpeng825485697/article/details/79974835
2、海量数据查找中位数
比如数是32位的,根据每个整数的二进制前5位,划分为32个桶,把数放进对应桶中。如果该桶放不下,继续划分,直至内存可以放心为止。统计每个桶中元素个数,算出中位数一定出现在哪个桶中,而且计算出是该桶中的第几大。

virusTotal

1、简化流程、先获取应用的sha1,然后上传sha1,如果之前有人检测过该应用,便会直接返回检测结果,如果结果为空,便把应用进行上传。
2、添加对结果的判断,之前是有检测结果便直接返回。我对检测结果进行判断,如果时间超过1年,便重新上传应用,获取新的检测结果。

项目总体介绍

我在实验室的工作其实都围绕着一个东西:分布式的任务管理平台。其中包括刚入实验室旧平台的维护、以及研二时期新平台的设计与实现。

先解释什么是分布式任务管理平台,我们实验室的一大特色就是拥有很多移动应用的检测工具,比方说静态检测、恶意代码检测、病毒检测、动态检测等,这些工具有的使用java写的,有的是用python写的,甚至有的就是个shell脚本,这些工具是分布在不同的机器上(我们称之为节点)。而实验室有这么一个需求,就是需要对外提供一个统一的接口。用户下发检测请求,比方说一个请求中包含了对100个应用进行两种引擎的请求,这个请求就会先发到一个总的调度机器上,在这个机器上分割成200个任务,然后下发到指定的检测机器上去执行,同时也会对任务和每台检测机器进行实时监控。任务管理平台负责的就是这么一个事情。

新平台以spring为框架,主要使用了mybatis、activemq、thrift、线程池、redis、阻塞队列等工具。其中内含四种机制,分别为节点监测机制、任务下发机制、引擎执行机制、结果回收机制。
1、节点监测机制就是调度机器中会开一个thrift服务给所有的检测机器,然后所有的机器会先注册到调度机器上,然后使用quartz框架实时发送心跳信息给调度机器,心跳信息既包含了cpu、内存、JVM内存这一类系统状态,也包含了检测执行的实时情况、内部剩余的任务数等,这些最终都是可以提供给用户的。

2、 任务下发机制:
首先调度机器上还会开启一个thrift服务给用户层(加上上一个一共开了两个服务),用户下发的总请求后,会切割成多个(比方说200个)任务,然后发给任务缓存模块,任务缓存模块把任务放到redis缓存池中。
然后刚刚也讲到节点监测机制会不停地收到所有检测机器的心跳信息,实际上它会根据心跳信息判断这个心跳对应的机器是不是需要新任务了,如果是的话就会向任务缓存模块。。。,然后由一个多线程的引擎执行模块来从队列中取任务进行执行。这就是整个任务下发机制的流程。也是该平台的核心功能。

我个人认为的有亮点的工作:

  1. 任务接收模块中,因为切割成task相对而言是比较耗时的,所以用户总入口处可能会有压力,因此在入口处只把mission切割成job,因为job数很少,所以这一步很快,然后将job丢到一个阻塞队列JobQueue中,然后再开启一个多线程消费者jobConsumer来接受job,然后各自将task进行切割,这样就通过异步操作以及多线程来减轻入口处的压力。
  2. redis缓存池的设计,redis池内部是以任务种类来分区域,每个区域的结构我是参考了作业调度中的多级反馈队列,因为task有五个优先级,所以有五个队列。同时,在项目实施的过程中我发现绝大多数task都在第三条队列中,这样的话每次获取task都得向redis发送三次连接。所以在任务缓存模块中我用了AtomicInteger每条队列的任务数以及缓存池的总任务数进行了统计,这样可以直接在内存中进行判断,不需要向redis发送多余的请求。
  3. node中为什么要设置一个等待队列,因为下载文件是需要时间的,如果不设置这个队列的话,下载的时间就行串行的,而实际上这部分时间造成的损耗是不能忽略的。因此在接受的时候先对其进行下载,然后将下载的任务放到队列中。

2、引擎执行机制:实际上就是获取task其中的部分参数,将其封装成windows或linux执行的命令行,然后调用processBuilder.start方法来执行引擎(jar包或python)。于此同时,其内置了引擎监测模块来实现对引擎执行状态的监控,实时监控引擎处在执行中、中断还是运行结束状态,同时也可以在超时之后主动中断这次任务的执行。
3、结果回收机制:刚刚说到,通过引擎执行机制可以知道引擎的运行状态,因此无论引擎执行成功或失败,node都会将失败或成功结果反馈给taskmanager,taskmanager的结果回收模块会把成功结果传到redis结果池中,失败任务丢到redis任务池中进行失败回滚。同时,还有一个结果统计模块,会统计每个结点执行任务的成功率,如果成功率低于设定值,将认为该节点“已损坏”,不再对该节点下发任务,也会统计每个任务执行的失败次数,当一个任务失败三次后,会丢弃该任务。

遇到的困难:
最大的问题在于我是自学的spring,是看了黑马的网课,那个时候整个实验室只有我一个学了spring,并且我也只是学了个皮毛,所以刚开始用spring写平台的时候会出现很多困惑,然后也没人能询问,就只能不停地查百度,或者自己一点一点去试:

  • 就比方说依赖注入,之前网课上学的是用ssm框架,就是service层autowire 了dao层,controller层autowire了service,然后开启tomcat服务器然后在前端调用就行了。
  • 问题在于:这个平台是没有前端的,也就是没有controller层,就不能autoWire Service层,并且线程池需要存放线程,而线程是需要new出来的,那么线程里面就不好注入东西,就类似这些东西,一开始写的时候弄的很迷糊,后来也是自己一点一点试出来解决方法的。
  • 解决方法:在一个start.java中,用applicationContext.getBean获得线程池和thrift接口,然后开启thrift服务和线程池,这样就能保证所有东西都在一个spring容器中。

困难2:activemq和spring的整合。

Pc应用检测

我在实验室主要负责的工作是任务管理平台的维护和设计,我刚来实验室的时候,前几任师姐已经写好了关于移动应用的任务管理平台,因此我刚来的时候主要任务便是学习平台所用到的activemq、thrift、mybatis等工具。后来便参与到了pc检测的项目中以及广州的项目中,主要工作是学会整套平台的代码并参与到项目的改造中。

扫描二维码关注公众号,回复: 6195431 查看本文章

我来实验室的时候pc检测这个项目刚刚开始,项目初期主要将移动的任务管理平台进行改造,改造成pc应用的任务管理平台,因为当时刚进实验室没多久,业务方面不是很熟,所以主流程的改造工作是我的师姐完成的,我所负责的是编写前端与后端交互的接口,也就是对数据库和mongodb进行,将结果返回给前端。

Linux

https://note.youdao.com/ynoteshare1/index.html?id=7d073d849ae46be7f44fe31c7eed3fdc&type=note#/
1、文件:cd ls ll cp rm mv
2、查看:
cat a.txt
head -100/-f a.txt
tail -100/-f a.txt
3、文件搜索:
从/home/下搜索a.txt:find /home/ -name a.txt
从/home/下搜索属于user1的文件和目录 find /home/ -user user1
从/home/下查找大于50M的文件 find /home/ -size +50M
4、权限:
chmod 777 a.txt : 所有人(u)-群组(g)-其他人(o),读(r4)-写(w2)-执行(x1)
chown user1 file1:改变文件的用户
5、文本处理:
在文件 ‘/home/a.txt’中查找关键词"text" :grep text /home/a.txt
在目录’/home/'中查找关键词"text" :grep -r text /home/
在目录 '/home/'中查找以"text"开头的关键词: grep -r ^text /home/
在目录 '/home/'中查找带有数字的行:grep -r [0-9] /home/
将example.txt文件中的 “123” 替换成 “456” :sed -i ‘s/123/456/g’ example.txt (-i表示在文件上改,g表示替换所有,不加g则只替换第一个)

socket

https://www.jianshu.com/p/089fb79e308b

项目中为什么使用rpc,而不是直接使用HTTP

1、项目的需要给不同语言的引擎接口,thrift支持跨语言。
2、rpc让使用者不需要知道底层的细节,就像调用一个正常的本地方法一样
3、rpc自定义tcp协议,相较于HTTP1.x而言,rpc传输的报文经过了封装0,极大地精简了传输内容。

RPC和thrift

因为本人在实验室所负责的任务管理系统有使用thrift技术,所以对RPC还是比较了解的。
RPC (Remote Procedure Call):即远程过程调用。它允许程序调用另一台机器上的函数,并且不需要知道底层通信和具体函数是怎么实现的。
个人理解:就相当于一个人点一道菜,调用厨房的炒菜函数,获得返回值(具体的菜),但它并不需要知道菜是怎么炒的。

RPC与JMS

RPC是调用方法,JMS是A向B发送消息。因此RPC是同步的,JMS可以是异步的。

thrift的通信原理:

Thrift 的传输体系包括协议层(protocol)和传输层(transport)
协议层:定义数据传输格式,有TBinaryProtocol,TJSONProtocol等。
传输层:使用什么方式进行传输,例如TSocket(最常见),TFramedTransport等。
在这里插入图片描述
在这里插入图片描述

thrift编写客户端和服务端的步骤:

  1. 编写xxx.thrift
namespace java com.xxx
namespace py xxx

struct Food{
    1:string name,
    2:i32 price
}

service FoodService{
	Food cook(
		1:string name
	)
}
  1. 生成java代码,放入服务端,服务端编写代码实现,然后开启服务。
  2. 将代码放入客户端,调用接口获得返回i结果。

HDFS的概念

  • 是一个分布式的文件系统。
  • HDFS中的文件在物理上是分块存储(block),默认是128M
  • 分为NameNode(存储系统元数据)和DataNode(存储文件数据块)
  • 文件会切成若干块后分布式存储在若干台datanode上
  • 适合用来做数据分析,并不适合用来做网盘应用,因为,不便修改,延迟大,网络开销大,成本太高
    写原理:
    在这里插入图片描述
    读原理:
    在这里插入图片描述

map-reduce

并发问题的解决思路

  1. 如何保证并发的多个相同退款请求只被处理一次?
    Redis存储查询轻量快速。在request进来的时候,可以先记录在缓存中。后续进来的request每次进行验证。整个流程处理完成,清除缓存。以退款为例子:

    I. 每次退款发起申请,读取缓存中是否有以orderId为key的值
    II. 没有,则往缓存中写入以orderId为key的value
    III.有,则说明有该订单的退款正在进行。
    IV. 操作完清缓存,或者缓存存值的时候设置生命周期

MongoDB

1、为什么使用mongo?

  • 可以存储json文件和二进制数据
  • 同时有类似sql的查询功能,可以快速获取需要的数据。

2、缺点:很吃内存,最简单的解决办法是重启服务。

3、java操作mongo

  • 获取一个集合:(集合可以实现增删查改各种操作)
    DBCollection coll = db.getCollection(“mycol”);
  • 插入文档
        BasicDBObject obj = new BasicDBObject();
        obj.put("name", "user28");
        obj.put("age", 30);
        obj.put("sex", 1);
        collection.insert(obj);
  • 获取文档:
DBCollection coll= MongodbConnFactory.getCollection("pc.clamav.result");
DBObject query = new BasicDBObject("md5", "7488936487b7b2d67ab5850cce2acafd");
DBObject dbObj = coll.findOne(query);
  • 获取文档中的数据:(转化成json再用fastjson取)

4、mongo自带查询语句:

  1. #查询某列非重复的记录
    db.foo.distinct(“xingoo”) ---- select distinct name from foo
  2. #查询age = 22 的记录
    db.foo.find({“age”:22}) ---- select * from foo where age = 22
  3. #查询age > 22 的记录
    db.foo.find({age:{$gt:22}}) ---- select * from foo where age > 22
  4. #查询name中包含xingoo的数据
    db.foo.find({name:/xingoo/}) ---- select * from foo where name like ‘%xingoo%’
  5. #查询name中以xingoo开头的数据
    db.foo.find({name:/^xingoo/}) ---- select * from foo where name like ‘xingoo%’
  6. #查询指定列name、age的数据 (个人一般是直接在mongoVUE中有的fileds中输入要查看的列)
    在这里插入图片描述
  7. #按照年龄排序
    同样是在Vue中,在sort里面输入:升序{age:1},降序{age:-1}

专利 二次签名:

我们发现,原始APK文件在进行签名之后,会生成META-INF文件夹,该文件夹中包括MANIFEST.MF、CERT.SF、CERT.RSA三个文件,通过跟踪Android系统验签源码发现,验签以上三个文件即可验签APK,但未对META-INF文件夹做自校验处理。因此,我们可以在META-INF中添加二次签名的信息,从而在不影响到APK的自我验签的基础上实现二次签名的过程。
在这里插入图片描述

秒杀系统

前端:秒杀页面设置成静态化,不用访问数据库。
网关:限制相同用户的访问频率。
服务层:

  1. 使用消息队列或者redis队列来异步操作:用户请求后直接返回,然后将请求放入队列中,再开启多线程从队列中取出请求,再对数据库层操作。
  2. 对于读多血少的系统(例如12306),可以设置一个redis缓存,查询商品时先查询redis,redis没有再查询数据库。(可能会导致缓存穿透和缓存雪崩)
    数据库层:无

https://blog.csdn.net/zxc456733/article/details/78864986

猜你喜欢

转载自blog.csdn.net/bintoYu/article/details/86773168