Other

Ruby的method_missing

用过ruby人对method_missing肯定不陌生,通常我们利用这一神技来实现调用不存在的方法,以便进行回调,利用它可以很方便的实现我们自己的DSL。 在学习method_missing之前,先理解下ruby方法调用过程 当ruby对象执行某一方法时,他需要找到这个方法,其查找流程如下: 1、查询当前对象的实例方法 2、查找当前对象所有模块,看是否有该方法 3、查找该对象的父类及父类模块(就是找他爹,他爹没有,再找它爷。。。) 4、如果这个对象很不幸没爹,那就直接到Object中找 5、到BasicObject中查找 如果还没找到,调用内核的method_missing方法,最终丢出NoMethodError 由上可知,method_missing是方法调用的最后一道防线,我们可以把method_missing理解为“方法找不到时,该做什么” 所以,我们可以在方法查询的任何位置通过重写method_missing的方式告诉ruby,“哥们,这方法如果没找到,就这样做。。。” 一、方法代理 方法代理使用的比较多的,通过method_missing让当前对象使用另外一个类的方法 举例: class A def do_this p this is class A end end class B def initialize @proxy = A.new end def method_missing(method_name, *args, &block) p this is class B @proxy.do_this end end b = B.new b.do_this b在查找do_this方法时,由于找不到,所以进入我们重写的method_missing中,在这里我们 通过class的实例对象proxy来执行A中的do_this方法。 二、编写DSL 通过上面的例子,可以知道method_missing可以对不存在的方法进行拦截,然后做我们想做 的事,这就为DSL的编写提供了很大的便利,我们在method_missing中对我们要执行的方法 进行解析,判断是不是满足我们所定义的语法等等,然后进行我们需要的操作,很多自动化测试框架就是使用这种方式的,通过定义自己的DSL可以让代码更具业务化。

mysql和oracle这两个数据库的差别

1、、Oracle数据库要收费,MySQL是免费的。本质: Oracle数据库是一个对象关系数据库管理系统;MySQL是一个开源的关系数据库管理系统,是世界上用的最多的数据库; 2、数据库的安全性,Oracle数据库安全。验证方法: MySQL使用三个参数来验证用户,即用户名,密码和位置; Oracle使用了用户名,密码,配置文件,本地身份验证,外部身份验证,高级安全增强功能等。 3、语法: Oracle数据库对SQL语句的扩展。在普通SQL语句的使用上增加了编程语言的特点(PL / SQL编程语言)使其更加灵活。Oracle的SQL * Plus工具提供了比MySQL更多的命令,用于生成报表输出和变量定义。 4、对象名称的区别: Oracle对所有对象名称都不区分大小写;而某些MySQL对象名称(如数据库和表)区分大小写(取决于底层操作系统)。 5、储存空间: 与Oracle相比,MySQL没有表空间,角色管理,快照,同义词和包以及自动存储管理。 6、临时表处理方式上的区别等等。 MYSQL 临时表只在当前会话中存在,(查询数据时)会话结束就删除了,空间很小 Oracle 临时表一旦创建就会存在,直到它们被显式删除。 Oracle 临时表具有适当权限的所有会话都可见,但各自用户只能看到自己的数据,数据可能在事务或用户会话期间持续存在。    

javascript原生实现http get和post

httpRequest.readyState状态码参照表 值 状态 描述 0 UNSENT 代理被创建,但尚未调用 open() 方法。 1 OPENED open() 方法已经被调用。 2 HEADERS_RECEIVED send() 方法已经被调用,并且头部和状态已经可获得。 3 LOADING 下载中; responseText 属性已经包含部分数据。 4 DONE 下载操作已完成。 1. Get方法 // 用我自己的接口做演示 // 接口地址 : https://api.wer.plus <script> // 建立一个req对象 var httpRequest = new XMLHttpRequest(); // 使用方法GET,参数url,默认true,建立连接,true表示是异步 httpRequest.open('GET', 'http://api.wer.plus:8080/api/today?token=949aa9b7d39715aa6d32ac77e0c00a0a', true); // 发送请求 httpRequest.send(); // onreadystatechange表示当以上请求的状态码发生改变后再触发函数 httpRequest.onreadystatechange = function () { // httpRequest.

nginx重新整理——————http请求的11个阶段中的content阶段[十八]

前言 简单介绍一下content 阶段。 正文 下面介绍一下root和alias。 这个前面其实就提交过了,这里再说明一下。 功能都是一样的:将url映射为文件路径,以返回静态文件内容。 差别:root 将完整url映射进文件路径中alias只会将location后的url映射到文件路径中。 访问文件的三个变量: request_filename 待访问文件的完整路径 document_root 由URI和root/alias规则生成的文件夹路径 realpath_root 将document_root 中的软链接等换成真实路径(假如有软链接会换成真实路径) 静态文件返回时的content-type: 关闭404日志: 访问目录时url 最后没有带/? static 模块实现了root/alias 功能时,发现访问目标是目录,单url末尾未加/ 时,会返回301重定向。 下面整理一些index 和 autoindex。 index 先于autoindex 作用。 对访问/时的处理: content 阶段的index 模块。 ngx_http_index_module 模块 syntax: index file ...; default: index index.html; context: http,server,location; 如果是autoindex。 那么当url以/结尾时,尝试以html/xml/json/jsonp 等格式返回 root/alias 中指定目录的目录结构 ngx_http_index_module 默认编译进nginx: --without-http_autoindex_module 取消。 autoindex_exact_size 显示相对路径还是绝对路径。 autoindex_format 确定哪种格式向用户返回。(html|xml|json|jsonp) autoindex_localtime 时间是否是本地时间。 下面介绍一下多个小文件的问题。 ngx_http_concat_module 其实原理就是这样的,多个文件合并成一个文件body,提升性能。 结 下一节access.log。

4.函数与异常处理应用编程

1 print(sum) 2 sum = 42 3 print(sum) 4 def inc(n): 5 sum = n+1 6 print(sum) 7 return sum 8 sum = inc(7) + inc(7) 9 print(sum)  2.实验任务2 task2_1.py def func1(a, b, c, d, e, f): ''' 返回参数a,b,c,d,e,f构成的列表 默认,参数按位置传递; 也支持关键字传递 ''' return [a,b,c,d,e,f] def func2(a, b, c,*, d, e, f): ''' 返回参数a,b,c,d,e,f构成的列表 *后面的参数只能按关键字传递 ''' return [a,b,c,d,e,f] def func3(a, b, c, /, d, e, f): ''' 返回参数a,b,c,d,e,f构成的列表 /前面的参数只能按位置传递 ''' return [a,b,c,d,e,f] # func1调用:按位置传递、按参数传递都可以 print( func1(1,9,2,0,5,3) ) print( func1(a=1, b=9, c=2, d=0, e=5, f=3) ) print( func1(1,9,2, f=3, d=0, e=5)) # func2调用:d,e,f必须按关键字传递 print( func2(11, 99, 22, d=0, e=55, f=33) ) print( func2(a=11, b=99, c=22, d=0, e=55, f=33) ) print( func2(11, 99, 22, 0, 55, 33) ) # func3调用:a,b,c必须按位置传递 print( func3(111, 999, 222, 0, 555, 333)) print( func3(111, 999, 222, d=0, e=555, f=333)) print(func3(a=111, b=999, c=222, 0, 555, 333))   task2_2.

java基础知识

一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。一个类可以有很多方法,逻辑运算、数据修改以及所有动作都是在方法中完成的。(所以除了定义变量其他语句都需要写在方法里,在我工作2年的时候我还纳闷语句为啥不能直接写在类里) 静态方法不能调用非静态成员(变量和方法),编译会报错 默认构造方法的访问修改符和类的访问修改符相同(类为 public,构造函数也为 public;类改为 private,构造函数也改为 private)。一旦你定义了自己的构造方法,默认构造方法就会失效。 假设P为父类,C为子类, P p=new C();//这是进行上转型 对子类C进行向上转型之后,使用父类对象p去调用方法,只能调用父类有的方法; C c=(C)p;//这是进行下转型 向下转型必须是在已经向上转型的基础上进行,进行下转型后,对象c能够调用C类的所有方法,类似C=new C()。 thows和thow throws 声明异常 当一个方法产生一个它不处理的异常时,那么就需要在该方法的头部声明这个异常,以便将该异常传递到方法的外部进行处理。使用 throws 声明的方法表示此方法不处理异常。 throw 拋出异常 当 throw 语句执行时,它后面的语句将不执行,此时程序转向调用者程序,寻找与之相匹配的 catch 语句,执行相应的异常处理程序。如果没有找到相匹配的 catch 语句,则再转向上一层的调用程序。这样逐层向上,直到最外层的异常处理程序终止程序并打印出调用栈情况。 区别: throws 用来声明一个方法可能抛出的所有异常信息,表示出现异常的一种可能性,但并不一定会发生这些异常;throw 则是指拋出的一个具体的异常类型,执行 throw 则一定抛出了某种异常对象。 通常在一个方法(类)的声明处通过 throws 声明方法(类)可能拋出的异常信息,而在方法(类)内部通过 throw 声明一个具体的异常信息 char本来就是ACSII码,实质上就是数字,数字怎么比较他就怎么比较,直接==; char型变量存放的其实是对应的字符码的值,即存的是int型的数。即charNum = ‘1’ 与int类型的intNum = 1进行比较,实际上是将 charNum1 = ‘1’ 的acs码:49 与 1 进行比较,因此肯定不相等,返回false。

操作系统实验六 信号量实现进程同步

操作系统实验六 信号量实现进程同步 【实验目的】 ​ 进程同步是操作系统多进程/多线程并发执行的关键之一,进程 同步是并发进程为了完成共同任务采用某个条件来协调他们的活动,这是进程之间发生的一种直接制约关系。本次试验是利用信号量进行进程同步。 【实验软件环境】 ​ VC++或者 Linux 操作系统 【实验内容】 生产者进程生产产品,消费者进程消费产品。 当生产者进程生产产品时,如果没有空缓冲区可用,那么生产 者进程必须等待消费者进程释放出一个缓冲区。 当消费者进程消费产品时,如果缓冲区中没有产品,那么消费 者进程将被阻塞,直到新的产品被生产出来 【实验程序及分析】 ​ 通过使用sem_t类型的信号量full,empty, mutex来实现对两个消费者进程和一个生产者进程之间的同步问题。需要特别注意的是,对信号量需要进行互斥访问,所以需要P(mutex)和V(mutex)夹紧互斥访问的操作。 #include <semaphore.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> sem_t *full, *empty, *mutex; void *createSharedMemory(size_t size) { void *addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); if (addr == MAP_FAILED) { return NULL; } return addr; } int main(){ full = (sem_t*)createSharedMemory(sizeof(sem_t)); empty = (sem_t*)createSharedMemory(sizeof(sem_t)); mutex = (sem_t*)createSharedMemory(sizeof(sem_t)); if (full == NULL || empty == NULL || mutex == NULL) { printf(creat share memory error\n); return 0; } sem_init(full, 10, 0); sem_init(empty, 10, 6); sem_init(mutex, 10, 1); pid_t pid1 = fork(); int i = 0; if (pid1 > 0) { while(1) { //生产 sem_wait(empty); sem_wait(mutex); sem_post(full); int value; sem_getvalue(full, &value); printf(Producer %d: produce 1 thing, now there are %d things\n, getpid(), value); sem_post(mutex); i++; sleep(2); } } else if (pid1 == 0) { pid_t pid2 = fork(); if (pid2 > 0) { //消费 while(1){ sleep(2); sem_wait(full); sem_wait(mutex); int value; sem_getvalue(full, &value); printf(Customer %d: use 1 thing, now there are %d things\n, getpid(), value); sem_post(mutex); sem_post(mutex); sleep(2); } } else if (pid2 == 0) { pid_t pid3 = fork(); if (pid3 > 0) { //消费 while(1){ sleep(2); sem_wait(full); sem_wait(mutex); int value; sem_getvalue(full, &value); printf(Customer %d: use 1 thing, now there are %d things\n, getpid(), value); sem_post(mutex); sem_post(empty); sleep(2); } } } } return 0; } 【实验截图】 【实验心得与体会】 ​ 在本次上机中,通过对信号量full, empty, mutex的sem_wait()和wem_post()操作,对通过PV操作来实现进程同步的方法理解更加深刻,同时对linux操作环境下进程的创建、共享内存的创建、信号量的初始化、信号量的操作也更加熟悉。

C++基础知识测试

1:构造函数有几种: a:默认构造函数 b:复制(拷贝)构造函数 c:初始化构造函数 d:转换构造函数 e:移动构造函数  2:赋值函数有几种 a:拷贝赋值 b:操作符“=”重载为赋值函数  3:纯虚函数不能再哪些函数内使用 a:从基类构造函数直接调用 b:从基类析构函数直接调用 c:从基类构造函数间接调用 d:从基类析构函数间接调用 e:通过悬空指针调用  4:修正下面代码 stuct Object{ Object(int a,int b); };   5:修正下面代码  参考连接:https://blog.csdn.net/guotianqing/article/details/103298909 struct Object{ ~Object() { this->func(); mObj->func(); } virtual void func() = 0; Object* mObj; } 改为: struct Object{ ~Object() {  //this->func(); 不能在基类构造函数和析构函数中直接或间接调用虚函数 //mObj->func(); 不能用悬空指针调用虚函数 } virtual void func() = 0; Object* mObj;  } 6:test 方法将调用哪个func方法

【jvm】内存结构

一。程序计数器  程序计数器是线程私有的。  每个线程都拥有一个程序计数器,用来记住吓一条指令的执行地址。  程序计数器不会发生内存溢出,也就是oom。 二。虚拟机栈  虚拟机栈是线程私有的。  虚拟机栈是用来存放栈帧的地方。  栈帧是每一次调用方法时所占用的内存。  栈帧中的结构有:  局部变量表: 用来存储方法中的局部变量。  基本数据类型数值。  reference  returnAddress  操作数栈: 当运行字节码文件时,会将数据临时存储其中(iload)。  动态链接: 在多态的情况下,当编译源代码时无法确定对象的类型,所以只能在运行时才能确定对象,指向常量池中的方法,将符号引用变成直接引用。  方法出口: 也就是方法返回地址,正常结束时返回地址,如果报错时返回异常地址。 三。本地方法栈  本地方法栈是线程私有。  本地方法栈时用来为虚拟机的native方法提供服务,这些方法由c++编写。 四。堆  堆不是线程私有的,是线程共享。  堆是存放各种对象的地方,也包括类对象,也是jvm垃圾回收机制回收的重点方法。  在1.7之后,stringTable也放入了堆中,便于垃圾回收(fullGC)。  堆内存诊断工具:  1. jps 工具 查看当前系统中有哪些 java 进程  2. jmap 工具 查看堆内存占用情况 jmap - heap 进程id  3. jconsole 工具 图形界面的,多功能的监测工具,可以连续监测 五。方法区