这几天开始刷面试题了,发现不记录一下根本不行,有很多细小的东西需要复习。首先就来记录一下我看到的一些面试题,不限于机器学习领域,但是是真实的面试机器学习工程师时遇到的问题,今天就来解决:
十分钟内,恶意IP访问检测(累计访问1024次)
理解题意:
- 十分钟内,这个十分钟是动态的。可以说这个十分钟是一个滑片,动态后移的。
- 怎么检测?没有具体的环境的话,先给一个提示,说这个是恶意ip。
- 累计访问1024次什么意思?从现在要统计的时间,往前推十分钟,在这十分钟之内,同一个ip出现的总次数,就是累计访问的次数。如果这个次数大于1024,则判定此ip为恶意访问。
解题思路:
- 对于同一个ip来说,把其访问的时间存入一个list中,为了便于查找动态的十分钟。
- 会有很多的ip来访问服务器,所以将ip和它对应的list存入一个HashMap中,为了快速索引想要的ip。
- 循环一个ip的list,找到第一个大于或等于十分钟之前的时间。比如现在的时间是15:12,十分钟之前为15:02,那么就在list中找到第一个大于或等于15:02的时间,记下这个时间的index。比如index=5
- 获取你上一步循环的list的size,减去上一步得到的index,得到十分钟之内累计的次数count。
- 用count与1024比较,如果大于1024,则为恶意ip。
代码实现:
- 用到了两个数据结构,List和HashMap,上一步有说具体存储什么。
- 用两个线程模拟了两个ip的恶意访问。
Thread1.java:
import java.util.HashMap;
import java.util.Map;
public class Thread1 {
public static Map map = new HashMap();
public static void main(String[] args) {
new Threadip("b", ).start();
new Threadip("h", ).start();
}
}
Threadip.java
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Threadip extends Thread {
private final long sleepMillis;
private String ip;
private List DateList = new ArrayList();
public Threadip(String ip, long sleepMillis) {
this.ip = ip;
this.sleepMillis = sleepMillis;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
detect();
DateList.add(new Date().getTime());
Thread1.map.put(ip, DateList);
System.out.println("ip:" + ip + "访问,访问总次数:" + ((List) Thread1.map.get(ip)).size());
}
}
private void detect() {
int index = ;
if (Thread1.map.get(ip) == null) {
// Thread1.map.put(ip, DateList);
return;
}
List list = (List) Thread1.map.get(ip);
for (int i = ; i < list.size(); i++) {
if ((long) list.get(i) > new Date().getTime() - * * ) {
index = i;
break;
}
}
if (list.size() - index + > ) {
System.out.printf("========恶意ip访问============" + ip);
}
}
}
遇到的问题&总结
- 在起两个线程的时候,让它们睡眠时间一样的话,会出现一个线程一直占用CPU资源,而另一个无法运行的情况。这是因为两个线程随机运行,运行一个时,由于cpu比内存运行地快,另一个内存没有更新,所以在内存中没有出现,导致另一个线程无法运行。
- 解决问题要先理解问题,清楚自己所需要的数据结构,清楚解决问题的步骤。
memoryjdch编辑于2018.1.17