微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!
经典专题提供经典的最新资讯内容,帮你更好的了解经典。
一个经典实用的iptables shell脚本
PS:这个iptables脚本不错,很实用,根据实际应用改一下就可以自己用。分享出来,供大家来参考。原作者佚名。源代码如下:#!/bin/sh#modprobe ipt_MASQUERADEmodprobe ip_conntrack_ftpmodprobe ip_nat_ftpiptables -Fiptables -t nat -Fiptables -Xiptables -t nat -X###########################INPUT键###################################iptables -P INPUT DROPiptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPTiptables -A INPUT -p tcp -m multiport --dports 110,80,25 -j ACCEPTiptables -A INPUT -p tcp -s 192.168.0.0/24 --dport 139 -j ACCEPT#允许内网samba,smtp,pop3,连接iptables -A INPUT -i eth1 -p udp -m multiport --dports 53 -j ACCEPT#允许dns连接iptables -A INPUT -p tcp --dport 1723 -j ACCEPTiptables -A INPUT -p gre -j ACCEPT#允许外网vpn连接iptables -A INPUT -s 192.186.0.0/24 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPTiptables -A INPUT -i ppp0 -p tcp --syn -m connlimit --connlimit-above 15 -j DROP#为了防止DOS太多连接进来,那么可以允许最多15个初始连接,超过的丢弃iptables -A INPUT -s 192.186.0.0/24 -p tcp --syn -m connlimit --connlimit-above 15 -j DROP#为了防止DOS太多连接进来,那么可以允许最多15个初始连接,超过的丢弃iptables -A INPUT -p icmp -m limit --limit 3/s -j LOG --log-level INFO --log-prefix "ICMP packet IN: "iptables -A INPUT -p icmp -j DROP#禁止icmp通信-ping 不通iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.0.0/24 -j MASQUERADE#内网转发iptables -N syn-floodiptables -A INPUT -p tcp --syn -j syn-floodiptables -I syn-flood -p tcp -m limit --limit 3/s --limit-burst 6 -j RETURNiptables -A syn-flood -j REJECT#防止SYN攻击 轻量#######################FORWARD链###########################iptables -P FORWARD DROPiptables -A FORWARD -p tcp -s 192.168.0.0/24 -m multiport --dports 80,110,21,25,1723 -j ACCEPTiptables -A FORWARD -p udp -s 192.168.0.0/24 --dport 53 -j ACCEPTiptables -A FORWARD -p gre -s 192.168.0.0/24 -j ACCEPTiptables -A FORWARD -p icmp -s 192.168.0.0/24 -j ACCEPT#允许 vpn客户走vpn网络连接外网iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPTiptables -I FORWARD -p udp --dport 53 -m string --string "tencent" -mtime --timestart 8:15 --timestop 12:30 --days Mon,Tue,Wed,Thu,Fri,Sat -j DROP#星期一到星期六的8:00-12:30禁止qq通信iptables -I FORWARD -p udp --dport 53 -m string --string "TENCENT" -mtime --timestart 8:15 --timestop 12:30 --days Mon,Tue,Wed,Thu,Fri,Sat -j DROP#星期一到星期六的8:00-12:30禁止qq通信iptables -I FORWARD -p udp --dport 53 -m string --string "tencent" -mtime --timestart 13:30 --timestop 20:30 --days Mon,Tue,Wed,Thu,Fri,Sat -j DROPiptables -I FORWARD -p udp --dport 53 -m string --string "TENCENT" -mtime --timestart 13:30 --timestop 20:30 --days Mon,Tue,Wed,Thu,Fri,Sat -j DROP#星期一到星期六的13:30-20:30禁止QQ通信iptables -I FORWARD -s 192.168.0.0/24 -m string --string "qq.com" -mtime --timestart 8:15 --timestop 12:30 --days Mon,Tue,Wed,Thu,Fri,Sat -j DROP#星期一到星期六的8:00-12:30禁止qq网页iptables -I FORWARD -s 192.168.0.0/24 -m string --string "qq.com" -mtime --timestart 13:00 --timestop 20:30 --days Mon,Tue,Wed,Thu,Fri,Sat -j DROP#星期一到星期六的13:30-20:30禁止QQ网页iptables -I FORWARD -s 192.168.0.0/24 -m string --string "ay2000.net" -j DROPiptables -I FORWARD -d 192.168.0.0/24 -m string --string "宽频影院" -j DROPiptables -I FORWARD -s 192.168.0.0/24 -m string --string "色情" -j DROPiptables -I FORWARD -p tcp --sport 80 -m string --string "广告" -j DROP#禁止ay2000.net,宽频影院,色情,广告网页连接 !但中文 不是很理想iptables -A FORWARD -m ipp2p --edk --kazaa --bit -j DROPiptables -A FORWARD -p tcp -m ipp2p --ares -j DROPiptables -A FORWARD -p udp -m ipp2p --kazaa -j DROP#禁止BT连接iptables -A FORWARD -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 --connlimit-mask 24#######################################################################sysctl -w net.ipv4.ip_forward=1 &>/dev/null#打开转发#######################################################################sysctl -w net.ipv4.tcp_syncookies=1 &>/dev/null#打开 syncookie (轻量级预防 DOS 攻击)sysctl -w net.ipv4.netfilter.ip_conntrack_tcp_timeout_established=3800 &>/dev/null#设置默认 TCP 连接痴呆时长为 3800 秒(此选项可以大大降低连接数)sysctl -w net.ipv4.ip_conntrack_max=300000 &>/dev/null#设置支持最大连接树为 30W(这个根据你的内存和 iptables 版本来,每个 connection 需要 300 多个字节)#######################################################################iptables -I INPUT -s 192.168.0.50 -j ACCEPTiptables -I FORWARD -s 192.168.0.50 -j ACCEPT#192.168.0.50是我的机子,全部放行!############################完#########################################
10大经典排序算法动图演示,看这篇就够了!配相应代码
排序算法是《数据结构与算法》中最基本的算法之一。排序算法可以分为内部排序和外部排序。内部排序是数据记录在内存中进行排序。而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括:关于时间复杂度:平方阶 (O(n2)) 排序 各类简单排序:直接插入、直接选择和冒泡排序。线性对数阶 (O(nlog2n)) 排序 快速排序、堆排序和归并排序;O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数。 希尔排序线性阶 (O(n)) 排序 基数排序,此外还有桶、箱排序。关于稳定性:稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序。不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序。1. 冒泡排序1.1 算法步骤比较相邻的元素。如果第一个比第二个大,就交换他们两个。对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。针对所有的元素重复以上的步骤,除了最后一个。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。1.2 动画演示1.3 参考代码1 // Java 代码实现2 public class BubbleSort implements IArraySort {34 @Override5 public int[] sort(int[] sourceArray) throws Exception {6 // 对 arr 进行拷贝,不改变参数内容7 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);89 for (int i = 1; i < arr.length; i++) {10 // 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。11 boolean flag = true;1213 for (int j = 0; j < arr.length - i; j++) {14 if (arr[j] > arr[j + 1]) {15 int tmp = arr[j];16 arr[j] = arr[j + 1];17 arr[j + 1] = tmp;1819 flag = false;20 }21 }2223 if (flag) {24 break;25 }26 }27 return arr;28 }29 }2. 选择排序2.1 算法步骤首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。重复第二步,直到所有元素均排序完毕。2.2 动画演示2.3 参考代码1 //Java 代码实现2 public class SelectionSort implements IArraySort {34 @Override5 public int[] sort(int[] sourceArray) throws Exception {6 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);78 // 总共要经过 N-1 轮比较9 for (int i = 0; i < arr.length - 1; i++) {10 int min = i;1112 // 每轮需要比较的次数 N-i13 for (int j = i + 1; j < arr.length; j++) {14 if (arr[j] < arr[min]) {15 // 记录目前能找到的最小值元素的下标16 min = j;17 }18 }1920 // 将找到的最小值和i位置所在的值进行交换21 if (i != min) {22 int tmp = arr[i];23 arr[i] = arr[min];24 arr[min] = tmp;25 }2627 }28 return arr;29 }30 }3. 插入排序3.1 算法步骤将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)3.2 动画演示3.3 参考代码1 //Java 代码实现2 public class InsertSort implements IArraySort {34 @Override5 public int[] sort(int[] sourceArray) throws Exception {6 // 对 arr 进行拷贝,不改变参数内容7 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);89 // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的10 for (int i = 1; i < arr.length; i++) {1112 // 记录要插入的数据13 int tmp = arr[i];1415 // 从已经排序的序列最右边的开始比较,找到比其小的数16 int j = i;17 while (j > 0 && tmp < arr[j - 1]) {18 arr[j] = arr[j - 1];19 j--;20 }2122 // 存在比其小的数,插入23 if (j != i) {24 arr[j] = tmp;25 }2627 }28 return arr;29 }30 }4. 希尔排序4.1 算法步骤选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;按增量序列个数 k,对序列进行 k 趟排序;每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。4.2 动画演示4.3 参考代码1 //Java 代码实现2 public class ShellSort implements IArraySort {34 @Override5 public int[] sort(int[] sourceArray) throws Exception {6 // 对 arr 进行拷贝,不改变参数内容7 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);89 int gap = 1;10 while (gap < arr.length) {11 gap = gap * 3 + 1;12 }1314 while (gap > 0) {15 for (int i = gap; i < arr.length; i++) {16 int tmp = arr[i];17 int j = i - gap;18 while (j >= 0 && arr[j] > tmp) {19 arr[j + gap] = arr[j];20 j -= gap;21 }22 arr[j + gap] = tmp;23 }24 gap = (int) Math.floor(gap / 3);25 }2627 return arr;28 }29 }5. 归并排序5.1 算法步骤申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;设定两个指针,最初位置分别为两个已经排序序列的起始位置;比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;重复步骤 3 直到某一指针达到序列尾;将另一序列剩下的所有元素直接复制到合并序列尾。5.2 动画演示5.3 参考代码1 //Java 代码实现2 public class MergeSort implements IArraySort {3 @Override4 public int[] sort(int[] sourceArray) throws Exception {5 // 对 arr 进行拷贝,不改变参数内容6 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);78 if (arr.length < 2) {9 return arr;10 }11 int middle = (int) Math.floor(arr.length / 2);1213 int[] left = Arrays.copyOfRange(arr, 0, middle);14 int[] right = Arrays.copyOfRange(arr, middle, arr.length);1516 return merge(sort(left), sort(right));17 }1819 protected int[] merge(int[] left, int[] right) {20 int[] result = new int[left.length + right.length];21 int i = 0;22 while (left.length > 0 && right.length > 0) {23 if (left[0] <= right[0]) {24
Java面试经典题:线程池专题
1、什么是线程池线程池的基本思想是一种对象池,在程序启动时就开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。2、使用线程池的好处减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。运用线程池能有效的控制线程最大并发数,可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。对线程进行一些简单的管理,比如:延时执行、定时循环执行的策略等,运用线程池都能进行很好的实现3、线程池的主要组件  一个线程池包括以下四个基本组成部分:线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;工作线程(WorkThread):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。4、ThreadPoolExecutor类讲到线程池,要重点介绍java.uitl.concurrent.ThreadPoolExecutor类,ThreadPoolExecutor线程池中最核心的一个类,ThreadPoolExecutor在JDK中线程池常用类UML类关系图如下: 我们可以通过ThreadPoolExecutor来创建一个线程池 new ThreadPoolExecutor(corePoolSize, maximumPoolSize,keepAliveTime,milliseconds,runnableTaskQueue, threadFactory,handler);1. 创建一个线程池需要输入几个参数corePoolSize(线程池的基本大小):当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数大于线程池基本大小时就不再创建。如果调用了线程池的prestartAllCoreThreads方法,线程池会提前创建并启动所有基本线程。maximumPoolSize(线程池最大大小):线程池允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。值得注意的是如果使用了无界的任务队列这个参数就没什么效果。runnableTaskQueue(任务队列):用于保存等待执行的任务的阻塞队列。ThreadFactory:用于设置创建线程的工厂,可以通过线程工厂给每个创建出来的线程设置更有意义的名字,Debug和定位问题时非常又帮助。RejectedExecutionHandler(拒绝策略):当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。以下是JDK1.5提供的四种策略。n AbortPolicy:直接抛出异常。keepAliveTime(线程活动保持时间):线程池的工作线程空闲后,保持存活的时间。所以如果任务很多,并且每个任务执行的时间比较短,可以调大这个时间,提高线程的利用率。TimeUnit(线程活动保持时间的单位):可选的单位有天(DAYS),小时(HOURS),分钟(MINUTES),毫秒(MILLISECONDS),微秒(MICROSECONDS, 千分之一毫秒)和毫微秒(NANOSECONDS, 千分之一微秒)。2. 向线程池提交任务我们可以通过execute()或submit()两个方法向线程池提交任务,不过它们有所不同execute()方法没有返回值,所以无法判断任务知否被线程池执行成功threadsPool.execute(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stub}});submit()方法返回一个future,那么我们可以通过这个future来判断任务是否执行成功,通过future的get方法来获取返回值try {Object s = future.get();} catch (InterruptedException e) {// 处理中断异常} catch (ExecutionException e) {// 处理无法执行任务异常} finally {// 关闭线程池executor.shutdown();}3. 线程池的关闭我们可以通过shutdown()或shutdownNow()方法来关闭线程池,不过它们也有所不同shutdown的原理是只是将线程池的状态设置成SHUTDOWN状态,然后中断所有没有正在执行任务的线程。shutdownNow的原理是遍历线程池中的工作线程,然后逐个调用线程的interrupt方法来中断线程,所以无法响应中断的任务可能永远无法终止。shutdownNow会首先将线程池的状态设置成STOP,然后尝试停止所有的正在执行或暂停任务的线程,并返回等待执行任务的列表。4. ThreadPoolExecutor执行的策略  线程数量未达到corePoolSize,则新建一个线程(核心线程)执行任务线程数量达到了corePools,则将任务移入队列等待队列已满,新建线程(非核心线程)执行任务队列已满,总线程数又达到了maximumPoolSize,就会由(RejectedExecutionHandler)抛出异常新建线程 -> 达到核心数 -> 加入队列 -> 新建线程(非核心) -> 达到最大数 -> 触发拒绝策略5. 四种拒绝策略AbortPolicy:不执行新任务,直接抛出异常,提示线程池已满,线程池默认策略DiscardPolicy:不执行新任务,也不抛出异常,基本上为静默模式。DisCardOldSetPolicy:将消息队列中的第一个任务替换为当前新进来的任务执行CallerRunPolicy:拒绝新任务进入,如果该线程池还没有被关闭,那么这个新的任务在执行线程中被调用)5、Java通过Executors提供四种线程池CachedThreadPool():可缓存线程池。线程数无限制有空闲线程则复用空闲线程,若无空闲线程则新建线程 一定程序减少频繁创建/销毁线程,减少系统开销FixedThreadPool():定长线程池。可控制线程最大并发数(同时执行的线程数)超出的线程会在队列中等待ScheduledThreadPool():定时线程池。支持定时及周期性任务执行。SingleThreadExecutor():单线程化的线程池。有且仅有一个工作线程执行任务所有任务按照指定顺序执行,即遵循队列的入队出队规则1. newCachedThreadPoolnewCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程 public class ThreadPoolExecutorTest1 {public static void main(String[] args) {ExecutorService cachedThreadPool = Executors.newCachedThreadPool();for (int i = 0; i < 1000; i++) {final int index = i;try {Thread.sleep(index * 1000);} catch (Exception e) {e.printStackTrace();}cachedThreadPool.execute(new Runnable() {public void run() {System.out.println(Thread.currentThread().getName()+":"+index);}});}}} 2. newFixedThreadPoolnewFixedThreadPool创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待,指定线程池中的线程数量和最大线程数量一样,也就线程数量固定不变示例代码如下public class ThreadPoolExecutorTest {public static void main(String[] args) {ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);// 每隔两秒打印3个数for (int i = 0; i < 10; i++) {final int index = i;fixedThreadPool.execute(new Runnable() {public void run() {try {System.out.println(Thread.currentThread().getName()+":"+index);//三个线程并发Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}});}}} 3. newscheduledThreadPoolnewscheduledThreadPool创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下.表示延迟1秒后每3秒执行一次public class ThreadPoolExecutorTest3 {public static void main(String[] args) {ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);scheduledThreadPool.scheduleAtFixedRate(new Runnable() {public void run() {System.out.println(Thread.currentThread().getName() + ": delay 1 seconds, and excute every 3 seconds");}}, 1, 3, TimeUnit.SECONDS);// 表示延迟1秒后每3秒执行一次}}  4. newSingleThreadExecutornewSingleThreadExecutor创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行public class ThreadPoolExecutorTest4 {public static void main(String[] args) {ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();for (int i = 0; i < 10; i++) {final int index = i;singleThreadExecutor.execute(new Runnable() {public void run() {try {System.out.println(Thread.currentThread().getName() + ":" + index);Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});}}}结果依次输出,相当于顺序执行各个任务。使用JDK自带的监控工具来监控我们创建的线程数量,运行一个不终止的线程