首页 文章 精选 留言 我的

精选列表

搜索[技能提示],共10006篇文章
优秀的个人博客,低调大师

小企业的数据备份和安全提示

如今,层出不穷的新技术提供了很多创新,但最终使人们的生活依赖于技术。企业必须以各种形式使用技术,例如企业的数据备份。企业需要花费时间才能在对其私有机密数据构成威胁之前进行备份。企业无疑是任何国家经济发展的核心,美国是企业创造一半工作岗位的国家之一。近30年来,近49%的低预算企业正在增长。那么,如何为小企业创建数据备份? 根据研究人员的调查,大多数小企业都没有进行数据备份,几乎达到35%。如果在那些没有采用互联网的情况下,大多数的企业主只有一个备份他们所有的数据的副本。这可能是非常危险的,不要把所有的数据放在一台机器上! 采用异地备份 将企业的业务数据存放在两个不同的地方。 将数据进行备份,另外一个备份保存在安全的异地。 业务需要拥有本地副本。 用户将能够继续依赖原始数据并将其用作主要的访问。 企业应该有一个本地备份,使其可以快速地查找和访问要查找的数据,而不会被删除,丢失和覆盖。 小型企业应该学会安全地将存储文件复制到异地,如果其所在位置或设备出现问题,那么企业的所有设备以及数据可以保持安全。即使在当今世界,人们仍然使用磁带备份与异地备份,现在有很多选择可用于基于云计算的异地备份。 如今,已具有各种云存储形式,在市场上有大量的数据备份软件,如TheOneSpy数据备份工具,Backblaze等等。另一方面,哪一个数据备份应用程序可能是最好的,其中有大量的形式,如手机数据备份软件,Mac和Windows数据备份应用程序。它为用户提供了大量开创性的功能,并且非常人性化。 如何使用数据备份程序? (1)使用数据备份软件 企业主应该使用最好的数据备份软件,并做出正确的选择。将其安装在企业的设备上,如智能手机,计算机和其他设备。一旦安装过程完成,就可以轻松保护数据。企业设备可能会因事故而丢失,被盗或意外损坏或烧毁。然后,企业可以访问数据备份应用程序的控制面板来收集所有数据。所有已经存储的数据或安装手机数据后应用程序后最近存储的数据,都可以在任何时间内轻松检索到。创建一个登录到Windows和Macs数据备份软件的控制面板,然后可以随时随地从世界任何地方收回其数据。 (2)应该备份什么? 企业在业务中保留的所有数据应具有强大的备份。 使用加密措施以保证企业的业务数据是完全安全和健全的。 当企业使用数据备份应用程序时,有必要认识到加密是内置的。 大多数小型企业都依靠Gmail服务来处理他们的电子邮件。 仅在云端可用的数据可能是一个失败,也可能是一个巨大的挫折。 将数据同时放在三个位置,并在本地备份副本。 结论: 小企业需要通过创建数据备份保护数据。而数据备份软件是保护其数据的最佳工具。 作者:佚名 来源:机房360

优秀的个人博客,低调大师

第一章 Java多线程技能

进程和多线程的概念及其优点 进程是操作系统结构的基础,是一次程序的执行;是一个程序及其数据在处理机上顺序执行时所发生的活动;是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。进程是受操作系统管理的基本运行单元。 线程可以理解成是在进程中独立运行的子任务。比如QQ.exe运行时就有很多的子任务在同时运行。再如,好友视频线程、下载文件线程、传输数据线程、发送表情线程等,这些不同的任务或者说功能都可以同时运行,其中每一项任务完全可以理解成是“线程”在工作,传文件、听音乐、发送图片表情等功能都有对应的线程在后台默默地运行。 多线程的优点:可以最大限度的利用CPU的空闲时间来处理其他的任务,而CPU在这些任务之间不停的切换,由于切换的速度非常快,给使用者的感受就是这些任务似乎在同时运行。所以使用多线程技术后,可以在同一时间内运行更多不同种类的任务。 单任务的特点就是排队执行,也就是同步,就像在cmd中输入一条命令后,必须等待这条命令执行完才可以执行下一条命令一样。这就是单任务环境的缺点,即CPU利用率大幅降低。而多线程情况下,CPU完全可以在任务1和任务2之间来回切换,使任务2不必等到10秒再运行,系统的运行效率大大得到提升,这就是多线程技术的优点,使用多线程也就是在使用异步,千万不要把开发环境里代码的顺序当成线程执行的顺序,线程被调用的时机是随机的。 使用多线程 继承Thread 类 在Java 的JDK 开发包中,已经自带了对多线程技术的支持,可以很方便地进行多线程编程。实现多线程编程的方式主要有两种,一种是继承Thread 类,另一种是实现Runnable 接口。 package com.mythread.www; public class MyThread extends Thread { @Override public void run() { super.run(); System.out.println("MyThread"); } } package test; import com.mythread.www.MyThread; public class Run { public static void main(String[] args) { MyThread mythread = new MyThread(); mythread.start(); System.out.println(" 运行结束! "); } } 输出结果 运行结束! MyThread MyThread.java 类中的run 方法执行的时间比较晚,这也说明在使用多线程技术时,代码的运行结果与代码执行顺序或调用顺序是无关的。 实现Runnable 接口 如果欲创建的线程类已经有一个父类了,这时就不能再继承自Thread 类了,因为Java不支持多继承,所以就需要实现Runnable 接口来应对这样的情况。 package myrunnable; public class MyRunnable implements Runnable { @Override public void run() { System.out.println(" 运行中!"); } public static void main(String[] args) { Runnable runnable=new MyRunnable(); Thread thread=new Thread(runnable); thread.start(); System.out.println(" 运行结束!"); } } 输出结果 运行结束! 运行中! 那也就意味着构造函数Thread(Runnable target) 不光可以传入Runnable 接口的对象,还可以传入一个Thread 类的对象,这样做完全可以将一个Thread 对象中的run() 方法交由其他的线程进行调用。 实例变量与线程安全 自定义线程类中的实例变量针对其他线程可以有共享与不共享之分,这在多个线程之间进行交互时是很重要的一个技术点。 不共享数据的情况 public class MyThread extends Thread { private int count = 5; public MyThread(String name) { super(); this.setName(name);// 设置线程名称 } @Override public void run() { super.run(); while (count > 0) { count--; System.out.println(" 由 " + this.currentThread().getName() + " 计算,count=" + count); } } } public class Run { public static void main(String[] args) { MyThread a=new MyThread("A"); MyThread b=new MyThread("B"); MyThread c=new MyThread("C"); a.start(); b.start(); c.start(); } } 一共创建了3 个线程,每个线程都有各自的count 变量,自己减少自己的count 变量的值。这样的情况就是变量不共享,此示例并不存在多个线程访问同一个实例变量的情况。 共享数据的情况就是多个线程可以访问同一个变量,比如在实现投票功能的软件时,多个线程可以同时处理同一个人的票数。 public class MyThread extends Thread { private int count=5; @Override public void run() { super.run(); count--; System.out.println(" 由 "+Thread.currentThread().getName()+" 计算, count="+count); } } public class Run { public static void main(String[] args) { MyThread mythread=new MyThread(); Thread a=new Thread(mythread,"A"); Thread b=new Thread(mythread,"B"); Thread c=new Thread(mythread,"C"); Thread d=new Thread(mythread,"D"); Thread e=new Thread(mythread,"E"); a.start(); b.start(); c.start(); d.start(); e.start(); } } 输出结果 由 B 计算, count=3 由 A 计算, count=3 由 C 计算, count=2 由 D 计算, count=1 由 E 计算, count=0 线程A 和B 打印出的count 值都是3,说明A 和B 同时对count 进行处理,产生了“非线程安全”问题。在某些JVM 中,i-- 的操作要分成如下3 步: 1 取得原有i 值。 2 计算i-1。 3 对i 进行赋值。 在这3 个步骤中,如果有多个线程同时访问,那么一定会出现非线程安全问题。 在这里占不解决同步问题,读者可以自行思考。 留意i-- 与System.out.println() 的异常 本节将通过程序案例细化一下println() 方法与i++ 联合使用时“有可能”出现的另外一种异常情况,并说明其中的原因。 package extthread; public class MyThread extends Thread { private int i = 5; @Override public void run() { System.out.println("i=" + (i--) + " threadName=" + Thread.currentThread().getName()); // 注意:代码i-- 由前面项目中单独一行运行改成在当前项目中在println() 方法中直接进行打印 } } package test; import extthread.MyThread; public class Run { public static void main(String[] args) { MyThread run = new MyThread(); Thread t1 = new Thread(run); Thread t2 = new Thread(run); Thread t3 = new Thread(run); Thread t4 = new Thread(run); Thread t5 = new Thread(run); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); } } 输出结果 i=5 threadName=B i=4 threadName=C i=5 threadName=A i=2 threadName=D i=3 threadName=E 虽然println() 方法在内部是同步的,但i-- 的操作却是在进入println() 之前发生的,所以有发生非线程安全问题的概率。 /** * Prints a String and then terminate the line. This method behaves as * though it invokes <code>{@link #print(String)}</code> and then * <code>{@link #println()}</code>. * * @param x The <code>String</code> to be printed. */ public void println(String x) { synchronized (this) { print(x); newLine(); } } currentThread() currentThread() 方法可返回代码段正在被哪个线程调用的信息。 /** * Created by Lee on 2018/7/25. */ public class MyThread extends Thread { public MyThread () { System.out.println("构造方法打印的是:" + Thread.currentThread().getName()); } @Override public void run() { System.out.println("run方法打印的是" + Thread.currentThread().getName()); } public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); //thread.start(); } } 输出结果 构造方法打印的是:main run方法打印的是Thread-0 //run方法打印的是main 再来一个比较复杂的 package mythread; public class CountOperate extends Thread { public CountOperate() { System.out.println("CountOperate---begin"); System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("this.getName()=" + this.getName()); System.out.println("CountOperate---end"); } @Override public void run() { System.out.println("run---begin"); System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("this.getName()=" + this.getName()); System.out.println("run---end"); } public static void main(String[] args) { CountOperate c = new CountOperate(); Thread t1 = new Thread(c); t1.setName("A"); t1.start(); } } 输出结果 CountOperate---begin Thread.currentThread().getName()=main this.getName()=Thread-0 CountOperate---end run---begin Thread.currentThread().getName()=A this.getName()=Thread-0 run---end 因为Thread.currentThread()是当前代码段正在那个线程调用,CountOperate的构造函数是有main主线程调用的,run是由Thread线程调用。同时线程的默认名称是Thread-(No),这点可以有Thread类的构造函数看出。其中一个构造函数如下: public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); } /* For autonumbering anonymous threads. */ private static int threadInitNumber; private static synchronized int nextThreadNum() { return threadInitNumber++; } 重点也就是最后一个this.getName() 为什么是Thread-0?由上面的Thread构造函数可以看出当使用一个Thread对象作为参数去实例化一个Thread对象时,实现Thread的线程类被缓存进了target对象,而当调用run()方法时,Thread类是这样实现的 /** * If this thread was constructed using a separate * <code>Runnable</code> run object, then that * <code>Runnable</code> object's <code>run</code> method is called; * otherwise, this method does nothing and returns. * <p> * Subclasses of <code>Thread</code> should override this method. * * @see #start() * @see #stop() * @see #Thread(ThreadGroup, Runnable, String) */ @Override public void run() { if (target != null) { target.run(); } } isAlive() 方法 方法isAlive() 的功能是判断当前的线程是否处于活动状态。 /** * @program: Demo * @description: java基础知识测试 * @author: lee * @create: 2018-07-18 09:45 **/ public class Demo extends Thread{ @Override public void run() { System.out.println("run=" + this.isAlive()); } public static void main(String[] args) { Demo mythread = new Demo(); System.out.println("begin ==" + mythread.isAlive()); mythread.start(); System.out.println("end ==" + mythread.isAlive()); } } 输出结果 begin ==false end ==true run=true 方法isAlive() 的作用是测试线程是否处于活动状态。什么是活动状态呢?活动状态就是线程已经启动且尚未终止。线程处于正在运行或准备开始运行的状态,就认为线程是“存活”的。 需要说明一下,如以下代码: System.out.println("end ==" + mythread.isAlive());虽然在上面的示例中打印的值是true,但此值是不确定的。打印true 值是因为mythread线程还未执行完毕,所以输出true。如果代码更改如下: public static void main(String[] args) throws InterruptedException { MyThread mythread = new MyThread(); System.out.println("begin ==" + mythread.isAlive()); mythread.start(); Thread.sleep(1000); System.out.println("end ==" + mythread.isAlive()); } 输出结果 begin ==false run=true end ==false 另外,在使用isAlive() 方法时,如果将线程对象以构造参数的方式传递给Thread 对象进行start() 启动时,运行的结果和前面示例是有差异的。造成这样的差异的原因还是来自于Thread.currentThread() 和this 的差异。 /** * @program: CountOperate * @description: java基础知识测试 * @author: lee * @create: 2018-07-18 09:45 */ public class CountOperate extends Thread { public CountOperate() { System.out.println("CountOperate---begin"); System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive()); System.out.println("this.getName()=" + this.getName()); System.out.println("this.isAlive()=" + this.isAlive()); System.out.println("CountOperate---end"); } @Override public void run() { System.out.println("run---begin"); System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive()); System.out.println("this.getName()=" + this.getName()); System.out.println("this.isAlive()=" + this.isAlive()); System.out.println("run---end"); } public static void main(String[] args) { CountOperate c = new CountOperate(); Thread t1 = new Thread(c); t1.setName("A"); t1.start(); } } 输出结果 CountOperate---begin Thread.currentThread().getName()=main Thread.currentThread().isAlive()=true this.getName()=Thread-0 this.isAlive()=false CountOperate---end run---begin Thread.currentThread().getName()=A Thread.currentThread().isAlive()=true this.getName()=Thread-0 this.isAlive()=false run---end 另一种方式 /** * @program: CountOperate * @description: java基础知识测试 * @author: lee * @create: 2018-07-18 09:45 */ public class CountOperate extends Thread { public CountOperate() { System.out.println("CountOperate---begin"); System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive()); System.out.println("this.getName()=" + this.getName()); System.out.println("this.isAlive()=" + this.isAlive()); System.out.println("CountOperate---end"); } @Override public void run() { System.out.println("run---begin"); System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive()); System.out.println("this.getName()=" + this.getName()); System.out.println("this.isAlive()=" + this.isAlive()); System.out.println("run---end"); } public static void main(String[] args) { CountOperate c = new CountOperate(); c.start(); } } 输出结果 CountOperate---begin Thread.currentThread().getName()=main Thread.currentThread().isAlive()=true this.getName()=Thread-0 this.isAlive()=false CountOperate---end run---begin Thread.currentThread().getName()=Thread-0 Thread.currentThread().isAlive()=true this.getName()=Thread-0 this.isAlive()=true run---end sleep() 方法 方法sleep() 的作用是在指定的毫秒数内让当前“正在执行的线程”休眠(暂停执行)。这个“正在执行的线程”是指this.currentThread() 返回的线程。 /** * @program: CountOperate * @description: java基础知识测试 * @author: lee * @create: 2018-07-18 09:45 */ public class CountOperate extends Thread { @Override public void run() { try { System.out.println("run threadName=" + Thread.currentThread().getName() + " begin"); Thread.sleep(2000); System.out.println("run threadName=" + Thread.currentThread().getName() + " end"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { CountOperate c = new CountOperate(); c.start(); } } getId() 方法 getId() 方法的作用是取得线程的唯一标识 /** * @program: CountOperate * @description: java基础知识测试 * @author: lee * @create: 2018-07-18 09:45 */ public class CountOperate extends Thread { public static void main(String[] args) { Thread runThread = Thread.currentThread(); System.out.println(runThread.getName() + " " + runThread.getId()); } } # 输出结果 main 1 停止线程 停止一个线程可以使用Thread.stop() 方法,但最好不用它。虽然它确实可以停止一个正在运行的线程,但是这个方法是不安全的(unsafe),而且是已被弃用作废的(deprecated),在将来的Java 版本中,这个方法将不可用或不被支持。 大多数停止一个线程的操作使用Thread.interrupt() 方法,尽管方法的名称是“停止,中止”的意思,但这个方法不会终止一个正在运行的线程,还需要加入一个判断才可以完成线程的停止。 在Java 中有以下3 种方法可以终止正在运行的线程: 使用退出标志,使线程正常退出,也就是当run 方法完成后线程终止。 使用stop 方法强行终止线程,但是不推荐使用这个方法,因为stop 和suspend 及resume 一样,都是作废过期的方法,使用它们可能产生不可预料的结果。 使用interrupt 方法中断线程。 停止不了的线程 本示例将调用interrupt() 方法来停止线程, 但interrupt() 方法的使用效果并不像for+break 语句那样,马上就停止循环。调用interrupt() 方法仅仅是在当前线程中打了一个停止的标记,并不是真的停止线程。 /** * @program: MyThread * @description: java基础知识测试 * @author: lee * @create: 2018-07-18 09:45 */ public class MyThread extends Thread { @Override public void run() { for (int i = 0; i < 500000; i++) { System.out.println("i=" + (i + 1)); } } public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); thread.interrupt(); } catch (Exception e) { System.out.println("main catch"); e.printStackTrace(); } } } 输出结果 ... ... i=499995 i=499996 i=499997 i=499998 i=499999 i=500000 从运行的结果来看,调用interrupt 方法并没有停止线程。如何停止线程呢,请继续向下读。 判断线程是否是停止状态 在介绍如何停止线程的知识点前,先来看一下如何判断线程的状态是不是停止的。在Java 的SDK 中,Thread.java 类里提供了两种方法。 this.interrupted():测试当前线程是否已经中断。 this.isInterrupted():测试线程是否已经中断。 /** * @program: demo * @description: java基础知识测试 * @author: lee * @create: 2018-07-18 09:45 **/ public class Demo extends Thread{ @Override public void run() { for (int i = 0; i < 50; i++) { System.out.println("i=" + (i + 1)); } } public static void main(String[] args) throws InterruptedException { try { Demo thread = new Demo(); thread.start(); thread.interrupt(); //Thread.currentThread().interrupt(); System.out.println(" 是否停止1 ? ="+thread.isInterrupted()); System.out.println(" 是否停止2 ? ="+thread.interrupted()); } catch (Exception e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } } 输出结果 是否停止1 ? =true 是否停止2 ? =false end! i=1 ... i=45 i=46 i=47 i=48 i=49 i=50 判断thread 对象所代表的线程是否停止,但从控制台打印的结果来看,线程并未停止,这也就证明了interrupted() 方法的解释:测试当前线程是否已经中断。这个“当前线程”是main,它从未中断过,所以打印的结果是两个false。 第二种情况 /** * @program: demo * @description: java基础知识测试 * @author: lee * @create: 2018-07-18 09:45 **/ public class Demo extends Thread{ @Override public void run() { for (int i = 0; i < 50; i++) { System.out.println("i=" + (i + 1)); } } public static void main(String[] args) throws InterruptedException { try { Demo thread = new Demo(); thread.start(); Thread.sleep(1000); thread.interrupt(); System.out.println(" 是否停止1 ? ="+thread.isInterrupted()); System.out.println(" 是否停止2 ? ="+thread.interrupted()); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } } 输出结果 i=1 ... i=47 i=48 i=49 i=50 是否停止1 ? =false 是否停止2 ? =false end! 为什么两种结果不一样呢,因为休息一秒后,线程早已经结束了,所以不能中断了,interrupted() 方法的解释:测试当前线程是否已经中断。等价于 /** * @program: demo * @description: java基础知识测试 * @author: lee * @create: 2018-07-18 09:45 **/ public class Demo extends Thread{ @Override public void run() { for (int i = 0; i < 50; i++) { System.out.println("i=" + (i + 1)); } } public static void main(String[] args) throws InterruptedException { try { Demo thread = new Demo(); thread.start(); Thread.sleep(1000); thread.interrupt(); System.out.println(" 是否停止1 ? ="+thread.isInterrupted()); System.out.println(" 是否停止2 ? ="+Thread.interrupted()); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } } 最后,再来看一下这两个方法的解释。 this.interrupted() :测试当前线程是否已经是中断状态,执行后具有将状态标志置清除为false 的功能。 this.isInterrupted() :测试线程Thread 对象是否已经是中断状态,但不清除状态标志。 能停止的线程——异常法 直接上代码 /** * @program: demo * @description: java基础知识测试 * @author: lee * @create: 2018-07-18 09:45 **/ public class Demo extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 5000; i++) { if (Thread.interrupted()) { System.out.println(" 已经是停止状态了! 我要退出了!"); break; } System.out.println("i=" + (i + 1)); } //System.out.println(" 我被输出,如果此代码是for 又继续运行,线程并未停止! "); } public static void main(String[] args) throws InterruptedException { Demo thread = new Demo(); thread.start(); thread.interrupt(); System.out.println(" 是否停止1 ? =" + thread.isInterrupted()); System.out.println(" 是否停止2 ? =" + Thread.interrupted()); System.out.println("end!"); } } 输出结果 是否停止1 ? =true 是否停止2 ? =false end! 已经是停止状态了! 我要退出了! 上面的示例虽然停止了线程,但如果for 语句下面还有语句,还是会继续运行的。 /** * @program: demo * @description: java基础知识测试 * @author: lee * @create: 2018-07-18 09:45 **/ public class Demo extends Thread { @Override public void run() { try { for (int i = 0; i < 500000; i++) { if (Thread.interrupted()) { System.out.println(" 已经是停止状态了! 我要退出了!"); throw new InterruptedException(); } System.out.println("i=" + (i + 1)); } System.out.println(" 我在for 下面"); } catch (InterruptedException e) { System.out.println(" 进MyThread.java 类run 方法中的catch 了! "); e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { Demo thread = new Demo(); thread.start(); thread.interrupt(); System.out.println(" 是否停止1 ? =" + thread.isInterrupted()); System.out.println(" 是否停止2 ? =" + Thread.interrupted()); System.out.println("end!"); } } 输出结果 是否停止1 ? =true 是否停止2 ? =false end! 已经是停止状态了! 我要退出了! 进MyThread.java 类run 方法中的catch 了! java.lang.InterruptedException at Demo.run(Demo.java:14) 在沉睡中停止 如果在sleep状态下停止某一线程,会进入catch语句,并且清除停止状态值,使之变成false. /** * @program: demo * @description: java基础知识测试 * @author: lee * @create: 2018-07-18 09:45 **/ public class Demo extends Thread { @Override public void run() { try { System.out.println("run begin"); Thread.sleep(200000); System.out.println("run end"); } catch (InterruptedException e) { System.out.println("在沉睡中被停止! 进入catch!"+this.isInterrupted()); e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { try { Demo thread = new Demo(); thread.start(); Thread.sleep(200); thread.interrupt(); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } } 输出结果 run begin end! 在沉睡中被停止! 进入catch!false java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at Demo.run(Demo.java:12) 另一种情况 /** * @program: demo * @description: java基础知识测试 * @author: lee * @create: 2018-07-18 09:45 **/ public class Demo extends Thread { @Override public void run() { try { for(int i=0;i<100000;i++){ System.out.println("i="+(i+1)); } System.out.println("run begin"); Thread.sleep(200000); System.out.println("run end"); } catch (InterruptedException e) { System.out.println(" 先停止,再遇到了sleep! 进入catch!"); e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { Demo thread = new Demo(); thread.start(); thread.interrupt(); System.out.println("end!"); } } 输出结果 ... i=99998 i=99999 i=100000 run begin 先停止,再遇到了sleep! 进入catch! 能停止的线程——暴力停止 使用stop() 方法停止线程则是非常暴力的,调用stop() 方法时会抛出java.lang.ThreadDeath 异常,但在通常的情况下,此异常不需要显式地捕捉,方法stop() 已经被作废,因为如果强制让线程停止则有可能使一些清理性的工作得不到完成。另外一个情况就是对锁定的对象进行了“解锁”,导致数据得不到同步的处理,出现数据不一致的问题。 /** * @program: demo * @description: java基础知识测试 * @author: lee * @create: 2018-07-18 09:45 **/ public class Demo extends Thread { @Override public void run() { try { for(int i=0;i<100000;i++){ System.out.println("i="+(i+1)); Thread.sleep(2000); } } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { Demo thread = new Demo(); thread.start(); Thread.sleep(10000); thread.stop(); System.out.println("end!"); } } 输出结果 i=1 i=2 i=3 i=4 i=5 end! stop停止导致数据不一致 /** * Created by Lee on 2018/7/28. */ public class StopSynchronizedObject { private String username = "a"; private String password = "aa"; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } synchronized public void printString(String username, String password) { try { this.username = username; Thread.sleep(8000); this.password = password; } catch (InterruptedException ex) { ex.printStackTrace(); } } } /** * Created by Lee on 2018/7/28. */ public class StopSynchronizedThread extends Thread { private StopSynchronizedObject object; public StopSynchronizedThread(StopSynchronizedObject object) { this.object=object; } @Override public void run() { object.printString("b","bb"); } } /** * Created by Lee on 2018/7/28. */ public class StopSynchronizedRun { public static void main(String[] args) { try { StopSynchronizedObject object = new StopSynchronizedObject(); StopSynchronizedThread thread = new StopSynchronizedThread(object); thread.start(); Thread.sleep(500); thread.stop(); System.out.println(object.getUsername()); System.out.println(object.getPassword()); } catch (InterruptedException e) { e.printStackTrace(); } } } 输出结果 b aa 再看一个例子 /** * Created by Lee on 2018/7/28. */ public class StopSynchronizedRun { public static void main(String[] args) { try { StopSynchronizedObject object = new StopSynchronizedObject(); StopSynchronizedThread thread = new StopSynchronizedThread(object); thread.start(); //Thread.sleep(500); thread.stop(); System.out.println(object.getUsername()); System.out.println(object.getPassword()); } catch (Exception e) { e.printStackTrace(); } } } 输出结果 a aa 使用return 停止线程 /** * @program: demo * @description: java基础知识测试 * @author: lee * @create: 2018-07-18 09:45 **/ public class Demo extends Thread { @Override public void run() { while (true) { if (this.isInterrupted()) { System.out.println("停止了!"); return; } System.out.println("timer=" + System.currentTimeMillis()); } } public static void main(String[] args) throws InterruptedException { Demo thread = new Demo(); thread.start(); Thread.sleep(1000); thread.interrupt(); System.out.println("end!"); } } 输出结果 timer=1532932687078 timer=1532932687078 end! 停止了! 暂停线程 暂停线程意味着此线程还可以恢复运行。在Java 多线程中,可以使用suspend() 方法暂停线程,使用resume() 方法恢复线程的执行。 /** * @program: demo * @description: demo * @author: lee * @create: 2018-07-29 11:05 **/ public class SuspendThread extends Thread { private long i = 0; public long getI() { return i; } public void setI(long i) { this.i = i; } @Override public void run(){ while (true) { i++; } } } /** * Created by Lee on 2018/7/28. */ public class SuspendThreadRun { public static void main(String[] args) { try { SuspendThread thread = new SuspendThread(); thread.start(); Thread.sleep(1000); //第一段 thread.suspend(); System.out.println("I="+thread.getI()); Thread.sleep(5000); System.out.println("I="+thread.getI()); //第二段 thread.resume(); Thread.sleep(1000); //第三段 thread.suspend(); System.out.println("I="+thread.getI()); Thread.sleep(5000); System.out.println("I="+thread.getI()); thread.stop(); } catch (InterruptedException ex) { ex.printStackTrace(); } } } 输出结果 I=483701768 I=483701768 I=1001747085 I=1001747085 suspend 与resume 方法的缺点——独占 在使用suspend 与resume 方法时,如果使用不当,极易造成公共的同步对象的独占,使得其他线程无法访问公共同步对象。 public class SynchronizedObject { synchronized public void printString() { System.out.println("begin"); if (Thread.currentThread().getName().equals("a")) { System.out.println("a 线程永远 suspend 了! "); Thread.currentThread().suspend(); } System.out.println("end"); } } public class Run { public static void main(String[] args) { try { final SynchronizedObject object = new SynchronizedObject(); Thread thread1 = new Thread() { @Override public void run() { object.printString(); } }; thread1.setName("a"); thread1.start(); Thread.sleep(1000); Thread thread2 = new Thread() { @Override public void run() { System.out.println("thread2 启动了,但进入不了printString() 方法! 只打印1 个begin"); System.out.println(" 因为printString() 方法被a 线程锁定并且永远 suspend 暂停了! "); object.printString(); } }; thread2.start(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 还有另外一种独占锁的情况也要格外注意,稍有不慎,就会掉进“坑”里 public class MyThread extends Thread { private long i = 0; @Override public void run() { while (true) { i++; } } } public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(1000); thread.suspend(); System.out.println("main end!"); } catch (InterruptedException e) { e.printStackTrace(); } } } 输出结果 main end! 如果更改程序如下 /** * @program: demo * @description: 2 * @author: lee * @create: 2018-07-30 14:52 **/ public class test extends Thread{ private long i = 0; @Override public void run() { while (true) { i++; System.out.println(i); } } public static void main(String[] args) { try { test thread = new test(); thread.start(); Thread.sleep(1000); thread.suspend(); System.out.println("main end!"); } catch (InterruptedException e) { e.printStackTrace(); } } } 输出结果 ... 113720 113721 113722 113723 不再会有main end!输出,出现这样情况的原因是,当程序运行到println() 方法内部停止时,同步锁未被释放。 /** * Prints a String and then terminate the line. This method behaves as * though it invokes <code>{@link #print(String)}</code> and then * <code>{@link #println()}</code>. * * @param x The <code>String</code> to be printed. */ public void println(String x) { synchronized (this) { print(x); newLine(); } } suspend 与resume 方法的缺点——不同步 在使用suspend 与resume 方法时也容易出现因为线程的暂停而导致数据不同步的情况。 public class MyObject { private String username = "1"; private String password = "11"; public void setValue(String u, String p) { this.username = u; if (Thread.currentThread().getName().equals("a")) { System.out.println(" 停止a 线程! "); Thread.currentThread().suspend(); } this.password = p; } public void printUsernamePassword() { System.out.println(username + " " + password); } } public class Run { public static void main(String[] args) throws InterruptedException { final MyObject myobject = new MyObject(); Thread thread1 = new Thread() { public void run() { myobject.setValue("a", "aa"); }; }; thread1.setName("a"); thread1.start(); Thread.sleep(500); Thread thread2 = new Thread() { public void run() { myobject.printUsernamePassword(); }; }; thread2.start(); } } 输出结果 停止a线程 a 11 yield 方法 yield() 方法的作用是放弃当前的CPU 资源,将它让给其他的任务去占用CPU 执行时间。但放弃的时间不确定,有可能刚刚放弃,马上又获得CPU 时间片。 /** * @program: demo * @description: demo * @author: lee * @create: 2018-07-29 11:21 **/ public class YieldThread extends Thread { @Override public void run(){ long beginTime = System.currentTimeMillis(); int count = 0; for (int i = 0; i < 5000000; i++) { // Thread.yield(); count = count + (i+1); } long endTime=System.currentTimeMillis(); System.out.println("用时:" + (endTime-beginTime) + "毫秒!"); } public static void main(String[] args) { YieldThread thread = new YieldThread(); thread.start(); } } # 输出结果 用时:2毫秒! # 没有注释Thread.yield();输出结果 用时:1809毫秒! 线程的优先级 在操作系统中,线程可以划分优先级,优先级较高的线程得到的CPU 资源较多,也就是CPU 优先执行优先级较高的线程对象中的任务,在Java 中,线程的优先级分为1 ~ 10 这10 个等级,如果小于1 或大于10,则JDK 抛出异常throw new IllegalArgumentException()。 JDK 中使用3 个常量来预置定义优先级的值,代码如下: public final static int MIN_PRIORITY = 1; public final static int NORM_PRIORITY = 5; public final static int MAX_PRIORITY = 10; 线程优先级的继承特性 在Java 中,线程的优先级具有继承性,比如A 线程启动B 线程,则B 线程的优先级与A 是一样的。 /** * @program: demo * @description: MyThread1 * @author: lee * @create: 2018-07-30 15:38 **/ public class MyThread1 extends Thread { @Override public void run() { System.out.println("MyThread1 run priority=" + this.getPriority()); MyThread2 thread2 = new MyThread2(); thread2.start(); } } /** * @program: demo * @description: MyThread2 * @author: lee * @create: 2018-07-30 15:38 **/ public class MyThread2 extends Thread { @Override public void run() { System.out.println("MyThread2 run priority=" + this.getPriority()); } } /** * @program: demo * @description: demo * @author: lee * @create: 2018-07-30 15:39 **/ public class RunDemo { public static void main(String[] args) { MyThread1 thread = new MyThread1(); thread.start(); } } 输出结果 MyThread1 run priority=5 MyThread2 run priority=5 优先级具有规则性 虽然使用setPriority() 方法可以设置线程的优先级,但还没有看到设置优先级所带来的效果。 import java.util.Random; /** * @program: demo * @description: 线程优先级测试 * @author: lee * @create: 2018-07-29 11:37 **/ public class PropertyThread1 extends Thread{ @Override public void run() { long beginTime = System.currentTimeMillis(); long addResult = 0; for (int j = 0;j < 100; j++) { Random random = new Random(); random.nextInt(); addResult = addResult +j; long endTime = System.currentTimeMillis(); System.out.println("*************** PropertyThread1 use time= " +(endTime-beginTime)); } } } import java.util.Random; /** * @program: demo * @description: 线程优先级测试 * @author: lee * @create: 2018-07-29 11:37 **/ public class PropertyThread2 extends Thread{ @Override public void run() { long beginTime = System.currentTimeMillis(); long addResult = 0; for (int j = 0;j < 100; j++) { Random random = new Random(); random.nextInt(); addResult = addResult +j; long endTime = System.currentTimeMillis(); System.out.println("######### PropertyThread2 use time= " +(endTime-beginTime)); } } } /** * @program: demo * @description: property测试 * @author: lee * @create: 2018-07-29 11:43 **/ public class PropertyRun { public static void main(String[] args) { PropertyThread1 thread1 = new PropertyThread1(); thread1.setPriority(2); thread1.start(); PropertyThread2 thread2 = new PropertyThread2(); thread2.start(); thread2.setPriority(6); } } 输出结果 ... ######### PropertyThread2 use time= 1 *************** PropertyThread1 use time= 2 ######### PropertyThread2 use time= 2 *************** PropertyThread1 use time= 3 ######### PropertyThread2 use time= 2 ... *************** PropertyThread1 use time= 11 *************** PropertyThread1 use time= 11 *************** PropertyThread1 use time= 11 *************** PropertyThread1 use time= 11 *************** PropertyThread1 use time= 11 高优先级的线程总是大部分先执行完,但不代表高优先级的线程全部先执行完。另外,不要以为thread1 线程先被main 线程所调用就会先执行完,当线程优先级的等级差距很大时,谁先执行完和代码的调用顺序无关,线程的优先级具有一定的规则性,也就是CPU 尽量将执行资源让给优先级比较高的线程。 优先级具有随机性 线程的优先级还具有“随机性”,也就是优先级较高的线程不一定每一次都先执行完,当优先级的差距不大的时候最能体现出随机性。 看谁运行得快 线程的优先级越高,CPU分配得到的机会越大,所以执行的时间越多。 守护线程 在Java 线程中有两种线程,一种是用户线程,另一种是守护线程。 守护线程是一种特殊的线程,它的特性有“陪伴”的含义,当进程中不存在非守护线程了,则守护线程自动销毁。典型的守护线程就是垃圾回收线程,当进程中没有非守护线程了,则垃圾回收线程也就没有存在的必要了,自动销毁。 用个比较通俗的比喻来解释一下“守护线程”:任何一个守护线程都是整个JVM 中所有非守护线程的“保姆”,只要当前JVM实例中存在任何一个非守护线程没有结束,守护线程就在工作,只有当最后一个非守护线程结束时,守护线程才随着JVM 一同结束工作。注意点: thread.setDaemon(true)必须在thread.start()之前设置。 在Daemon线程中产生的新线程也是Daemon的。 不是所有的应用都可以分配给Daemon线程来进行服务,比如读写操作或者计算逻辑。因为Daemon Thread还没来得及进行操作,虚拟机可能已经退出了。 /** * @program: demo * @description: 守护线程 * @author: lee * @create: 2018-07-29 12:04 **/ public class DaemonThread extends Thread{ private int i = 0; @Override public void run() { while (true) { try { System.out.println(i++); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } /** * @program: demo * @description: 守护进程 * @author: lee * @create: 2018-07-29 12:06 **/ public class DaemonRun { public static void main(String[] args) throws InterruptedException { DaemonThread thread = new DaemonThread(); thread.setDaemon(true); thread.start(); Thread.sleep(5000); System.out.println("***************************************************************再也不会打印东西了。。。。"); } } 输出结果 0 1 2 3 4 ***************************************************************再也不会打印东西了。。。。 如果多线程类改变一下 /** * @program: demo * @description: 守护线程 * @author: lee * @create: 2018-07-29 12:04 **/ public class DaemonThread extends Thread{ private int i = 0; @Override public void run() { while (true) { System.out.println(i++); } } } 输出结果 ... 106250 106251 106252 ***************************************************************再也不会打印东西了。。。。 106253 106254 106255 ... 106341 Process finished with exit code 0

优秀的个人博客,低调大师

运维工程师需要掌握的技能

提起运维,大家都会想到又苦又累,又不被人重视的网管,机房运维,认为这个工种很low,入门门槛低,做的事比较杂,从搬服务器上架到修打印机,修电脑,处理网络小故障等杂七杂八的活,究其原因,多年来小公司都把运维当做一种打杂的小工使。其实运维从分类可以分为很多专业领域,比如网络工程师,系统工程师,备份存储工程师,CDN工程师,数据库管理员,应用运维,运维开发,运维架构师等等岗位,本章暂不对运维岗位做过多解释,我就个人的经验,我是从运维实施、系统管理员、DBA最后到运维开发的,简单说说各大互联网公司对岗位的面试要求: WEB篇:1、负载均衡篇:熟悉常用的负载均衡技术,LVS,dpdk,Nginx等四层/七层负载均衡,除了硬件负载均衡设备F5,有搭建、维护并熟悉负载均衡原理;2、Nginx 重要配置、优化及使用、与lua的结合,接入、降级、限流、隔离、熔断、动静分离、反向代理、负载均衡,反爬虫,黑白名单等 另Nginx 和Apache的比较;3、TCP/HTTPs协议及三次握手,四次挥手,get/post的差异,协议头,跳转,常见返回码的含义200/30x/40x/50x等知识及导致返回码的可能故障原因,如果可能请详细了解TCP/TP协议内容;4、web的优化,web 访问的流程,从浏览器-DNS-CDN-缓存(本地缓存,负载均衡层,缓存层,接入层,应用层,数据库层)-应用-数据库整个流程,需要陈述过程,并能解释调优排障的思路;http 连接越快越好,越快建立连接越好,中间DNS解析, tcp握手都是可以优化的点http 请求少并且小,减少请求的数量,请求的体积,比如 cookie的大小 解析html 的速度,dom树解析,js 执行和首屏渲染是串行的,页面渲染,把js放到body后面加载页面,下载资源,利用上面的原则,尽量少的发http请求,比如图片,字体,以及js文件等等 网络篇:网络抖动,网卡打满,大面积断网,网络丢包,网络劫持,接口响应超时等,常用网络故障排查的手段,工具等,如tcpdump/iftop/traceroute/netstat等 故障篇:网络失败,业务异常(参数错误、业务逻辑处理错误,返回数据格式错误等下游业务不可用),机器故障 cpu 负载太高,内存溢出,磁盘打满,网卡打满,超时监控快速反馈 监控:正面预防,快速发现、定位问题进行报警降级:反向止损,遇到故障自动处理,降低损失 监控篇: 常规监控: zabbix 、Ganglia、Cacti、Nagios等业务监控:业务指标的监控调用链监控:CAT、zipkin、阿里鹰眼等其他新兴监控: Prometheus open-falcon日志监控:ELK等另外时序数据库是监控领域比较火的技术,大家可以多研究一下 应用篇Java,weblogic,tomcat,jetty等Java中间件,涉及jvm 的调优,监控,GC的调优,cpu高的诊断dubbo spring cloud sprin boot sping 全家桶,微服务的搭建,部署,监控(调用链监控)鉴于微服务领域还不成熟,很多公司还没有实践,另外有必要了解K8S等编排工具消息中间库 rabbitmq 、rocketmq,Kafka 等对比使用,如吞吐量、时延等优缺点,运维中遇到的问题及故障处置redis 的架构,有单节点,官方cluster集群,复制,读写分离,分片等,业界使用的proxy 方案,对比优缺点,常遇到的故障及问题,再就是容灾,跨机房,业界的解决方案,一般是通过流复制redis 和memcache的区别,优缺点增加对项目的架构,集群规模,QPS/TPS等数据的认知mongodb 集群的运维,分片集群的规模,运维监控,处理过的问题及优化,主要有cpu高,慢查询,占用内存高,夯死等问题应用部署的问题,涉及发布,构建,编译等 大数据篇:Hadoop 生态圈 hdfs,habase ,hive,mapreduse,zookeerer,kafka,tez,impla,spark等组件,zeppelin,kylin,侧重生产机器的规模,遇到的问题,踩到的坑,有的侧重原理 数据库篇:MySQL oracle、简单了解,sql 语句的查询,索引的类型,数据库高可用架构,主从、双主、MHA架构、Proxy方案等,另外了解数据库中间件,例如mycat等 存储篇:ceph 的搭建,对象存储的原理,各种存储(NAS/SAN/对象存储等)的优缺点及使用场景 公有云、私有云篇:openstack ,zstack ,虚拟化 vm 的原理 docker 篇docker的基本原理、编排工具k8s 的使用,k8s 的概念,pod ,网络的解决方案遇到的坑及解决方案,当然也要防止某些辣鸡公司套你方案docker 自建仓库,docker file的使用 自动化运维篇自动化运维工具的使用,ansible ,saltstack 等使用,Django 的开发 cmdb/自动化部署,任务调度系统,数据库运维系统CI/CD的构建,自动化发布,灰度发布,金丝雀发布,蓝绿发布等等devops的概念及实施,对AIops的见解及作出的变革 开发篇:shell 脚本 基础运维命令python 开发 ,主要是web开发,表单的设计,数据库或者orm的设计,高并发,消息队列 restapi等 前端比较弱是运维的通病salca 略了解,多用于大数据开发go 略了解,如果熟悉并开发过项目,一定是加分项,求之不得; 面试篇:个人自我介绍目前的工作内容,负责的项目,遇到的故障,印象深刻的项目,遇到的挑战,遇到的棘手问题,自己负责过的项目,项目规模,集群规模,人数等等

优秀的个人博客,低调大师

现代网络性能监控工具应具备何种技能?

以前,企业网络工程师不得不为各种连接的服务器、应用程序和终端设备提供网络接入和足够的带宽。从OSI模型角度看,这些工具主要关注于1-4层网络。由于通过一个网络的所有流量和数据流都共享全部的带宽和队列资源,更高的OSI层次多少被忽略了。 慢慢地,网络设备变得越来越复杂,现在网络中不同的数据流都可以被识别出来并区别对待。各种服务质量(QoS)和应用层流程成型技术也可用于实现这个目 标。此外,随着对于关键业务应用程序依赖程度越来越高,网络工程师也迫切需要了解OSI模型的更高层次,这样他们才能发现网络、服务器操作系统、虚拟化软件和应用程序本身所存在的性能问题或其他问题。但是,要想解决这些问题,他们需要借助于一些工具。 在许多场景中,网络性能监控工具已经从较为传统和简单的网络监控软件向前进化。这些监控工具通常使用ICMP的ping和简单网络监控协议(SNMP)的 polling/traps去检查网络状态。更现代的补充功能包括监控、基线化和智能分析应用程序本身的所有状态。最先进的网络监控工具则还能够执行以下 5种功能: 1. 网络与应用程序监控 2. 网络问题分析 3. 应用数据与流拦截分析 4. 虚拟化与操作系统问题检测 5. 问题根源分析 不同的网络性能监控供应商在执行这些任务的粒度各不相同。而且,越精确的任务在实现和管理时会越复杂。因此,一定要准确理解自身组织的需求,之后再恰当地平衡粒度和复杂度。那么,我们接下来继续分析现代网络性能监控工具所具备的5个常用功能。 网络与应用程序监控 正如前面所提到的,现代网络监控工具已经从使用ICMP ping和SNMP协议的网络监控进化为更复杂的工具了。来自网络监控服务器的常规ping命令会发送到各种不同的网络、服务器及其他需要监控的终端设备 上。如果所监控的设备没有响应ping请求,那么监控工具可能会将该设备标记为“宕机”,然后向支持人员发出警报。 SNMP会收集和组织来自支持这种协议的网络与服务器组件的各种不同类型的数据。 对于网络设备而言,这通常意味着要不断地监控特定的设备接口状态和数据吞吐量。此外,它还会监控硬件状态,其中包括电源、风扇和内存使用率等。 有一些网络性能监控工具还能够收集和响应各不同的系统日志(Syslog)消息。系统日志是一种面向基础架构设备日志消息的通用标准。这些消息会被发送和 存储到一个集中的网络监控工具中,经过分析后会在出现系统故障时用于通知支持工程师。 网络监控工具具有全面的监控能力,它不仅能够监控可用性和性能统计数据,甚至能够监控整个应用层。这种监控通常依赖于所配置的软件插件或操作系统设置,将监控数据发送回中央监控服务器。 虚拟化和操作系统问题检测 网络与应用程序之间也一定会出现一些问题。这其中包括虚拟化、服务器操作系统及应用程序所依赖的各种中间件。虚拟机管理程序需要单独监控可能造成应用层性 能下降的问题。负责管理分布式系统之间通信的主操作系统和中间件也有一样的问题。网络性能监控供应商会使用不同的方法去监控这些问题,其中一些还支持更多 的虚拟机管理程序、操作系统和中间件软件。 网络问题分析 除了提供简单的在线/断线状态和使用率信息,网络性能监控产品还能执行更复杂的自动化网络故障修复任务。这其中包括路由协议监控和计划外路由变化警报。此外,有一些产品还能使用智能技术去理解各种WAN技术、虚拟堆叠和QoS特性的工作方式。此外,它们还能设置成在出现问题时自动发送警报,甚至还能够执行 自动修复问题的操作。 应用数据与流的捕捉分析 现代网络性能监控工具的最重要任务就是解析和分析数据与流。在网络中,不同区域可以用不同的方法去捕捉数据包,然后执行自动和/或人工分析。最常见的方法 有: 1. 在所有关键的网络位置上部署分布式数据采集代理。 2. 使用特定路由器/交换机硬件所具有的数据包捕捉功能。 分析数据包并执行更精细的应用分析,这是许多企业组织越来越重视的需求。通过使用深度数据包检测技术,网络管理员就能够分辨出与应用程序关系更密切的通信问题,否则这些问题很难检测到。 网络流采集会整理出数据进出网卡的IP网络统计信息。一旦将这些数据发送到一个集中的服务器并通过网络性能监控流分析工具的分析,网络支持管理员就能够分 辨流量的源信息和目标信息,以及流量在通过网络时会遇到的详细QoS策略。最终,这些数据会被用于识别网络设备之间的配置问题或各个网络路径的拥塞问题。 问题根源分析 在一个网络性能监控工具上整合各种事件数据并进行分析,能够形成一种自动化问题根源分析功能。如果网络中出现一个问题,然后它触发多个组件的事件,那么许 多网络性能监控工具都会使用人工智能技术分析这些事件的关联性,最终确定这个问题的根源。这是其中一个需要配置的复杂功能,因为它要求正确配置所有的设备 和监控系统。例如,如果设备时间没有通过网络时间协议(Network Time Protocol)进行同步,那么事件发现的时间就会出错。这会给问题根源分析引擎的精确度造成负面影响。但是,一旦创建好并采取正确的维护措施,自动化 问题根源分析工具就能够在故障修复方面节省大量的时间。 作者:佚名 来源:51CTO

优秀的个人博客,低调大师

数据科学挑战重重 get新技能成当务之急

随着更多新兴工具和技术的出现,许多企业正在努力应对当今大数据和数据科学生态系统的复杂性。 根据TDWI(数据仓库研究所)的最新研究,专业数据科学家的短缺仍然是企业面临的数据科学的挑战之一。 TDWI公司副总裁兼研究总监Fern Halper说:“我们经常听到很多组织表示,在数据科学环境中面临的最大挑战是找到合适的技术和工具。” 该研究收集了超过300家企业的大数据和数据科学经验。大数据分析和数据科学经验这两个主题越来越融合,因为组织需要了解过去几年中收集大量数据的工作者。 此次调查的受访者列举的其他常见挑战还有:缺乏对大数据工具的了解,缺乏利用大数据所需的企业架构,安全和隐私问题以及治理协议不足等问题。 尤其是技术方面的问题特别棘手。Halper表示,在过去几年中出现了许多新工具,包括Hadoop,Spark,Python等等,企业很难确保跟上这些新工具、新技术快速发展的步伐。 有些受访者认为很多技术让人眼花缭乱,其中不乏炒作的因素,他们有时不知道该怎样面对技术的迭代更新。另外一些人认为技术和工具变更速度很快,如果缺乏敏捷性,他们不一定能保持最好的架构。 现在,企业都在使用自己熟悉的工具和技术应对数据科学的挑战。约80%的受访者表示他们目前使用数据仓库工具作为主要数据源。对于分析而言,简单的查询和数据可视化工具是最常用的。在接下来的两年中,数据仓库工具将依然广受欢迎,与此同时,Hadoop和开源R也受到更多企业的青睐。 Halper说,调查结果显示出非结构化数据查询和预测分析(包括机器学习)的强劲势头。这些新兴工具和技术似乎将在未来将彻底取代更多的工具。 “数据仓库不会消失,但它正被其他类型的平台取代,并创建一个生态系统,” Halper说, “预测分析是一项热门技术,再加上机器学习的驱动,未来的发展势头不可小觑。” 本文转自d1net(转载)

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册