机器学习面试题解1

    这几天开始刷面试题了,发现不记录一下根本不行,有很多细小的东西需要复习。首先就来记录一下我看到的一些面试题,不限于机器学习领域,但是是真实的面试机器学习工程师时遇到的问题,今天就来解决:

十分钟内,恶意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", 300).start();
        new Threadip("h", 400).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(300);
            } 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 = 0;
        if (Thread1.map.get(ip) == null) {
            // Thread1.map.put(ip, DateList);
            return;
        }
        List list = (List) Thread1.map.get(ip);
        for (int i = 0; i < list.size(); i++) {
            if ((long) list.get(i) > new Date().getTime() - 10 * 60 * 1000) {
                index = i;
                break;
            }
        }
        if (list.size() - index + 1 > 1024) {
            System.out.printf("========恶意ip访问============" + ip);
        }
    }
}

遇到的问题&总结

  • 在起两个线程的时候,让它们睡眠时间一样的话,会出现一个线程一直占用CPU资源,而另一个无法运行的情况。这是因为两个线程随机运行,运行一个时,由于cpu比内存运行地快,另一个内存没有更新,所以在内存中没有出现,导致另一个线程无法运行。
  • 解决问题要先理解问题,清楚自己所需要的数据结构,清楚解决问题的步骤。

                                                           memoryjdch编辑于2018.1.17
    

你可能感兴趣的:(机器学习面试)