-
Java多线程--1.启动、休眠、优先级
2018-04-18 18:08:27仅作为Java多线程的复习梳理笔记,如果有错误希望大家批评指出 1.使用Java多线程 继承Thread类: public class MyThread extends Thread{ @Override public void run() { // 重写run()方法,这个方法就是线程进入...仅作为Java多线程的复习梳理笔记,如果有错误希望大家批评指出
1.使用Java多线程
- 继承
Thread
类:
public class MyThread extends Thread{ @Override public void run() { // 重写run()方法,这个方法就是线程进入running状态后要运行的方法 super.run(); System.out.println(Thread.currentThread().getName()); } public static void main(String[] args) { // 因为是继承自Thread类,所以可以直接创建线程对象 Thread t1 = new MyThread(); Thread t2 = new MyThread(); // 调用start()方法以后,该线程会进入ready状态 // 操作系统会进行调度,根据调度算法线程可能会进入running状态 // 只有线程真正进入running状态以后,CPU才会执行该线程的代码 t1.start(); t2.start(); } }
打印输出结果:
Thread-1 Thread-0
直接继承自
Thread
类是实现Java多线程最直接的一种方式,因为是继承自Thread
类,所以可以直接创建线程对象,线程运行时执行的代码或者方法需要放在重写父类的run()
方法里。- 实现
Runnable
接口
如果当当前类已近有一个父类,这时候就不能再继承
Thread
类,所以可以实现Runnable
接口来使用多线程。public class MyThread implements Runnable{ @Override public void run() { // 实现Runnale类一定要重写run()方法 // 因为接口的方法是抽象方法,所以必须得实现 System.out.println(Thread.currentThread().getName()); } public static void main(String[] args) { // 创建线程传入Runnale接口的实例 // 因为我们实现了Runnale接口,所以MyThread类的实例就是它的实例 // 后面的参数是此线程的线程名 Thread t1 = new Thread(new MyThread(),"线程1"); Thread t2 = new Thread(new MyThread(),"线程2"); t1.start(); t2.start(); } }
打印结果:
线程1 线程2
2.常用方法
public static void main(String[] args) { System.out.println(Thread.currentThread()); System.out.println(Thread.currentThread().getPriority()); System.out.println(Thread.currentThread().getName()); System.out.println(Thread.currentThread().getId()); System.out.println(Thread.currentThread().isAlive()); }
输出:
Thread[main,5,main] 5 main 1 true
Thread.currentThread()
:获取当前正在运行的线程的指针Thread.getPriority()
:获取该线程的优先级Thread.getName())
:获取线程的名字Thread.getId()
:获取该线程在JVM中的IDThread.isAlive()
:获取该线程的存活状态,只要是调用了start()方法以后,无论是该线程处在ready状态还是running状态,该线程都是存活状态。
3.线程休眠
public class MyThread implements Runnable{ @Override public void run() { // 分别打印:线程名,休眠开始前系统时间,休眠结束后系统时间 System.out.println(Thread.currentThread().getName()); System.out.println(System.currentTimeMillis()); try { // 调用Thread.sleep(millis),使当前线程休眠1000毫秒 Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(System.currentTimeMillis()); } public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new MyThread(),"线程1"); Thread t2 = new Thread(new MyThread(),"线程2"); t1.start(); // 调用join()方法以后,其他线程会等待该线程死亡以后再继续运行 // 其他线程包括主线程,都会处于等待状态(原理是使用了同步锁) t1.join(); t2.start(); } }
打印结果:
线程1 1523976884092 1523976885092 线程2 1523976885093 1523976886094
可以看到调用
Thread.sleep()
方法以后,当前线程就进入一种休眠状态,也就是说这个线程会什么也不做的读过这段时间,要注意的是,该线程并不会释放同步锁。4.优先级
在操作系统中,线程可以划分优先级,优先级越高的线程的到的CPU资源越多,设置线程优先级有助于操作系统决定下一次选择哪一个线程来优先执行(但是操作系统调度线程和优先级具有随机性)
public class MyThread implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()); } public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new MyThread(),"线程1"); Thread t2 = new Thread(new MyThread(),"线程2"); // 优先级划分等级从1-10 // 不在这个范围之内会抛出异常 t1.setPriority(1); t2.setPriority(10); t1.start(); t2.start(); } }
打印结果:
线程2 线程1
当然也有可能打印结果:
线程1 线程2
因为:
- 线程优先级和代码执行顺序无关,但往往优先级高的线程完成同样的任务,结束时间要高于优先级低的线程(因为CPU资源分配更多)
- 优先级不代表优先执行该线程,而只是操作系统会尽量给予更多地CPU运算能力。
5.总结
- Java线程的本质:在JDK1.2以前,Java曾经使用自己的
Green Thread
实现了用户级别的线程(ULP),但是由于用户级别的线程存在种种问题(比如线程阻塞时和进程就会出现不一致问题),JDK1.2以后,JVM选择了交给操作系统进行线程管理(通过系统调用),也就是操作系统中常说的轻量级进程(LWP)。对于Windows系统,明确的划分了进程和线程两种数据结构,进行了较好的多线程实现,对于Linux系统,依旧是使用了进程的方式实现了线程。 - Java线程模型和操作系统线程的关系:参考我的另一篇文章–Java线程和操作系统线程的关系
- 继承
-
Java中PriorityQueue梳理和解析
2020-04-29 09:39:39PriorityQueue 一个基于优先级的优先级队列。队列中的元素按照其自然顺序(比如数值类型从小到大的顺序)进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。该队列不允许使用 ...1、概述
PriorityQueue 一个基于优先级的优先级队列。一定要与Collections中是sort区分开。此队列仅仅保证队首元素最小或者队首元素最大,可作为大根堆或者小根堆看待。队列中的元素按照其自然顺序(比如数值包装Integer、Long等类型,按照从小到大的顺序排序,注意,注意,注意,这个排序不是对全部元素进行排序,仅仅保证队首与剩余元素的关系。比如,如果按照自然顺序排序的话,假设有n个元素,排序后仅仅保证队首元素不大于剩下的n-1个元素,但是剩下的n-1个元素之间未必是非递减的。与Collections中的sort方法不同,sort是对所有元素进行排序,保证所有元素大小关系的一致性,左面都不大于右面或者左面都不小于后面。但是,PriorityQueue 中只保证队首与剩余元素的关系的一致性,队首不大于剩下的所有元素或者队首不小于剩下的所有元素)进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。该队列不允许使用 null 元素也不允许插入不可比较的对象(没有实现Comparable接口的对象)。根据排序规则不同,PriorityQueue 队列的头指向排序规则中的最值元素。如果多个元素都是最值则随机选一个。PriorityQueue 是一个无界队列,但是初始的容量(实际是一个Object[]),随着不断向优先级队列添加元素,其容量会自动扩容,无需指定容量增加策略的细节。
2、常用方法
(1)构造方法:
PriorityQueue()使用默认的初始容量(11)创建一个 PriorityQueue,并根据其自然顺序来排序其元素(使用 Comparable)。
PriorityQueue(int initialCapacity)使用指定的初始容量创建一个 PriorityQueue,并根据其自然顺序来排序其元素(使用 Comparable)。
PriorityQueue(int initialCapacity, Comparator comparator)使用指定的初始容量创建一个 PriorityQueue,并根据指定的比较器comparator来排序其元素。
(2)peek():返回队首元素
(3)poll():返回队首元素,队首元素出队列
(4)add():添加元素
(5)size():返回队列元素个数
(6)isEmpty():判断队列是否为空,为空返回true,不空返回false
3、关于排序规则
(1)普通类型:比如Integer,Long等类型,默认使用升序的排序方式,也即默认队首是最小的元素。如果想降序排列,则要自定义降序规则。
如下:k指定了初始容量,并通过new Comparator重写了compare方法,实现了降序规则
PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(k, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});案例:
import java.util.PriorityQueue; public class Main { public static void main(String[] args) { PriorityQueue<Integer> queue = new PriorityQueue<>(); queue.add(0); queue.add(5); queue.add(1); queue.add(3); for(Integer fac : queue){ System.out.println(fac); } System.out.println("------------"); while(queue.size() != 0){ System.out.println(queue.remove()); } } }
打印结果:
0
3
1
5
------------
0
1
3
5分析:元素中加入0,5,1,3后打印的结果是0,3,1,5。可见队首0是最小的元素,队首不大于剩下的元素,而且剩下的元素未必是非递减的。while循环逐个删除打印队首并删除,结果是0,1,3,5,由此可知,每次删除元素后,队列都重新进行了排序,保证队首最小。
(2)自定义类型
两种定义排序规则的方式,如同Collections中的sort方法(可以参考Java中Collections.sort()案例讲解)
(1)类实现接口
import java.util.PriorityQueue; public class Main { public static void main(String[] args) { PriorityQueue<PriorityQueueTest> queue = new PriorityQueue<>(); queue.add(new PriorityQueueTest(5,"world")); queue.add(new PriorityQueueTest(1,"bing")); queue.add(new PriorityQueueTest(3,"bao")); queue.add(new PriorityQueueTest(0,"hello")); for(PriorityQueueTest fac : queue){ System.out.println(fac.num+" "+fac.name); } System.out.println("------------"); while(queue.size() != 0){ PriorityQueueTest removeFac = queue.remove(); System.out.println(removeFac.getNum()+ " "+ removeFac.getName()); } } } class PriorityQueueTest implements Comparable<PriorityQueueTest>{ int num; String name; public PriorityQueueTest(int num, String name) { this.num = num; this.name = name; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public String getName() { return name; } public void setName(String name) { this.name = name; } // 此类实现Comparable接口,重写了compareTo方法,自定义按照升序排列:按照num升序排序 @Override public int compareTo(PriorityQueueTest o) { return this.num - o.num; } }
打印结果:
0 hello
1 bing
3 bao
5 world
------------
0 hello
1 bing
3 bao
5 world(2)在新建PriorityQueue实例时候,通过构造方法来的new Comparator参数来自定义排序规则
案例:
import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.PriorityQueue; public class Main { public static void main(String[] args) { PriorityQueue<PriorityQueueTest> queue = new PriorityQueue<PriorityQueueTest>(new Comparator<PriorityQueueTest>() { @Override public int compare(PriorityQueueTest o1, PriorityQueueTest o2) { return o2.getNum() - o1.getNum(); } }); queue.add(new PriorityQueueTest(5,"world")); queue.add(new PriorityQueueTest(1,"bing")); queue.add(new PriorityQueueTest(3,"bao")); queue.add(new PriorityQueueTest(0,"hello")); for(PriorityQueueTest fac : queue){ System.out.println(fac.num+" "+fac.name); } System.out.println("------------"); while(queue.size() != 0){ PriorityQueueTest removeFac = queue.remove(); System.out.println(removeFac.getNum()+ " "+ removeFac.getName()); } } } class PriorityQueueTest{ int num; String name; public PriorityQueueTest(int num, String name) { this.num = num; this.name = name; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
打印结果:
5 world
1 bing
3 bao
0 hello
------------
5 world
3 bao
1 bing
0 hello可知,在PriorityQueue的构造方法中传入new Comparator,然后自定义compare方法来实现排序。
注意:PriorityQueue存储的元素要求必须是可比较的对象, 如果不是就必须明确指定比较器
-
c语言常用知识点梳理
2019-06-10 16:47:54c语言常用知识点: 知识点1:交换两个变量值的方法 采用第三方变量(最容易想到的方法) 采用加减法进行值得交换(面试时常用**) 代码如下: ...因为[]的优先级高于*,所以结合顺序不一样,所表示的...c语言常用知识点:
知识点1:交换两个变量值的方法
- 采用第三方变量(最容易想到的方法)
- 采用加减法进行值得交换(面试时常用**)
代码如下:
b = a - b; a = a - b; b = a + b;
采用按位异或的位方式
代码如下:
a = a^b; b = a^b; a = a^b;
知识点2:(*p)[3]与*p[3]的区别
因为[]的优先级高于*,所以结合顺序不一样,所表示的含义也不一样。
- (*p)[3]:p先和*结合,表示p是一个指针,然后和[3]结合,表示指向一个维度为3的数组,合起来的意思就是p指向一个n行3列的二维数组。
- *p[3]:p先个[3]结合,表示p是一个数组,然后再和*结合,表示里面存的是指针,合起来的意思就是p是一个3行的数组,数组里面存的指针。
知识点3:sizeof的使用
- sizeof是一种运算符不要想当然理解为函数
- sizeof使用时可以不加()
- sizeof可以加变量、常量、数据类型
- 跟数据类型是必须加()
知识点4:#include编译预处理命令与多文件团队开发
- include编译预处理命令可以认为是:将后面的文件内容拷贝到当前的文件中
- 多文件团队开发:模块分别编译成.o都不能链接成功,合起来链接生成最终程序。
- 链接:把项目中所有相关联的.o目标文件、C语言函数库合并在一起,生成可执行文件
- 函数的定义放.c文件,函数的声明放.h文件
- 如果要使用某个.c文件中定义的函数,只需要#include这个.c文件对应的.h文件
- h文件的作用:被别人拷贝。编译链接的时候不需要管.h文件
知识点5:数组的几种初始化方式如下
int a[3] = {10, 9, 6}; int a[3] = {10,9}; int a[] = {11, 7, 6}; int a[4] = {[1]=11,[0] = 7};(知道有此种初始化方式即可)
知识点6:数组的内存分析和注意点
- 存储空间的划分(内存的分配是从高地址到低地址进行的,但一个数组内部元素又是从低到高进行的)【注:对于以后学习重要】
- 数组名的作用,查看元素地址
- 注意数组不要越界
知识点7:字符串知识点
- "123”其实是由’1’、‘2’、‘3’、’\0’组成
- 字符串的输出"%s",’\0’是不会输出的
知识点8:字符串处理函数:strlen()
- 计算的是字符数,不是字数
- 计算的字符不包括’\0’,一个汉字相当于3个字符
例子:“哈haha” 字符数为7
指针部分:
知识点9:指针定义的格式
变量类型 *变量名
如 int *p
知识点10:指针作用
能够根据一个地址值,访问对应的存储空间
例:
int *p; int a = 90; P = &a; *p = 10;//把10赋值给p所指的存储空间
知识点11:指针使用注意
- int *p只能指向int类型的数据
- 指针变量只能存储地址
- 指针变量未经初始化不要拿来间接访问其他存储空间
知识点12:指针与数组
遍历数组
int ages[5] = {10, 4, 9, 44, 99}; for(int i = 0; i<5; i++){ printf("%d\n", ages[i]); }
使用指针遍历数组:
int *p;// 指针变量P指向了数组的首地址 p = &ages[0];// 使用指针遍历数组 for(int i = 0; i<5; I++){ printf("ages[%d] = %d\n", i, *(p + i)); }
- 注:指针+ 1取决于指针的类型
- 注:数组的访问方式
- 数组名[下标]
- 指针变量名[下标]
- *(p+i)
知识点13:指针与字符串
定义字符串的两种方式
-
利用数组
char name[] = “Andyzhao”特点:字符串里的字符可以修改
适用场合:字符串内容需要经常修改
-
利用指针
char *name = “itcast”
特点:字符串是一个常量,字符串里面的字符不能修改
使用场合:字符串的内容不需要修改,而这个字符串经常使用
知识点13:预处理指令(三种):
- 宏定义
- 条件编译
- 文件包含
- 宏定义的配对使用和带参数的宏
带参数的宏
# define sum(v1,v2) ((v1) + (v2))//括号是必须的
例如:
#define pingfang1(a) a*a #define pingfang2(a) (a*a) 想想,为什么结果为不一样呢?? pingfang1(4)/pingfang1(2)//结果为16 pingfang2(4)/pingfang2(2)//结果为4
- 带参数的宏效率比函数高
- 条件编译(一般是判断宏的值)
#if 条件 ... #elif 条件 ... #else ... #endif(非常重要)不然后面的代码全部无效
- 文件包含
<>表示系统自带的文件,""表示自定义文件
不允许循环包含,比如a.h包含b.h,b.h又包含a.h
知识点14:typedef 只是给类型起了个别名并不是定义新类型
struct Student{ int age; char *name; }; typedef struct Student Student; 等价于 typedef struct Student{ int age; char *name; }Student; 也等价于 typedef struct { int age; char *name; }Student;
类似的给枚举类型起名
typedef enum Sex{ Man,Women }Sex;
- 下面这种情况的写法比较特殊
//下面是函数指针类型的自定义数据类型,返回值类型和参数类型要匹配 #include typedef int (*TypeFuncPointer)(int, int); int add(int a, intb){ return a + b; } int minus(int a, intb){ return a - b; } int main(){ TypeFuncPointer p = add;//使用自定义类型Î TypeFuncPointer p2 = minus;//使用自定义类型Î printf("add = %d\n",p(1, 2)); printf("minus = %d\n",p2(1, 2)); return 0; }
下面是定义结构体的指针类型
typedef struct Student{ int age; char *name; }*PtrStu; //使用方式 Student stu ={18, "zhangsan"}; PtrStu p = &stu;
宏定义也是可以为类型起名的
#define Integer int
相当于
typedef int Integer
注意和typedef的区别
例如:typedef char * String #define String char *
知识点15:static和extern区别是能否进行跨文件访问
- 函数
- 变量
对函数的作用
外部函数:定义的函数能被本文件和其他文件访问
内部函数;定义的函数只能被本文件访问
默认情况下,所有函数都是外部函数(相当于带关键字extern),所以可以省略extern作用:完整的定义和引用一个外部函数都加extern
引用时也是默认是外部函数所以也省略extern
static作用:定义一个内部函数
使用:static返回类型函数名(参数列表)
不能被其他文件调用
一个项目中,本文件的外部函数名不能和其他文件的外部函数同名(error)
本文件中的内部函数(static)可以和其他文件的函数名同名的
对变量的作用:
全局变量分为两种:
外部变量:定义的变量可以被其他文件访问
- 默认情况下所有的全局变量都是外部变量
- 不同文件中的同名外部变量都代表同一个
- 定义一个外部变量不加extern,声明才加extern
同样的声明是没有错误的
内部变量:定义的变量不能被其他文件访问
不同文件的同名内部变量互不影响
-
Ruby基础知识梳理
2015-10-18 23:55:51了解ruby,安装ruby和使用irb关于ruby(解释型语言),执行ruby文件Ruby基础知识常用基本概念和方法 puts, p 单引号”和双引号”“, 字符串嵌入,“#{abc}” 数值表示和计算 注释 运算符及优先级 对象、变量和常量 ...了解ruby,安装ruby和使用irb
关于ruby(解释型语言),执行ruby文件
Ruby基础知识
常用基本概念和方法
- puts, p
- 单引号”和双引号”“, 字符串嵌入,“#{abc}”
- 数值表示和计算
- 注释
- 运算符及优先级
对象、变量和常量
- Ruby中一切皆对象
- 弱变量类型,局部变量,全局变量,实例变量,类变量
- 常量/变量命名规范,保留字
- 多重赋值,交换变量值,获取数组元素
条件判断
- 真假值,逻辑运算符 && || !, 不推荐使用 and or
- if, elsif, unless, case
- if/unless修饰符;
循环
- while, until, loop(较少使用)
- 迭代器,times, each(常用),block
- 循环控制,break, next, redo
方法
- 调用
- 返回值
- 实例方法
- 类方法
- 定义
- 参数, 个数不确定
- 语法糖(拟态方法)
类和模块
- 类和实例,继承
- class,intialize,attr_accessor, self
- 实例变量,类变量, 实例方法,类方法,常量
- public, protected, private, alias,undef
- 模块 module,命名空间,include,extend,prepend
- 祖先链 ancestors
- 方法查找规则
异常处理
异常分类
- ScriptError
- LoadError, SyntaxError
- StandarError
- RuntimeError, NameError(NoMethodError), ArgumentError, TypeError, …
捕获异常 rescue
- rescue修饰符
- 抛出异常 raise
- 后处理 ensure
- 重试 retry
Ruby 常用类库
提示: 需要区分Rails的方法和Ruby原生方法
数值类
- Numeric
- Integer(Fixnum, Bignum), Float, Rational(有理数), Complex
- 数值字面量,进制,数值运算
- div,quo,modulo,divmod,remainder
- 数值类型转换
- 位运算
- 随机数,rand
- times,upto,downto,step
- Math模块, Comparable模块
Array
- 数组的创建
[],new,%w, %i, to_a, String#split - 索引,[],获取元素,赋值,values_at
- 交集&,并集|, +, -
- 常用方法
- shift, unshift, <<, push, pop, concat, +, [],
- compact, delete, delete_at, delete_if, reject!,
- slice!, uniq!, collect!, map!, fill,
- flatten!, reverse!, sort!, sort_by
- inject, any?, all?, select, each, each_with_index, one?
- Enumerable模块
String
- 字符串创建
“”, ”, %Q, %q, Here Document, sprintf; - 常用方法
- size, length, count, empty?,
- [], +, ==, <, >,
- split, chop!, chomp!, strip!, encode!,
- index, include?, sub!, gsub!,
- slice!, concat/+, delete!, reverse!,
- upcase!, downcase!, swapcase!, capitalize!
Symbol
- Symbol#to_s
- String#to_sym
Hash
- 创建
{}, Hash.new; 值获取与设定;默认值; - 常用方法
- keys, values, to_a, fetch;
- key?(key), has_key?, include?, member?, value?, has_value?;
- size, length, empty?
- delete, delete_if, reject!
- clear, each;
- merge update
- Enumerable模块
- Hash作为方法调用的最后一个参数时,可以不加括弧 “{}”
正则表达式 Regexp
- 创建
- //, Regexp.new, %r()
- 匹配
- =~, !~;
- match方法
- 匹配普通字符
- 行首与行尾匹配
- ^, $,
- 字符串首部和尾部匹配
- \A, \Z
- 指定匹配字符的范围
[] - 匹配任意字符
- ”.”
- 使用反斜杠的模式
- \s, \d, \w, \A, \z, \(字符串转义)
- 重复
- *, +, ?, {}, ()
- 最短匹配
- *?, +?
- 正则表达式的选项
- i, x, m
- 捕获
- 1,2, ‘,&, $’(这三个依次表示:匹配部分前面、匹配部分本身、匹配部分后面的字符串)
- sub, gsub, scan
File
- 继承关系
- File.ancestors # => [File, IO, File::Constants, Enumerable, Object, Kernel, BasicObject]
- 常用类方法
- File.rename, File.delete, File.unlink,
- File.open, File.new, File.close
- File.basename, File.dirname, File.extname,
- File.split, File.join, File.expand_path
- File::Stat类
- File.stat, File.ctime, File.mtime, File.atime, File.utime
- File.chmod, File.chown
- FileTest模块
- exist?, file?, directory?,
- owned?, grpowned?, readable?, writable?, executable?,
- size, size?, zero?
其他重要的类和模块
- Object
- Kernal
- Module
- Enumerable
- IO
- Encoding
- Time
- Date
- Proc
- Dir
参考书籍:《Ruby基础教程-第4版》
-
概念梳理类之Java中的多线程简介
2021-01-29 19:01:15提示:线程概念梳理 文章目录Java中的多线程之线程概念简介前言一、多线程是什么?二、线程的生命周期2.线程优先级3.通过 Implements Runnable接口创建线程4.通过extends Thread类创建线程5.Thread类中的线程方法:... -
this指向undefined uiapp_一文梳理JavaScript中的this
2021-01-06 12:53:12this指向this在全局范围内this在对象的构造函数内this在对象的方法内this在简单函数内this在箭头函数内this在一个事件侦听器内this绑定规则默认绑定隐式绑定显示绑定(this修改)优先级箭头函数1. this是什么?this是... -
C++基础梳理 2019.1.14 (内联函数的引出-宏缺陷以及内联函数和编译器处理,函数的占位参数,函数重载的实现...
2019-01-14 02:13:382、展开是无脑展开,很容易因为符号优先级的问题而产生一些错误。(下图代码中宏函数为了防止出错,将每一个变量都加了小括号) 3、宏函数没有作用域 内联函数 类内部成员函数默认会添加i... -
工作方法总结
2019-10-18 09:13:09个人工作方法的总结 第一步,梳理个人工作的范围,确定需要沟通的具体部门或者人员,确认联系方式。 第二步,根据范围梳理哪些工作是日常工作,每周或每月例行工作,一次性工作,确定每周例行要完成的工作任务,并... -
【白雪红叶】JAVA学习技术栈梳理思维导图.xmind
2018-04-25 20:28:30优先级 引用 语言工具类库 容器类 集合 链表 map 工具类 系统类 日期类 数字类 字符串+正则 流 字符流 字节流 语言特性 继承 封装 多态 JVM 多线程与并发 GC机制 GC收集器类型 串行 CMS ... -
敏捷方法与Scrum
2020-09-03 16:04:55通过不断梳理需求的优先级来消除在低价值需求上的资源浪费, 通过提高沟通效率来消除团队沟通上的资源浪飞, 鼓励团队在一起工作,使得团队信息更加紧密、更透明。敏捷开发通过细分项目的交付目标灵活轻便的管理方式... -
我的产品方法论之需求分析(下)
2021-02-25 09:21:12前文说到,作为产品经理,需求分析的核心方法分别为:在遇见单个需求时,首先要分析用户、场景、问题以及现有解决方案,利用思维导图将思考过程完整记录并梳理,从中筛选并提炼出最有价值的信息与开发方向。... -
产品经理的工作方法论
2020-12-30 10:21:57在遇见单个需求时,首先要分析用户、场景、问题以及现有解决方案,利用思维导图将思考过程完整记录并梳理,从中筛选并提炼出最有价值的信息与开发方向。 在遇见海量需求时,要明确需求优先级排序原则,逐一运用四... -
Matlab的p文件分析与操作方法
2021-01-24 20:22:51面对大量的p文件,开始时用了可行但是比较麻烦的方法,即:在p文件下新建同名的m文件,然后进行单步调试,这样就能够通过同名m文件的调用顺序确定p文件的调用,至少能够梳理p文件的调用关系(p文件优先级高于m文件)... -
syb需求分析问卷_数据分析方法8—KANO分析模型
2020-12-25 12:52:17背景介绍需求会因人而异,会因文化差异而不同,也会随着时间的变化,作为产品设计者,应该持续调研需求,...为了避免直接拍脑袋给出解决方案,就需要一套科学的分析方法,真正从用户需求出发来梳理出需求层次以及需... -
智能客服搭建(5)——5步骤之一定义对话系统
2020-12-21 22:53:48确定优先级(首先要实现的功能)和关键信息要素(实现功能所需要的信息)2.任务要素梳理(定义变量)四、撰写故事线 一、定义对话系统的方法 以下方法论其实就是在定义对话系统,后面的 确定场景边界 梳理业务... -
用正则表达式实现的计算器
2019-09-19 07:55:47首先我们应该先梳理一下计算器的实现过程,当然,有几种实现方法。先从最简单的开始讲吧。下面是计算器的思考流程。 1,考虑计算的优先级 ()的优先级最高,其次是乘除,最后是加减 2,算最里面括号的值,并代替... -
syb需求分析问卷_需求分析神器:KANO分析模型详解
2020-12-25 12:51:55背景介绍需求会因人而异,会因文化差异而不同,也会随着时间的变化,作为产品设计者,应该...为了避免直接拍脑袋给出解决方案,就需要一套科学的分析方法,真正从用户需求出发来梳理出需求层次以及需求的优先级,并... -
Java 学习笔记(1)基础的基础
2020-05-16 12:45:05这里写自定义目录标题1、简单输出2、注释3、标识符4、变量5、常量8、运算符 和 运算优先级9、获取键盘输入 COVID-19大寒假期间在家学习Java渐感力不从心,眼见快要开学,因此下定决心开始梳理知识点。 1、简单输出... -
HTML学习笔记_引用CSS样式
2020-09-25 21:28:19内部样式一、行内样式(内联样式)二、内部样式表(嵌入样式)外部样式Link链导入式小结四种CSS使用方法优先级 多种引用CSS样式的方法? 内部样式 一、行内样式(内联样式) 在开始标签内,添加style样式属性 如下: ... -
更优秀的延迟初始化方案
2019-04-12 15:34:58背景:梳理了application和mainactivity的代码之后,有些任务,它的优先级其实并没有那么高,所以,可以将它进行延迟初始化。延迟到界面显示后再进行加载。 最简单的方案是将代码移动到界面显示之后,界面显示之后... -
如何构建一套完整的VR设计流程
2021-02-25 18:52:14按优先级排序,分为四个部分:工作流程,各角色在团队中需要关注的内容和分工;设计工具的使用;用户研究方法,用户需求管理;设计原则(设计规范)归纳和建立。如下图所示:以下是对四个部分的内容进行具体的 -
Spark性能优化总结
2018-01-29 17:56:46vcores + 480G memory,一天的日志可在2.5小时内跑完,下面对一些优化的思路方法进行梳理。 优化的目标 保证大数据量下任务运行成功降低资源消耗提高计算性能 三个目标优先级依次递减,首要解决的是... -
用研项目需求分析沟通中的五个“坑”
2020-02-20 08:47:50对于用户研究项目来说,同样也不例外,项目需求的分析是否清晰明确,将直接影响需求优先级的确定、研究方法的选取、研究结论的方向以及研究价值的体现。清晰明确的需求分析,也是一个用户研究人员专业性的体现。 ...
-
MySQL 索引
-
MySQL 性能优化(思路拓展及实操)
-
主流嵌入式芯片手册S3C2440-S5PV210-IMX6ULL-STM32MP157-AM335.rar
-
2.数据类型、表达式和基本运算
-
【爱码农】C#制作MDI文本编辑器
-
OpenGL入门教程
-
MySQL 视图
-
Win10_LTSB_2016_X64_Extrem.esd
-
MySQL 函数、用户自定义函数
-
基于Flink+Hudi构建企业亿级云上实时数据湖教程(PC、移动、小
-
安卓底层和应用开发!Android社招最全面试题,震撼来袭免费下载!
-
《python数据分析与数据化运营》3.rar
-
系统分析师 复习笔记精华版.pdf
-
BTC使用的技术
-
fwknop ubuntu dockerfile.rar
-
MySQL 触发器
-
安卓开发api!闭关在家37天“吃透”这份345页PDF,深度解析,值得收藏
-
网盘分享教师资格证备考复习资料高频考点速记手册 幼儿园 小学 中学 分享
-
tensorflow1代码,softmax(无隐层)实现mnist数据集分类
-
全能地图下载器-MapTileDownloader v3.0