今天,咱们就把线程给完完全全的结束掉,但是不是说,就已经覆盖了全部的知识点,可以说是线程的常见的问题及所含知识基本都包含。

1、多线程(理解)

  (1)JDK5以后的针对线程的锁定操作和释放操作

    Lock锁

  (2)死锁问题的描述和代码体现

    同步的弊端:

      A:效率低

      B:容易产生死锁

    死锁:

      两个或两个以上的线程在争夺资源的过程中,发生的一种相互等待现象。

    举例:

      中国人和外国人吃饭的案例

      正常情况下:

        中国人:筷子两支

        外国人:刀和叉

      死锁情况下:

        中国人:筷子1支,刀一把。

        外国人:筷子1支,叉一把。

        (都在等待对方给自己的用具)

用代码怎么体现一个死锁问题?(面试题)

创建一个锁类,有两把锁:

 package com.wyh.lock;

 /**
* @author WYH
* @version 2019年11月23日 上午8:27:03
*/
public class MyLock { //定义两把锁
public static final Object objA = new Object();
public static final Object objB = new Object(); }

创建线程类,重写run方法:

 package com.wyh.lock;

 /**
* @author WYH
* @version 2019年11月23日 上午8:28:17
*/
public class DieLock extends Thread{
private boolean flag; public DieLock(boolean flag) {
this.flag = flag;
} @Override
public void run() {
if(flag) {
synchronized(MyLock.objA) {
System.out.println("if objA");//情况是当dl1走到这里等待锁B
synchronized(MyLock.objB) {
System.out.println("if objB");
}
}
}else {
synchronized(MyLock.objB) {
System.out.println("else objB");//当dl2走到这里等待锁A
synchronized(MyLock.objA) {
System.out.println("else objA");
}
}
}
} }

编写测试类:

 package com.wyh.lock;

 /**
* @author WYH
* @version 2019年11月23日 上午8:33:50
*/
public class DieLockDemo {
public static void main(String[] args) {
DieLock dl1 = new DieLock(true);
DieLock dl2 = new DieLock(false); dl1.start();
dl2.start();
} }

  (3)生产者和消费者多线程体现(线程间的通信问题)

    上一节我们写的售票程序并不符合实际情况。

      以学生作为资源来实现的

      资源类:student

      设置数据类:SetThread(生产者)

      获取数据类:GetThread(消费者)

      测试类:StudentDemo

      代码:

A:最基本的版本,只有一个数据。

Student类:

 package 生产者消费者01;

 /**
* @author WYH
* @version 2019年11月23日 上午9:03:02
*/
public class Student {
String name;
int age; }

SetThread类:(为了保证多个线程是操作同一个学生,我们重写有参构造方法)

 package 生产者消费者01;

 /**
* @author WYH
* @version 2019年11月23日 上午9:03:35
*/
public class StudentSetThread implements Runnable {
private Student s ; public StudentSetThread(Student s) {
this.s = s;
} @Override
public void run() {
s.name = "王友虎";
s.age = 22;
} }

SetThread类:

 package 生产者消费者01;

 /**
* @author WYH
* @version 2019年11月23日 上午9:04:46
*/
public class StudentGetThread implements Runnable {
private Student s ; public StudentGetThread(Student s) {
this.s = s;
} @Override
public void run() {
System.out.println(s.name+"---"+s.age);
} }

测试类;

 package 生产者消费者01;

 /**
* @author WYH
* @version 2019年11月23日 上午9:05:35
*/
public class StudentThreadDemo {
public static void main(String[] args) {
Student s = new Student();
StudentSetThread st = new StudentSetThread(s);
StudentGetThread sg = new StudentGetThread(s); Thread t1 = new Thread(st);
Thread t2 = new Thread(sg); t2.start();
t1.start(); }
}

但是运行多次我们发现,有出现姓名为null或者年龄为0的情况出现,这是为什么?

这是因为CPU进行的操作都是原子操作,有情况是当对年龄进行赋值,还没来得及对姓名赋值,下一个线程就进行输出。从而导致有null的情况,其他情况类推。

B:改进版本,给出了不同的数据。并加入了同步机制。

为了数据效果好一点,我们设置循环和判断,给出不同的值.

学生类:

 package 生产者消费者02;

 /**
* @author WYH
* @version 2019年11月23日 上午9:03:02
*/
public class Student {
String name;
int age; }

SetThread类:

 package 生产者消费者02;

 /**
* @author WYH
* @version 2019年11月23日 上午9:03:35
*/
public class StudentSetThread implements Runnable {
private Student s ;
private int x = 0; public StudentSetThread(Student s) {
this.s = s;
} @Override
public void run() {
while(true) { if(x%2==0) {
s.name = "王友虎";
s.age = 22;
}else {
s.name = "李智恩";
s.age = 20;
} x++;
} } }

GetThread类:

 package 生产者消费者02;

 /**
* @author WYH
* @version 2019年11月23日 上午9:04:46
*/
public class StudentGetThread implements Runnable {
private Student s ; public StudentGetThread(Student s) {
this.s = s;
} @Override
public void run() {
while(true) { System.out.println(s.name+"---"+s.age); } } }

测试类:

 package 生产者消费者02;

 /**
* @author WYH
* @version 2019年11月23日 上午9:05:35
*
* 解决线程安全的问题
*
*/
public class StudentThreadDemo {
public static void main(String[] args) {
Student s = new Student();
StudentSetThread st = new StudentSetThread(s);
StudentGetThread sg = new StudentGetThread(s); Thread t1 = new Thread(st);
Thread t2 = new Thread(sg); t2.start();
t1.start(); }
}

运行结果:

我们发现了问题

    1:同一个数据出现多次

        CPU的一点点时间片的执行权,就足够执行很多次

    2:姓名和年龄不匹配

        线程运行的随机性

很显然,我们这个改进还是存在线程安全的问题:

  怎么判断一个线程是不是安全的:

    1:是否是多线程环境  是

    2:是都有共享数据  是

    3:是否有多条语句操作共享数据  是

C:等待唤醒机制改进程序。让数据能够实现依次的出现

            wait()  :等待

            notify(): 唤醒单个线程

            notifyAll(): 唤醒多个线程

(上面这3个方法的调用必须是通过锁对象调用,而当我们使用的锁悐是任意锁,所以和没加锁区别不大,所以,这些方法必须定义在Object类中s)

对上面的进行解决:加锁,synchronized,并且通过等待唤醒机制进行操作。保证数据是依次出现的

注意:1、不同种类的线程都要加锁。   2、不同种类的线程加的锁必须是同一把。

学生类:

 package 生产者消费者03;

 /**
* @author WYH
* @version 2019年11月23日 上午9:03:02
*/
public class Student {
String name;
int age;
boolean flag; //默认没有数据.false
}

SetThread类:

 package 生产者消费者03;

 /**
* @author WYH
* @version 2019年11月23日 上午9:03:35
*/
public class StudentSetThread implements Runnable {
private Student s ;
private int x = 0; public StudentSetThread(Student s) {
this.s = s;
} @Override
public void run() {
while(true) {
synchronized(s) {
if(s.flag) {
try {
s.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} if(x%2==0) {
s.name = "王友虎";
s.age = 22;
}else {
s.name = "李智恩";
s.age = 20;
} //此时有数据
s.flag = true;
//唤醒线程
s.notify(); //唤醒不代表立即执行,还需要争夺CPU执行权. }
x++; } } }

GetThread类:

 package 生产者消费者03;

 /**
* @author WYH
* @version 2019年11月23日 上午9:04:46
*/
public class StudentGetThread implements Runnable {
private Student s ; public StudentGetThread(Student s) {
this.s = s;
} @Override
public void run() {
while(true) {
synchronized (s) {
if(!s.flag) {
try {
s.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(s.name+"---"+s.age); //消費了
s.flag = false;
//綫程
s.notify(); }
} } }

测试类:

 package 生产者消费者03;

 /**
* @author WYH
* @version 2019年11月23日 上午9:05:35
*
* 等待唤醒机制
*
*/
public class StudentThreadDemo {
public static void main(String[] args) {
Student s = new Student();
StudentSetThread st = new StudentSetThread(s);
StudentGetThread sg = new StudentGetThread(s); Thread t1 = new Thread(st);
Thread t2 = new Thread(sg); t2.start();
t1.start(); }
}

D:资源唤醒机制的代码优化,

把数据及操作都写在了资源类中,同步方法实现。

学生类:

 package 生产者消费者04优化;

 /**
* @author WYH
* @version 2019年11月23日 上午9:03:02
*
*
* 用同步方法来优化
*
*/
public class Student {
private String name;
private int age;
private boolean flag; //默认没有数据.false public synchronized void set(String name,int age) {
if(flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} this.name = name;
this.age = age; //修改
flag = true; //唤醒
this.notify();
} public synchronized void get() {
if(!flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} System.out.println(this.name + "---" + this.age); //修改
flag = false; //唤醒
this.notify();
} }

SetThread类:

 package 生产者消费者04优化;

 /**
* @author WYH
* @version 2019年11月23日 上午9:03:35
*/
public class StudentSetThread implements Runnable {
private Student s ;
private int x = 0; public StudentSetThread(Student s) {
this.s = s;
} @Override
public void run() {
while(true) {
if(x%2==0) {
s.set("王友虎", 22);
}else {
s.set("李智恩", 20);
}
x++;
}
} }

GetThread类:

 package 生产者消费者04优化;

 /**
* @author WYH
* @version 2019年11月23日 上午9:04:46
*/
public class StudentGetThread implements Runnable {
private Student s ; public StudentGetThread(Student s) {
this.s = s;
} @Override
public void run() {
while(true) {
s.get(); }
} }

测试类:

 package 生产者消费者04优化;

 /**
* @author WYH
* @version 2019年11月23日 上午9:05:35
*
* 等待唤醒机制
*
*/
public class StudentThreadDemo {
public static void main(String[] args) {
Student s = new Student();
StudentSetThread st = new StudentSetThread(s);
StudentGetThread sg = new StudentGetThread(s); Thread t1 = new Thread(st);
Thread t2 = new Thread(sg); t2.start();
t1.start(); }
}

线程的状态转换图:

  

  (4)线程组(用实现Runnable接口的方式举例)

 package 线程组1;

 /**
* @author WYH
* @version 2019年11月23日 上午10:30:51
*/
public class MyRunnable implements Runnable{ @Override
public void run() {
System.out.println(Thread.currentThread().getName()); } }

测试类:

 package 线程组1;

 /**
* @author WYH
* @version 2019年11月23日 上午10:31:37
*/
public class MyRunnableDemo {
public static void main(String[] args) {
ThreadGroup tg = new ThreadGroup("这是一个新的线程组"); MyRunnable mr = new MyRunnable(); Thread t1 = new Thread(tg,mr,"王友虎");
Thread t2 = new Thread(tg,mr,"李智恩"); System.out.println(t1.getThreadGroup().getName());
System.out.println(tg.getName());
} }

  (5)线程池

    程序启动一个新的线程成本是比较高的,因为它涉及到要与操作系统进行交互,而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池。

      1、线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。

      2、在JDK5之前,我们必须手动实现自己的线程池,从JDk5开始,Java内置支持线程池。

    如何实现线程池的代码呢?

      1、创建一个线程对象,控制要创建几个线程对象。

        public static ExecutorService newFixedThreadPool(int nThread)

      2、这种线程池的线程可以执行:

        可以执行Runnable对象或者Callable对象代表的线程

        做一个类实现Runnable接口。

      3、调用下面的方法即可

        Future submit(Runnable task)

        <T> future<T> submit(Callable<T> task)

      4、我就要结束,可以吗? 可以。

        shutdown()

实现Runnable接口:

 package 线程池;

 /**
* @author WYH
* @version 2019年11月23日 上午11:08:38
*/
public class MyRunnable implements Runnable{ @Override
public void run() {
for(int x = 0;x<500;x++) {
System.out.println(Thread.currentThread().getName()+":"+x);
} } }

测试类:

 package 线程池;

 import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* @author WYH
* @version 2019年11月23日 上午11:09:57
*
* 线程池的创建
*/
public class ExecutorsDemo {
public static void main(String[] args) {
//创建线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
ExecutorService pool1 = Executors.newCachedThreadPool(); pool.submit(new MyRunnable());
pool.submit(new MyRunnable()); pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable()); pool.shutdown();
pool1.shutdown(); } }

  (6)多线程实现的第三种方案

MyCallable类:

 package com.wyh.callable;

 import java.util.concurrent.Callable;

 /**
* @author WYH
* @version 2019年11月23日 下午2:29:25
*/
public class MyCallable implements Callable { @Override
public Object call() throws Exception {
for(int x = 0;x<500;x++) {
System.out.println(Thread.currentThread().getName()+":"+x);
}
return null;
} }

测试类:

 package com.wyh.callable;

 import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* @author WYH
* @version 2019年11月23日 下午2:30:21
*
* 创建线程的第三种方式
*/
public class MyCallableDemo {
public static void main(String[] args) {
//创建线程池
ExecutorService pool = Executors.newFixedThreadPool(2); pool.submit(new MyCallable());
pool.submit(new MyCallable()); pool.shutdown();
} }

  (6_2)Callable的案例(计算1+....的总和 线程池实现)

Runnable类:

 package com.wyh.callable案例1;

 import java.util.concurrent.Callable;

 /**
* @author WYH
* @version 2019年11月23日 下午2:29:25
*/
public class MyCallable implements Callable<Integer> {
private int number; public MyCallable(int number) {
this.number = number;
} @Override
public Integer call() throws Exception {
int sum =0;
for(int x = 1;x<=number;x++) {
sum += x;
// System.out.println(Thread.currentThread().getName()+":"+sum);
}
// System.out.println(Thread.currentThread().getName()+":"+sum);
return sum;
} }

测试类:

 package com.wyh.callable案例1;

 import java.beans.FeatureDescriptor;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; /**
* @author WYH
* @version 2019年11月23日 下午2:30:21
*
* 创建线程的第三种方式
*/
public class MyCallableDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//创建线程池
ExecutorService pool = Executors.newFixedThreadPool(3); Future<Integer> f1 = pool.submit(new MyCallable(50));
Future<Integer> f2 = pool.submit(new MyCallable(100));
Future<Integer> f3 = pool.submit(new MyCallable(200)); int i1 = f1.get();
int i2 = f2.get();
int i3 = f3.get(); System.out.println(i1);
System.out.println(i2);
System.out.println(i3); pool.shutdown();
} }

  (7)多线程的面试题

    a:多线程有几种实现方案,分别是哪几种?

      两种。(面试答2种

        继承Thread类

        实现Runnable接口

        扩展一种,实现Callable接口,这个要和线程池结合使用。

    b:同步有几种方式,分别是是什么?

      两种。

        同步代码块  锁是任意对象锁

        同步方法   锁是this

        同步静态方法  锁是当前类的二进制字节码文件

    c:启动一个线程是run()还是start()?它们的区别?

      start()

        run():封装了被线程执行的代码块,直接调用仅仅是一个普通方法的调用

        start():启动线程,并由JVM自动调用run()方法

    d:sleep()和wait()方法的区别

      sleep():必须指定时间,不释放锁。

      wait():可以不指定时间,也可以指定时间,但是它释放锁。

    e:为什么wait(), notify(), notifyAll()等方法都定义在Object类中?

      因为这些方法的调用是依赖于锁对象的,而同步代码块的锁对象是任意锁。而Object代表任意对象,所以,定义在里面。

    f:线程的生命周期图(如上)

      新建 -- 就绪 -- 运行 -- 死亡

      新建 -- 就绪 -- 运行 -- 阻塞 -- 就绪 -- 运行 -- 死亡

2、设计模式(理解)

  (1)面试对象的常见设计原则

      单一职责原则

      开闭原则

      里氏替换原则

      依赖注入原则

      接口分离原则

      迪米特原则

  (2)设计模式概述和分类

    A:经验的总结

    B:三类:

      创建型

      结构型

      行为型

  (3)改进的设计模式

    A:简单工厂模式

Animal类:

 package 工厂设计模式;

 /**
* @author WYH
* @version 2019年11月23日 下午4:36:06
*/
public abstract class Animal {
public abstract void eat(); }

Animal

 package 工厂设计模式;

 /**
* @author WYH
* @version 2019年11月23日 下午4:37:44
*/
public class AnimalFactory {
private AnimalFactory(){ } public static Animal CreateAnimal(String type) {
if(type.equals("dog")) {
return new Dog();
}else if(type.equals("cat")) {
return new Cat();
}else {
return null;
}
} }

AnimalFactory

 package 工厂设计模式;

 /**
* @author WYH
* @version 2019年11月23日 下午4:37:16
*/
public class Cat extends Animal { @Override
public void eat() {
System.out.println("猫吃鱼"); } }

Cat

 package 工厂设计模式;

 /**
* @author WYH
* @version 2019年11月23日 下午4:36:45
*/
public class Dog extends Animal { @Override
public void eat() {
System.out.println("狗吃肉"); } }

Dog

 package 工厂设计模式;

 /**
* @author WYH
* @version 2019年11月23日 下午4:41:54
*/
public class FactoryDemo {
public static void main(String[] args) {
Animal a = AnimalFactory.CreateAnimal("dog");
a.eat();
Animal b = AnimalFactory.CreateAnimal("cat");
b.eat(); Animal c = AnimalFactory.CreateAnimal("pig");
if(c != null) {
c.eat();
}else {
System.out.println("对不起,该工厂无法造该对象.");
} } }

FactoryDemo

    B:工厂方法模式

 package 工厂方法模式;

 /**
* @author WYH
* @version 2019年11月23日 下午5:18:40
*/
public abstract class Animal {
public abstract void eat(); }

Animal

 package 工厂方法模式;

 /**
* @author WYH
* @version 2019年11月23日 下午5:19:23
*/
public interface Factory {
public abstract Animal CreateAnimal(); }

Factory

 package 工厂方法模式;

 /**
* @author WYH
* @version 2019年11月23日 下午5:20:39
*/
public class Dog extends Animal { @Override
public void eat() {
System.out.println("狗吃肉"); } }

Dog

 package 工厂方法模式;

 /**
* @author WYH
* @version 2019年11月23日 下午5:22:01
*/
public class DogFactory implements Factory { @Override
public Animal CreateAnimal() {
return new Dog();
} }

DogFactory

 package 工厂设计模式;

 /**
* @author WYH
* @version 2019年11月23日 下午4:37:16
*/
public class Cat extends Animal { @Override
public void eat() {
System.out.println("猫吃鱼"); } }

Cat

 package 工厂方法模式;

 /**
* @author WYH
* @version 2019年11月23日 下午5:23:46
*/
public class CatFactory implements Factory { @Override
public Animal CreateAnimal() {
return new Cat();
} }

CatFactory

 package 工厂方法模式;

 /**
* @author WYH
* @version 2019年11月23日 下午5:20:03
*/
public class FactoryDemo {
public static void main(String[] args) {
//我需要狗
Factory f = new DogFactory();
Animal a = f.CreateAnimal();
a.eat(); //我需要猫
f = new CatFactory();
Animal a1 = f.CreateAnimal();
a1.eat(); } }

FactoryDemo

    C:单例模式(掌握)

        a:饿汉式

Student类:

 package 单例模式;

 /**
* @author WYH
* @version 2019年11月23日 下午6:20:40
*/
public class Student {
// 将构造方法私有
private Student() { } // 自己创建一个对象
// 静态方法只能访问静态的成员变量,加static
// 为了不让外界随意改动这个对象,我们将他私有化
private static Student s = new Student(); // 提供一个方法给外界进行访问到这个对象
public static Student getStudent() {
return s;
} }

测试类:

 package 单例模式;

 /**
* @author WYH
* @version 2019年11月23日 下午6:20:47
*
* 单例模式:保证类在内存中指存在一个对象
* 饿汉式
*
*/
public class StudentDemo1 {
public static void main(String[] args) { Student s1 = Student.getStudent();
Student s2 = Student.getStudent(); System.out.println(s1 == s2);
} }

        b:懒汉式

Teacher类:

 package 单例模式;

 /**
* @author WYH
* @version 2019年11月23日 下午6:32:09
*
* 懒汉式
*/
public class Teacher {
private Teacher() { } private static Teacher teacher = null; public synchronized static Teacher getTeacher() {
if(teacher == null) {
teacher = new Teacher();
} return teacher;
} }

测试类:

 package 单例模式;

 /**
* @author WYH
* @version 2019年11月23日 下午6:34:12
*/
public class TeacherDemo {
public static void main(String[] args) {
Teacher t1 = Teacher.getTeacher();
Teacher t2 = Teacher.getTeacher(); System.out.println(t1 == t2);
System.out.println(t1);
System.out.println(t2); } }

(注意:面试的时候写懒汉式,开发的时候写饿汉式,因为饿汉式不存在线程安全问题)

  (4)Runtime

      JDK提供的一个单例模式应用的类

      还可以通过dos命令。

例子:

 package 单例模式;

 import java.io.IOException;

 /**
* @author WYH
* @version 2019年11月23日 下午6:43:36
*
* 饿汉式的一个类的例子
*
*
*/
public class RunTimeDemo {
public static void main(String[] args) throws IOException {
Runtime r = Runtime.getRuntime();
// r.exec("calc"); //调出计算器
// r.exec("shutdown -s -t 10000");
r.exec("shutdown -a");
}
} /*
* 源码:
*
* class Runtime{
* private Runtime() {}
* private static Runtime currentRuntime = new Runtime();
* public static Runtime getRuntime() {
* return currentRuntime;
* }
*
* }
*/

大数据之路week03--day05(线程 II)的更多相关文章

  1. 大数据之路week03--day05(线程 I)

    真的,身体这个东西一定要爱护好,难受的时候电脑都不想去碰,尤其是胃和肾... 这两天耽误了太多时间,今天好转了立刻学习,即刻不能耽误!. 话不多说,说正事: 1.多线程(理解) (1)多线程:一个应用 ...

  2. 大数据之路week01--自学之集合_1(Collection)

    经过我个人的调查,发现,在今后的大数据道路上,集合.线程.网络编程变得尤为重要,为什么? 因为大数据大数据,我们必然要对数据进行处理,而这些数据往往是以集合形式存放,掌握对集合的操作非常重要. 在学习 ...

  3. 大数据之路week07--day03(Hadoop深入理解,JAVA代码编写WordCount程序,以及扩展升级)

    什么是MapReduce 你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查并且数出有多少张是黑桃. MapReduce方法则是: 1.给在座的所有玩家中分配这摞牌 2.让每个玩家数自己手中的牌有几 ...

  4. 大数据之路week04--day06(I/O流阶段一 之异常)

    从这节开始,进入对I/O流的系统学习,I/O流在往后大数据的学习道路上尤为重要!!!极为重要,必须要提起重视,它与集合,多线程,网络编程,可以说在往后学习或者是工作上,起到一个基石的作用,没了地基,房 ...

  5. 大数据之路week04--day03(网络编程)

    哎,怎么感觉自己变得懒了起来,更新博客的频率变得慢了起来,可能是因为最近得知识开始变得杂变得难了起来,之前在上课的时候,也没有好好听这一方面的知识,所以,现在可以说是在学的新的知识,要先去把新的知识思 ...

  6. C#码农的大数据之路 - 使用C#编写MR作业

    系列目录 写在前面 从Hadoop出现至今,大数据几乎就是Java平台专属一般.虽然Hadoop或Spark也提供了接口可以与其他语言一起使用,但作为基于JVM运行的框架,Java系语言有着天生优势. ...

  7. 胖子哥的大数据之路(11)-我看Intel&&Cloudera的合作

    一.引言 5月8日,作为受邀嘉宾,参加了Intel与Cloudera在北京中国大饭店新闻发布会,两家公司宣布战略合作,该消息成为继Intel宣布放弃大数据平台之后的另外一个热点新闻.对于Intel的放 ...

  8. 胖子哥的大数据之路(10)- 基于Hive构建数据仓库实例

    一.引言 基于Hive+Hadoop模式构建数据仓库,是大数据时代的一个不错的选择,本文以郑商所每日交易行情数据为案例,探讨数据Hive数据导入的操作实例. 二.源数据-每日行情数据 三.建表脚本 C ...

  9. 胖子哥的大数据之路(9)-数据仓库金融行业数据逻辑模型FS-LDM

    引言: 大数据不是海市蜃楼,万丈高楼平地起只是意淫,大数据发展还要从点滴做起,基于大数据构建国家级.行业级数据中心的项目会越来越多,大数据只是技术,而非解决方案,同样面临数据组织模式,数据逻辑模式的问 ...

随机推荐

  1. TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option

    先解决他 详细不详解 在初始化 加上 --explicit_defaults_for_timestamp=true 即可

  2. NIO理解

    ByteBuffer Test: package java_guide; import java.nio.ByteBuffer; public class ByteBufferMethods { pu ...

  3. 三个思路解决413 Request Entity Too Large报错处理

    最近一个项目当中,要求上传图片,并且限制图片大小,虽然在laravel当中已经添加了相关的表单验证来阻止文件过大的上传,然而当提交表单时,还没轮到laravel处理,nginx就先报错了.当你仔细看报 ...

  4. Java线程安全队列Queue实现原理

    原文链接:https://www.cnblogs.com/DreamRecorder/p/9223016.html 在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列.J ...

  5. 给出一个javascript的Helloworld例子

    1.基础知识:Helloworld:例 1.1<html><head>    <!--  如果你用notepad建立一个txt之后你再改为html,一定在存时,要存成ut ...

  6. go 结构体2 文法

    结构体文法表示通过结构体字段的值作为列表来新分配一个结构体. 使用 Name: 语法可以仅列出部分字段.(字段名的顺序无关.) 特殊的前缀 & 返回一个指向结构体的指针. //分配的v1结构体 ...

  7. uboot 与 代码重定位

    ref: https://blog.csdn.net/dhauwd/article/details/78566668 https://blog.csdn.net/yueqian_scut/articl ...

  8. 监听lsnrctl status查询状态报错linux error 111:connection refused

    报错现象 今天给客户一个单实例环境配置监听,创建正常,查询状态异常报错 tns tns tns linux error :connection refused 匹配MOS Starting TNS L ...

  9. (二)Activiti之用activiti.cfg.xml配置文件初始化表

    一.案例 本章案例使用activiti 5.19.0.2版本 1.1 引入maven依赖 <dependencies> <dependency> <groupId> ...

  10. js对象 c#对象转换

    前台页面 js 创建对象 let t = {}; 数组对象 let c = []; c.push({}) ;// 添加对象 以string格式 传递 JSON JSON.stringify(c); c ...