推荐 最新
无事小神仙

Oracle数据库修改进程连接数

一、查询Oracle数据库进程连接数首选用Oracle工具PL/SQL登录到Oracle数据库,执行下面的命令,查看Oracle当前的进程连接最大数量:select value,t.* from v$parameter t where name = 'processes'; 我们可以看到,Oracle数据库默认只支持最大150个客户端连接。如果是生产环境,这些数量肯定是不够的。下面我们来修改这个参数,把它改到500。二、修改Oracle数据库进程连接数为500继续在PL/SQL工具的SQL窗口中执行下面命令,修改Oracle的连接数为500:alter system set processes=500 scope=spfile; 执行成功后,直接查第一步的语句发现还是150。我们需要重启Oracle数据库使这个配置生效。。三、Windows下重启Oracle数据库,使配置生效3.1、关闭Oracle数据库监听服务以管理员权限打开命令窗口,使用lsnrctl命令来关闭监听服务,输入:lsnrctl stop关闭Oracle的监听器服务后,我们下一步需要登录Oracle数据库,用命令停止Oracle实例。3.2、用sqlplus以sysdba身份登录到Oracle数据库以管理员权限打开命令窗口,输入:sqlplus / as sysdba以sysdba身份登录到数据库。3.3、立即关闭Oracle数据库登录到数据库后,我们来把Oracle数据库关闭掉,输入命令:shutdown immediate我们可以看到,数据库已关闭。已经卸载数据库。ORACLE例程已经关闭。这就代表Oracle数据库已经被我们关闭掉了。现在再去用PL/SQL登录Oracle数据库发现已经登录不上了。3.4、退出sqlplus,回到命令行现在我们来退回到命令行,继续输入:exit退出了sqlplus。3.5、启动Oracle数据库监听服务我们在命令行,重新把Oracle监听服务开起来。输入命令:lsnrctl start查看监听发现没有运行任何实例。是的,上面我们已经把数据库关闭了,所以没有实例是正常的。3.6、用sqlplus以sysdba身份登录到Oracle数据库然后,我们需要重新登录到Oracle数据库中,把Oracle‘数据库实例启动起来。执行以下命令:sqlplus / as sysdba我们用sqlplus命令登录到了数据库。3.7、启动Oracle数据库我们继续把Oracle数据库实例启动起来,继续输入命令:startup我们能现在可以看到,Oracle数据库已经装载完毕、数据库已经打开。3.8、退出sqlplus,回到命令行我们再退回到命令行。3.9、查看Oracle数据库监听服务状态我们再把Oracle数据库监听服务的状态查看一下,输入命令:lsnrctl status我们可以看到,现在Oracle监听服务已经能够发现“tzq”这个实例了。说明数据库运行正常。四、重新查询Oracle数据库进程连接数我们重新用PL/SQL登录到Oracle数据库,再次查看Oracle进程最大连接数,执行以下查询SQL:select value,t.* from v$parameter t where name = 'processes';发现Oracle进程最大连接数已经被修改成了500。至此,Oracle修改进程连接数教程也演示完毕!

0
0
0
浏览量2075
无事小神仙

Oracle查锁表(史上最全)

Oracle分两种锁,一种是DDL锁,一种是DML锁。一、Oracle DDL锁的解锁(dba_ddl_locks视图)1.1、查表的DDL锁的详情(kill session脚本、表名、执行锁表的SQL等)查DDL锁的数据字典,SQL如下:SELECT DISTINCT 'alter system kill session ''' || s.sid || ',' || s.serial# || ',@' || s.inst_id || ''' immediate;' AS kill_session_scripts ,s.sql_id ,a.sql_text ,s.sid ,s.serial# FROM dba_ddl_locks l ,gv$session s ,gv$sqlarea a WHERE 1 = 1 AND l.session_id = s.sid AND s.sql_id = a.sql_id AND lower(a.sql_text) NOT LIKE '%alter system kill session %' -- AND l.owner IN ('TZQ','LOG') ; 查表的DDL锁的详情的查询结果如下图所示:.2、解锁表的DDL锁有两种方式可以解锁表的DDL锁一是:执行kill session脚本。二是:调用tzq_server_pkg包的kill_session存过执行杀会话kill session。1.2.1、解锁表的DDL锁 - 1、执行kill session脚本Ⅰ、打开命令窗口Ⅱ、执行上面生成好的kill session脚本alter system kill session '314,93,@1' immediate;1.2.2、解锁表的DDL锁 - 2、调用tzq_server_pkg包的kill_session存过执行杀会话kill session。tzq_server_pkg包的代码详见博客:Oracle解锁表、包、用户、杀会话、停job打开命令行窗口,执行下面命令:set serveroutput on execute sys.tzq_server_pkg.kill_session(6335,15519); 二、Oracle DML锁的解锁(gv$locked_object视图)2.1、查表的DML锁的详情(kill session脚本、表名、执行锁表的SQL等)查DML锁的数据字典,SQL如下:SELECT DISTINCT 'alter system kill session ''' || s.sid || ',' || s.serial# || ',@' || s.inst_id || ''' immediate;' AS kill_session_scripts ,o.owner ,o.object_name ,s.sql_id ,a.sql_text ,s.sid ,s.serial# FROM gv$locked_object l ,dba_objects o ,gv$session s ,gv$sqlarea a WHERE l.object_id = o.object_id AND l.session_id = s.sid AND l.inst_id = s.inst_id AND s.sql_id = a.sql_id -- AND o.owner IN ('TZQ','LOG') ; 查表的DML锁的详情的查询结果如下图所示:2.2、解锁表的DML锁有两种方式可以解锁表的DML锁。一是:执行kill session脚本。二是:调用tzq_server_pkg包的kill_session存过执行杀会话kill session。2.2.1、解锁表的DML锁 - 1、执行kill session脚本Ⅰ、打开命令窗口Ⅱ、执行上面生成好的kill session脚本alter system kill session '314,93,@1' immediate;2.2.2、解锁表的DML锁 - 2、调用tzq_server_pkg包的kill_session存过执行杀会话kill session。打开命令行窗口,执行下面命令:set serveroutput on execute sys.tzq_server_pkg.kill_session(6335,15519);三、附录3.1、根据sid查sql_text(gv$session、gv$sqlarea)SELECT s.sid ,s.serial# ,s.sql_id ,s.sql_hash_value ,s.username ,a.sql_text FROM gv$session s LEFT JOIN gv$sqlarea a ON s.sql_id = a.sql_id WHERE s.sql_id IS NOT NULL AND a.sql_text NOT LIKE '%AND a.sql_text NOT LIKE %' ; 3.2、查锁表的详情(dba_locks视图)SELECT DISTINCT 'alter system kill session ''' || s.sid || ',' || s.serial# || ',@' || s.inst_id || ''' immediate;' AS kill_session_scripts ,l.session_id ,s.serial# ,l.lock_TYPE ,l.mode_held ,l.mode_requested ,CASE WHEN o1.object_name IS NOT NULL THEN o1.owner||'.'||o1.object_name ELSE NULL END AS id1_object_name ,CASE WHEN o2.object_name IS NOT NULL THEN o2.owner||'.'||o2.object_name ELSE NULL END AS id2_object_name ,l.last_convert ,l.blocking_others ,a.SQL_TEXT FROM dba_locks l LEFT JOIN dba_objects o1 ON l.lock_id1 = o1.OBJECT_ID LEFT JOIN dba_objects o2 ON l.lock_id2 = o2.OBJECT_ID LEFT JOIN gv$session s ON l.session_id = s.SID LEFT JOIN v$sqlarea a ON s.sql_id = a.sql_id WHERE 1=1 AND a.SQL_TEXT IS NOT NULL AND (o1.owner IN ('TZQ','LOG') OR o2.owner IN ('TZQ','LOG')) ; 3.3、Oracle查询锁定表的会话信息(gv$session、gv$process、gv$sqlarea)Oracle查询锁定表的会话信息,可以执行下面的SQL来进行查询:SELECT s.sid ,s.serial# ,p.spid ,s.username ,s.osuser ,s.program ,s.module ,s.action ,s.logon_time ,s.type ,a.sql_text FROM gv$session s ,gv$process p ,gv$sqlarea a WHERE s.paddr = p.addr AND s.sql_id = a.sql_id AND s.status = 'ACTIVE' AND s.username IS NOT NULL AND s.type != 'BACKGROUND' AND a.sql_text NOT LIKE '%gv$sqlarea a%' ORDER BY s.logon_time DESC; 3.4、gv$lock视图此查询将返回被锁定的表的会话ID、用户名、机器名、锁模式、锁定类型以及锁定对象的ID等信息。请注意,如果有多个锁定类型,则此查询可能会返回多行。SELECT s.sid ,s.serial# ,s.username ,s.osuser ,s.machine ,l.type ,l.block ,l.id1 ,l.id2 ,a.SQL_TEXT ,CASE WHEN o1.object_name IS NOT NULL THEN o1.owner||'.'||o1.object_name ELSE NULL END AS id1_object_name ,CASE WHEN o2.object_name IS NOT NULL THEN o2.owner||'.'||o2.object_name ELSE NULL END AS id2_object_name FROM gv$session s ,gv$lock l ,gv$sqlarea a ,dba_objects o1 ,dba_objects o2 WHERE s.sid = l.sid AND s.sql_id = a.sql_id AND l.id1 = o1.OBJECT_ID(+) AND l.id2 = o2.OBJECT_ID(+) AND a.SQL_TEXT NOT LIKE '%,gv$sqlarea a%' ; 查询结果如下图:

0
0
0
浏览量2049
青椒肉丝加点糖

MySQL(一)认识MySQL、常用管理命令、列类型列约束、查询语句

一、软件生命周期和计算机数据存储方式1. 软件生命周期        定义期:可行性研究阶段/需求分析阶段;        开发期:概要设计阶段/详细设计阶段/编码实现阶段/测试阶段;        维护期:部署阶段/维护阶段。2. 计算机对数据的存储,有4个方面通过特定的文件如excel、word等存储,只适用于存储小量数据且速度慢;内存,临时存储,运行时会有数据产生并存储,结束运行后数据即销毁;速度快;第三方云服务器,共享;数据库服务器。MySQL属于数据库服务器存储的范畴。二、数据库        数据库的作用就是按照一定的形式组织存放数据,目的是为便于操作数据,即增、删、改、查。数据库的发展历程为:网状数据库-->层次型数据库-->关系型数据库(RDBMS)-->非关系型数据库。1. 常见的关系型数据库SQLite——微型数据库,常用于移动端MySQL——开源RDBMS,是一种关联数据库管理系统,将数据库保存在不同的库中,每个库可包含多个表,表中可以有多行多列的数据,可用于各种操作系统SQL Server——Microsoft开发的中型数据库,只适用于Windows操作系统Oracle——Oracle开发的中大型数据库,可用于各种操作系统DB2——IBM开发的中大型数据库,常与IBM服务器搭配2. MySQL部署结构        MySQL部署分服务器端和客户端,服务器端负责存储维护数据,客户端负责连接服务器端,对数据进行增删改查操作。使用客户端连接服务器端时只需要执行命令:mysql.exe -h127.0.0.1 -P3306 -uroot -p -h,host IP地址/域名 eg:127.0.0.1/localhost(永远指向自己本身的电脑) -P,port 端口(此处为3306端口) -u,user 用户名(root是管理员账户,在root下密码为空) -p,password 密码此命令也可以简写为:mysql -uroot3. 常用管理命令(必须以英文“;”结尾)quit;  退出连接show databases;  显示当前所有数据库use 数据库名称;  进入指定的数据库show tables;  显示当前数据库下的所有数据表desc 数据表名称;  描述数据表中都有哪些列4. 常用SQL命令以及举例(1)定义数据结构(DDL)drop database if exists jd; //丢弃数据库jd(存在的基础上) create database jd; //创建数据库jd use jd; //进入数据库jd create table student ( id int, name varchar ( 8 ), sex varchar ( 1 ), score int ); //创建表student,包括id、name、sex、score四列 (2)操作数据(DML)insert into student values('1','张三','M','99'); //向student表中插入一行数据 delete from user where uid="2";  //删除uid为2的行数据 update user set upwd="666666",isOnline="n" WHERE uid="3"; //修改uid为3的行密码为666666,在线状态为n(3)查询数据(DQL)select * from student; //查询student表中的所有数据三、列类型        列类型指在创建数据表时,指定的列所能存储的数据类型。1. 数值型2. 日期时间型3. 字符串型    字符串型和日期时间型 必须加引号四、列约束        列约束的意思是MySQL对要插入的数据进行特定的验证,只有符合条件才允许插入(位于列类型之后)。1. 主键约束  primary key        声明了主键约束的列,不允许插入重复,一个表中只能有一个主键约束,通常用于编号列,可加快数据查找速度。        自增列 Auto_increment:自动增长,声明了自增列,插入数据时只需要赋值为 null,就会获取最大值然后加1插入。声明了自增列也允许手动赋值。2. 非空约束  not null        声明了非空约束的列上禁止插入Null。3. 唯一约束  unique        声明了唯一约束的列不允许插入重复的值,但是 unique 允许插入重复的 null 甚至多个 null,一个表中可以有多个唯一约束。4. 默认值约束  defaul        可以使用 default 关键字设置默认值,default使用时不加引号。5. 检查约束  check        也称自定义约束,用户可以制定约束的条件。但是 MySQL 不支持检查约束,认为会极大影响数据插入数据,后期需要通过 JS 实现。6. 外键约束  foreign        声明了外键约束的列称为外键列,这一列取值范围到另一个表的主键中,是为了让两个表建立关联。外键约束用法特殊,常用于创建表的最后一行,外键列要和对应的主键列的列类型保持一致。格式如下:格式:foreign key(外键列) references 另一个表(主键列) eg:foreign key(familyId) references family(fid)五、MySQL查询语句注:以下举例中 ,emp为员工表,dept为部门表1. 简单查询(1)查询特定的列     eg:查询所有员工的编号和姓名 select eid,ename from emp;(2)查询所有的列     eg:查询员工表emp中所有信息 select * from emp;(3)给列起别名       eg:查询所有员工的编号和姓名并起别名 select eid as 编号,ename as 姓名 from emp;(4)显示不同的记录eg:查询有哪些性别的员工 select distinct sex from emp;(5)查询时执行计算eg:查询所有员工姓名及年薪 select ename,salary*12 from emp;(6)查询结果排序     eg:查询所有部门数据,结果按照编号升序排列 select * from dept order by did asc;(7)条件查询             eg:查询编号为5的员工的数据 select * from emp where eid=5;(8)模糊条件查询     eg:查询姓名中含有“e”的员工 select * from emp where ename like "%e%"; % 表示匹配任意个字符, _ 表示匹配一个字符,以上两个匹配符须结合like关键字使用(9)分页查询        当查询的结果中数据太多,一次显示不完,就可以使用分页显示。分页查询需要两个已知条件:当前页码+每页数据量。语法:select * from emp limit 开始查询的值, 每页的数据量;eg:假设每页显示五条数据,分别查出前三页 第1页:select * from emp limit 0,5; 第2页:select * from emp limit 5,5; 第3页:select * from emp limit 10,5; 注意:开始查询的值=(当前的页码-1)* 每页数据量2. 复杂查询(1)聚合查询/分组查询eg:通过员工编号查询员工数量 select count(eid) from emp; eg:查询各部门员工 最高工资,员工数量,平均工资 select max(salary),count(*),avg(salary),deptId from emp group by deptId; eg:查询所有员工出生的年份 select year(birthday) from emp;(2)子查询多个SQL命令的组合,把一个SQL命令的结果作为另一个命令的条件; eg:查询高于平均工资的男员工 select * from emp where sec=1 && salary>(select avg(salary) from emp); eg:查询和Tom同一年出生的员工 select * from emp where year(birthday)=(select year(birthday) from emp where ename="Tom") && ename!="Tom";(3)多表查询查询的列分布在不同的表中时,用多表查询(前提:表和表之间必须有关联); eg:查询所有员工的姓名及部门名称 select emp.ename,dept.dname from emp,dept where emp.deptId=dept.did;select ename,dname from emp left outer join dept on deptId=did;

0
0
0
浏览量2048
无事小神仙

Oracle解锁表、包、用户、杀会话、停job

一、创建包tzq_server_pkgsys用户以sysdba身份登录Oracle数据库,创建包 tzq_server_pkg ,上代码:CREATE OR REPLACE PACKAGE sys.tzq_server_pkg IS PROCEDURE unlock_table(table_owner IN VARCHAR2, table_name IN VARCHAR2); PROCEDURE unlock_package(package_owner IN VARCHAR2, package_name IN VARCHAR2); PROCEDURE unlock_user(username IN VARCHAR2); PROCEDURE stop_job(job_id IN NUMBER); PROCEDURE kill_session(se_sid IN NUMBER, se_serail# IN NUMBER); PROCEDURE grant_pris(username IN VARCHAR2); END tzq_server_pkg; / CREATE OR REPLACE PACKAGE body SYS.tzq_server_pkg IS PROCEDURE unlock_table(table_owner IN VARCHAR2, table_name IN VARCHAR2) IS CURSOR c1 IS SELECT DISTINCT '''' || s.sid || ',' || s.serial# || ',@' || s.inst_id || '''' AS si_id FROM gv$locked_object l ,dba_objects o ,gv$session s WHERE l.object_id = o.object_id AND l.session_id = s.sid AND l.inst_id = s.inst_id AND o.owner = upper(table_owner) AND o.object_name = upper(table_name); c1_rec c1%ROWTYPE; v_sql VARCHAR2(2000); BEGIN FOR c1_rec IN c1 LOOP v_sql := 'alter system kill session ' || c1_rec.si_id || ' immediate'; dbms_output.put_line(v_sql); BEGIN EXECUTE IMMEDIATE v_sql; EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLERRM); END; END LOOP; END unlock_table; PROCEDURE unlock_package(package_owner IN VARCHAR2, package_name IN VARCHAR2) IS CURSOR c1 IS SELECT DISTINCT '''' || a.sid || ',' || a.serial# || ',@' || a.inst_id || '''' AS si_id FROM gv$session a ,gv$access b WHERE b.object = upper(package_name) AND b.owner = upper(package_owner) AND a.sid = b.sid AND a.inst_id = b.inst_id; c1_rec c1%ROWTYPE; v_sql VARCHAR2(2000); BEGIN FOR c1_rec IN c1 LOOP v_sql := 'alter system kill session ' || c1_rec.si_id || ' immediate'; dbms_output.put_line(v_sql); BEGIN EXECUTE IMMEDIATE v_sql; EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLERRM); NULL; END; END LOOP; END unlock_package; PROCEDURE unlock_user(username IN VARCHAR2) IS us_name VARCHAR2(200) := username; v_sql VARCHAR2(2000); BEGIN v_sql := 'alter user ' || us_name || ' account unlock'; BEGIN EXECUTE IMMEDIATE v_sql; dbms_output.put_line(us_name || '''s account is unlock'); EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLERRM); END; END unlock_user; PROCEDURE stop_job(job_id IN NUMBER) IS CURSOR c1 IS SELECT DISTINCT '''' || a.sid || ',' || a.serial# || ',@' || a.inst_id || '''' AS si_id FROM gv$session a ,(SELECT v.sid ,v.id2 job ,v.inst_id inst_id FROM sys.job$ j ,gv$lock v WHERE v.type = 'JQ' AND j.job(+) = v.id2) b ,gv$instance c WHERE a.inst_id = b.inst_id AND a.sid = b.sid AND a.inst_id = c.inst_id AND c.inst_id = b.inst_id AND b.job = job_id; c1_rec c1%ROWTYPE; v_sql VARCHAR2(2000); BEGIN FOR c1_rec IN c1 LOOP v_sql := 'alter system kill session ' || c1_rec.si_id || ' immediate'; dbms_output.put_line(v_sql); BEGIN EXECUTE IMMEDIATE v_sql; EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLERRM); NULL; END; END LOOP; END stop_job; PROCEDURE kill_session(se_sid IN NUMBER, se_serail# IN NUMBER) IS p_sid NUMBER := se_sid; p_serail NUMBER := se_serail#; is_back_process NUMBER := 0; CURSOR c1 IS SELECT DISTINCT '''' || a.sid || ',' || a.serial# || ',@' || a.inst_id || '''' AS si_id FROM gv$session a WHERE a.sid = p_sid AND a.serial# = p_serail; c1_rec c1%ROWTYPE; v_sql VARCHAR2(2000); BEGIN IF se_sid IS NULL OR se_serail# IS NULL THEN dbms_output.put_line('sid is null or serail# is null'); RETURN; END IF; BEGIN SELECT 1 INTO is_back_process FROM gv$session WHERE sid = se_sid AND serial# = se_serail# AND TYPE = 'BACKGROUND'; EXCEPTION WHEN OTHERS THEN is_back_process := 0; END; IF is_back_process = 1 THEN RETURN; END IF; FOR c1_rec IN c1 LOOP v_sql := 'alter system kill session ' || c1_rec.si_id || ' immediate'; dbms_output.put_line(v_sql); BEGIN EXECUTE IMMEDIATE v_sql; EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLERRM); NULL; END; END LOOP; END kill_session; PROCEDURE grant_pris(username IN VARCHAR2) IS us_name VARCHAR2(200) := username; v_sql VARCHAR2(2000); v_sql2 VARCHAR2(2000); v_sql3 VARCHAR2(2000); v_sql4 VARCHAR2(2000); v_sql5 VARCHAR2(2000); v_sql6 VARCHAR2(2000); v_sql7 VARCHAR2(2000); BEGIN v_sql := 'grant create synonym,create table,create type,create sequence,create view ,create materialized view,create job,create database link,connect,resource,create procedure ,debug any procedure, debug connect session to ' || us_name; v_sql2 := 'grant select on gv_$locked_object to ' || us_name; v_sql3 := 'grant select on dba_objects to ' || us_name; v_sql4 := 'grant select on gv_$session to ' || us_name; v_sql5 := 'grant select on gv_$process to ' || us_name; v_sql6 := 'grant select on gv_$sql to ' || us_name; v_sql7 := 'grant select on gv_$access to ' || us_name; BEGIN EXECUTE IMMEDIATE v_sql; EXECUTE IMMEDIATE v_sql2; EXECUTE IMMEDIATE v_sql3; EXECUTE IMMEDIATE v_sql4; EXECUTE IMMEDIATE v_sql5; EXECUTE IMMEDIATE v_sql6; EXECUTE IMMEDIATE v_sql7; dbms_output.put_line('grant success!'); EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLERRM); END; END grant_pris; END tzq_server_pkg; / 二、授权给需要使用的用户logsys用户以sysdba身份登录Oracle数据库,给需要使用该包(sys.tzq_server_pkg)的用户授予  的权限,执行下面命令授权:grant execute on sys.tzq_server_pkg to log; 三、解锁表:执行存过unlock_table(schema_name, table_name)以上面被授权的log用户,打开命令行窗口,执行下列SQL:set serveroutput on execute sys.tzq_server_pkg.unlock_table('LOG','tzq_log_t'); 四、解锁包:执行存过unlock_package(schema_name, pkg_name)以上面被授权的log用户,打开命令行窗口,执行下列SQL:set serveroutput on execute sys.tzq_server_pkg.unlock_package('LOG','tzq_log_pkg'); 五、解锁用户:执行存过unlock_user(username)以上面被授权的log用户,打开命令行窗口,执行下列SQL:set serveroutput on execute sys.tzq_server_pkg.unlock_user('LOG');六、停止job任务:执行存过stop_job(job_id)以上面被授权的log用户,打开命令行窗口,执行下列SQL:set serveroutput on execute sys.tzq_server_pkg.stop_job(6);七、杀session会话:执行存过kill_session(se_sid, se_serail#)7.1、查询需要kill的session的SID及serial#执行下列SQL:SELECT * FROM gv$session;找到你需要kill的那个session会话,拿到SID及serial#:159, 37297.2、执行存过kill_session(se_sid, se_serail#)执行存过kill_session(),kill掉上面的那个session会话。在命令行执行下面的SQL:set serveroutput on execute sys.tzq_server_pkg.kill_session(159, 3729); 八、给新建的用户授权:执行存过 grant_pris(username)以上面被授权的log用户,打开命令行窗口,执行下列SQL:set serveroutput on execute sys.tzq_server_pkg.grant_pris('log');

0
0
0
浏览量2046
青椒肉丝加点糖

JavaScript基础(一)js环境搭建、变量常量、数据类型及转换、运算符

一、JS开发环境的搭建        JavaScript 开发环境分为浏览器端和服务器端。所谓浏览器端就是 JS 代码通过浏览器自带的 JS 解释器来执行,典型代表就是五大浏览器:谷歌、火狐、edge、safari、欧朋。浏览器端执行需要创建一个 .js 文件和一个 .html 文件,然后将 .js 文件嵌入到 .html 文件中。<script src="01.js"></script>嵌入之后用浏览器打开.html文件即可。        服务器端则需要用到 Node.js,它是运行在服务器端的开发环境。需要使用时下载安装,执行方式也较为简单快捷,只需在命令提示符 cmd 下输入:node 空格  然后拖拽要运行的文件。如下:那么,如何检测自己是否安装Node了呢?在cmd命令提示符下输入node -v; 如果显示出版本号,则表示Node已成功安装。二、变量和常量        变量是存储数据的容器;常量同变量一样用于存储数据,但常量声明以后不允许重新赋值。        声明变量使用关键字var,声明常量使用关键字const。示例://变量声明 var x = 1;//表示在内容中开辟一块空间并命名为x,把1保存至这个空间中 var y = 2; var ename = '张三';//使用字符串时需要加引号 //常量声明 const pi = 3.14;三、数据类型       五大原始类型:数值型、字符串型、布尔型、未定义型、空数值型 number,包括二进制、八进制和十进制。 var n1 = 10;//10进制 var n2 = 012;//8进制 var n3 = 0xa;//16进制 var n5 = 3.1415E+2;//浮点型字符串型 string,被引号包含的数据即为字符串。 var str1 = 'abc'; var str2 = '8';布尔型 Boolean,只有两个值:true、false,通常用于保存只有两个状态的数据,例如是否在线、是否登录、一些运算符的结果等。未定义型 undefined,只有一个值 undefined,代表一个空值,例如声明了变量未赋值。空 null,只有一个值 null,类型为 object,通常结合对象一起使用检测数据类型需要用到 typeof,使用方法如下:var p = null;//定义一个变量为空 console.log(p,typeof p);//打印并用typeof检测数据类型,显示为null四、数据类型的转换首先是隐式转换,它是运算过程中自动产生的数据转换,其实是自动调用了Number函数(1)数字+字符串   数字转换为字符串后拼接(2)数字+布尔型   布尔型转换为数字,true--1,false--0(3)布尔型+字符串   布尔型转换为字符串后拼接(4)undefined+数字  undefined转为NaN(5)减乘除时,数据自动转为数值var n1 = 2 + '3';//23 var n2 = 2 + true;//3 var n3 = 'zxc' + false;//zxcfalse var n2 = '3' - 1;//2 var n3 = '2' * true;//2第二个是强制转换,需要用到函数(1)强制转换为数值型 Number( )var n1 = Number("1"); //1 var n1 = Number(true); //1 var n2 = Number(false); //0 var n3 = Number(undefined); //NaN var n4 = Number(null); //0 var n5 = Number("1a"); //NaN(2)强制转换为整型 parseInt( ) ,强制将字符串和小数转为整型var p1 = parseInt("3.14"); //3 var p2 = parseInt("6.18a"); //6 var p3 = parseInt("a6.18"); //NaN var p4 = parseInt(5.9); //5(3)强制转换为浮点型 parseFloat( ) ,强制将字符串转换为浮点型var f1 = parseFloat("3.14"); //3.14 var f2 = parseFloat("6.18a"); //6.18 var f3 = parseFloat("6a"); //6 var f4 = parseFloat("a6.18"); //NaN(4)数值和布尔型强制转为字符串 toString( )var num = 5; var str = num.toString( ); //"5"五、运算符        在学习运算符之前,先来了解以下“表达式”的定义:由数据本身或者由运算符连接的操作数据组成的形式称为表达式,也就是说,运算符所连接的数据均称为表达式。1. 算数运算符        即我们平常所用的加(+)、减(-)、乘(*)、除(/),还有取余(%)、自增(++)、自减(--)。加减乘除以及取余较为简单,不做探讨。通过一组代码来理解自增和自减:var a2 = 5; var a3 = a2++;//先将a2的值赋给a3,再自增 console.log(a2,a3);//6 5var a4 = 7; var a5 = ++a4;//a4先自增,再赋值给a5 console.log(a4,a5);//8 8        可以看出,如果自增用在变量后面,则是先使用变量的值参与计算,随后再进行变量加1;而如果自增用在变量前面,则是先将变量进行自增以后再参与计算,自减同理。2. 比较运算符等于“==”只比较两者的值是否相同,全等于“===”同时比较类型和值;不等于“!=”只比较值是否不同,不全等于“!==”同时比较类型和值,有一个不等即为 true;数字与字符串比较时,字符串转为数值;字符串之间比较时,比较首个字符的 Unicode 码;NaN 和任何值比较均返回 false,NaN == NaN 也为 false;console.log(2 == '2');//== 只比较值的大小,都为2,所以显示true console.log(2 === '2');//=== 比较值和类型,值虽然都为2,但前者为数值型,后者为字符串,所以显示false3. 逻辑运算符&& 逻辑与,关联的两个条件都为true,结果为true|| 逻辑或,关联的两个条件有一个为true结果即为true  ,! 逻辑非,取反 eg:!true = false逻辑运算符中比较重要的为短路逻辑:var a = 2; a > 3 && console.log(num);        如上代码,a 的值为 2,逻辑与判断中,第一个表达式为 a>3,而 2 不大于 3,说明此处为false,由于这里使用的运算符为逻辑与 &&,只有前后两个条件都为 true 时整体才为 true,所以第二个表达式就没有 必要再运行了,此时就是发生了短路逻辑。换句话说,短路逻辑的看重点就是在于是否执行第二个表达式。4. 位运算符        模拟计算机底层的运算,先将数据转为2进制进行运算,运算结束后再将结果转回10进制& 按位与,上下两位都是1,结果为1,否则为0;| 按位或,上下两位有一个1则结果为1;^ 按位异或,上下两位不同为1,相同为0;>> 按位右移,删除末尾的位数(原基础上除以2再取整);<< 按位左移,在末尾补0(原基础上乘以2)。//按位与 console.log(3 & 5);//011 & 101 == 001 == 1 console.log(5 & 8);//0101 & 1000 == 0000 == 0 //按位或 console.log(4 | 7);//100 | 111 == 111 == 7 //按位异或 console.log(6 ^ 9);//0110 ^ 1001 == 1111 == 15 //按位右移 console.log(9 >> 1);//1001 >> 1 == 0100 == 4 //按位左移 console.log(5 << 1);//101 << 1 == 1010 == 105. 赋值运算符        所谓赋值运算,就是先进行运算,再进行赋值var a = 1; a += 3;//4 a = a + 3;//46. 三目运算符一目运算符:由一个运算符连接的一个操作数据或者表达式  !  ++  --二目运算符:由一个运算符连接的两个操作数据或者表达式三目运算符:由两个运算符连接的三个操作数据或者表达式        格式:条件表达式 ? 表达式1 : 表达式2;如果条件表达式为 true,执行表达式1,如果条件表达式为false,执行表达式2。var a = 1,b = 2; a > b ? console.log('对') : console.log('错');        在以上函数中,a为1,b为2,首先判断a是否大于b,如果大于,则执行 console.log('对'),如果小于,则执行 console.log('错')。所以此语句输出结果为:错。

0
0
0
浏览量2041
青椒肉丝加点糖

JS 高级(三)继承、多态、ES5严格模式

一、面向对象1. 继承            只要将方法定义放在构造函数中,那么每次 new 时都会执行 function,这样就会反复创建相同函数的多个副本,导致浪费内存。如果将来发现多个子对象都要使用相同的功能和属性值时,都可以用继承来解决。        父对象中的成员,子对象无需重复创建就可直接使用,就像使用自己的成员一样,这就是继承。js 中的继承都是通过原型对象实现的,原型对象就是替所有子对象集中保存共有属性值和方法的特殊父对象。当多个子对象需要使用相同的功能和属性值时,都可将相同的功能和属性值集中定义在原型对象中。        原型对象不用自己创建,在定义构造函数时,程序自动附赠我们一个空的原型对象。构造函数中都有一个自带的属性 prototype,指向自己配对的原型对象——构造函数 .prototype。new 的第二步自动让新创建的子对象,继承构造函数的原型对象。new 会自动为子对象添加_ _proto_ _ 属性,指向构造函数的原型对象。向原型对象中添加新的共有属性和方法时,只能是强行赋值:        添加新属性或方法后,用子对象访问对象的成员时,js引擎先在子对象内部查找自有的属性;如果子对象没有,则 js 引擎会自动延 _ _proto_ _ 属性去父元素查找。如果在父元素中找到了想要的属性或方法,则和访问子对象的方法一样调用。        示例: 将所有子对象共用的方法保存进构造函数里<script> // 构造函数 function Student(sname, sage) { this.sname = sname; this.sage = sage; } // 强行向student类型的原型对象(prototype)中添加一个所有子对象共用的的方法intr Student.prototype.intr = function () { console.log(`我叫${this.sname},我今年${this.sage}岁`); } // 用构造函数反复创建多个相同结构但内容不同的对象 var lilei = new Student("李雷", 45); var hmm = new Student("韩梅梅", 30); console.log(lilei); console.log(hmm); lilei.intr(); hmm.intr(); console.log(lilei.__proto__ == Student.prototype); //true说明原型对象是子元素的父级 console.log(hmm.__proto__ == Student.prototype); //true </script>自有属性和共有属性(1)获取属性值时,毫无差别,都可用: 子对象.属性名。如果 js 引擎发现要使用的属性不在子对象中,则自动延 _ _proto_ _ 属性向父对象继续查找要用属性。(2)修改属性值示例: 为所有学生添加共有的班级名属性,并修改;<script> function Student(sname, sage) { this.sname = sname; this.sage = sage; } Student.prototype.className = "初一二班"; var lilei = new Student("lilei", 11); var hmm = new Student("hmm", 12); // 修改自有属性 lilei.sname = "zhangsan"; console.log(lilei); console.log(hmm); console.log(lilei.className, hmm.className); // 一年后,两位同学一起升级(修改共有属性) // 1.错误方式 // lilei.className = "初二二班"; // 此方式不会修改原型对象中的共有属性,而会给当前子对象添加一个同名的自有属性,导致该子对象与其他子对象无法继续保持同步。 // 2.正确方式,必须修改原型对象 Student.prototype.className = "初二二班"; console.log(lilei.className, hmm.className); </script> 内置类型的原型对象        内置类型就是 ES 标准中规定的,浏览器已经实现,我们可以直接使用的类型。包括十一种String、Number、Boolean、Array、Date、RegExp、Error、Function、Object、Math(不是类型,而是一个{ }对象)、global(全局作用域对象,在浏览器中被window代替)。        每种类型一定有2部分组成:构造函数,负责创建该类型的子对象;原型对象,负责为该类型所有子对象集中保存共有的属性值和方法定义。除 Math 和 global 之外,其余也都可以通过 new 创建子对象。        想要查看该类型中有哪些 API,可以使用 -- 类型名.prototype -- 。        如果经常使用的一个功能,但是原型对象中没有提供,我们可以自定义一个函数保存到原型对象中。举例:为数组类型添加求和的方法<script> var array1 = [1, 2, 4, 5, 8, 8]; var array2 = [125, 48, 48, 478, 2584]; // 创建自定义函数 Array.prototype.sum = function () { console.log("调用自定义函数sum"); // 数组求和套路 // 1.定义变量临时保持求和的值 var sum = 0; // 2.遍历数组元素 for (i = 0; i < this.length; i++) { // 3.将遍历出的元素值累加 sum += this[i]; } // 4.返回累加结果 return sum; } // 调用sum console.log(array1.sum()); console.log(array2.sum()); </script> 原型链        原型链是由多级父对象逐级继承形成的链式结构,保存着:一个对象可用的所有属性和方法,控制着属性和方法的使用顺序,采用就近原则,先子级后父级。<script> function Student(sname, sage) { this.sname = sname; this.sage = sage; } // 向Student原型对象中添加一个toString方法 Student.prototype.toString = function () { // 此处this指将来调用这个toString()的点前的某个学生的类型的子对象. return `{sname:${this.sname},sage:${this.sage}}`; } var lilei = new Student("lilei", 12); var arr = [1, 2, 3]; var now = new Date(); console.log(lilei.toString()); console.log(arr.toString()); console.log(now.toString); </script> 2. 多态        多态指同一个函数,在不同情况下表现出不同的状态,包括重载和重写。3. 自定义继承(1)只更换一个对象的父对象,两种方法://示例:更换一个对象的父对象 <script> function Student(sname, sage) { this.sname = sname; this.sage = sage; } var lilei = new Student("李磊", 11); var hmm = new Student("韩梅梅", 12); var father = { money: 1000000000000, car: "infiniti" } // 1.只更换一个对象的父对象 // 更换hmm的继承父对象为father // hmm.__proto__ = father;//不推荐 Object.setPrototypeOf(hmm, father); //推荐 console.log(hmm.money, hmm.car); console.log(lilei.money, lilei.car); console.log(lilei); console.log(hmm); </script>(2)批量更换多个子对象的父对象,只需要更换构造函数的 prototype 属性就可以,但必须在创建子对象之前更换!//示例: 批量更换两个子对象的父对象 <script> function Student(sname, sage) { this.sname = sname; this.sage = sage; } var father = { money: 1000000000000, car: "infiniti" } // 2.批量更换多个子对象的父对象 // 必须在创建子对象之前更换构造函数的原型对象 Student.prototype = father; var lilei = new Student("李磊", 11); var hmm = new Student("韩梅梅", 12); console.log(hmm.money, hmm.car); console.log(lilei.money, lilei.car); console.log(lilei); console.log(hmm); </script> 二、ES5(ECMAScript 第5个版本)1. 严格模式        在旧的js中有很多广受诟病的缺陷,严格模式就是比旧的js运行机制要求更严格的新运行机制,今后企业中所有代码都要运行在严格模式下。启用严格模式只需在当前代码段的顶部添加:   "use strict"; 即可。严格模式有四个新规定: a:禁止给未声明过的变量赋值;旧的js中,如果强行给未声明过的变量赋值,不会报错,而是,自动在全局设置该变量,这就造成了全局污染。而严格模式中,强行给未声明过的变量赋值,会报错,这样就减少了因为写错变量名造成的全局污染!举例:给未声明的局部变量赋值<script> function send() { var gf; // 假设不小心写错了变量名 qgf = "今晚308,w84u"; //直接报错qgf is not defined console.log(`女朋友收到${gf}`); } send(); console.log(`全局中:${qgf}`); </script>未使用严格模式,打印如下,本来想给“女朋友”发送的消息,却发到了全局,但系统不报错。启用严格模式,在代码段首行添加"use strict";<script> // 启用严格模式 "use strict"; // 禁止给未声明过的变量赋值 function send() { var gf; // 假设不小心写错了变量名 qgf = "今晚308,w84u"; //直接报错qgf is not defined console.log(`女朋友收到${gf}`); } send(); console.log(`全局中:${qgf}`); </script> 打印如下,此时直接报错,便于我们发现程序中的问题并修改。 b. 静默失败升级为错误;静默失败指程序运行不成功,但是也不报错,这样极其不利于调试程序,严格模式:会将绝大部分静默失败都升级为报错。<script> // 静默失败升级为错误 var eric = { aid: 1001, sanme: "斯塔克" } // 这里将eid属性设置为只读 Object.defineProperty(eric, "eid", { writable: false }) // 试图篡改 eric.eid = 1002; console.log(eric); </script>打印如下:即使将eid设置为只读,属性值仍被修改,但不报错。 启动严格模式后打印如下: c. 普通函数调用中的 this 不再指 window,而是指 undefined,在旧 js 中普通函数调用中的 this 默认指 window,极容易造成全局污染。启用严格模式后普通函数调用中的 this 指向 undefined,不再指 window,可防止因为错误使用 this 而导致的全局污染。<script> // 启用严格模式 "use strict"; // 普通函数调用中的this不再指window,而是指undefined function Student(sname, sage) { console.log(this); this.sname = sname; //报错 Cannot set property 'sname' of undefined this.sage = sage; } var lilei = new Student("李蕾", 12); // 假设忘记写new var hmm = Student("韩梅梅", 13); console.log(lilei); console.log(hmm); console.log(window); </script> d. 禁用了 arguments.callee,arguments.callee; 是在一个函数内,获得当前函数本身的一种特殊关键字(递归)。在函数内写死当前函数名,一旦外部函数名改变,内部函数名忘记修改,则程序立刻报错造成紧耦合,所以在函数内使用 arguments.callee 代替写死的函数名。在运行时,自动获得当前函数本身(松耦合)。        而且递归重复计算量太大,效率极低,如果递归调用严重影响程序的性能时,就要用循环来代替递归。举例:分别使用递归和循环实现计算斐波那契数列第 n 个数//递归方式 <script> // 禁用了arguments.callee // 斐波那契数列 // 前两个数是都是1,从第三个数开始,每个数都是它相邻的前两个数的和 function f(n) { if (n < 3) { return 1; } else { return arguments.callee(n - 1) + arguments.callee(n - 2); } } console.log(f(10));//55 </script>//循环方式 <script> function f(n) { if (n < 3) { return 1; } else { var f1 = 1, f2 = 1, fn; for (var i = 3; i <= n; i++) { fn = f1 + f2; f1 = f2; f2 = fn; } return fn; } } console.log(f(10)); //55 </script>补充:this 4种指向; (1)obj.fun() fun中的this指 .前的obj对象(谁调用指谁); (2)new Fun() Fun中的this指new创建的新对象; (3)fun() 或 (function(){ ... })() 或 回调函数 thisz默认指windozw; (4)原型对象(prototype)中的this指将来调用这个共有函数的.前的某个子对象(谁调用指谁)。

0
0
0
浏览量2038
青椒肉丝加点糖

MySQL(二)MySQL部署、建库建表实操示例

一、MySQL 的部署        部署MySQL的第一步是用客户端连接服务器端打开xampp-control,连接MySQL(部分电脑需要用管理员模式打开软件才可正常运行);连接成功后如图,会显示端口号与PID打开"shell"(命令行)进入后如图此时,输入命令 mysql -uroot 实现客户端与服务器端的连接连接成功后显示如下 连接成功以后即可用管理命令查看已有数据库与数据表,示例如下:其余管理操作省略.......二、建库建表        部署完 MySQL 之后,就可以建库建表和数据查询操作了;此时需要用到 SQL 语言,而 SQL 的执行方式有两种:交互模式和脚本模式。交互模式是在客户端输入一行,点击回车,服务端执行一行,适用于临时查看数据;脚本模式是客户端把要执行的命令写在一个脚本文件中,一次性提交给服务器执行,适用于批量操作数据,使用方式为:mysql -uroot<脚本文件路径;在这里我们使用脚本模式,需要用到第二款软件 EditPlus,我们先创建脚本文件,直接创建文本文档设置后缀为 .sql 即可;右键使用 EditPlus 打开,主界面如图;此时,就可以输入SQL语言进行建库建表操作了;#设置客户端连接服务器端的编码 set names utf8; #丢弃数据库,如果存在 drop database if exists web; #创建数据库,设置存储的编码 create database web charset=utf8; #进入数据库 use web; #创建部门表 create table dept( did int primary key auto_increment, dname varchar(8) unique ); #插入数据 insert into dept values(10,'研发部'); insert into dept values(20,'运营部'); insert into dept values(30,'市场部'); insert into dept values(40,'测试部'); #创建员工表 create table emp( eid int primary key auto_increment, ename varchar(8) not null, sex boolean default 1, #1-男 0-女 birthday date, salary decimal(8,2), #999999.99 deptId int, foreign key(deptId) references dept(did) ); #插入数据 insert into emp values(null,'tao',default,'1973-7-15',50000,20); INSERT INTO emp VALUES(NULL,'Tom',1,'1990-5-5',6000,20); INSERT INTO emp VALUES(NULL,'Jerry',0,'1991-8-20',7000,10); INSERT INTO emp VALUES(NULL,'David',1,'1995-10-20',3000,30); INSERT INTO emp VALUES(NULL,'Maria',0,'1992-3-20',5000,10); INSERT INTO emp VALUES(NULL,'Leo',1,'1993-12-3',8000,20); INSERT INTO emp VALUES(NULL,'Black',1,'1991-1-3',4000,10); INSERT INTO emp VALUES(NULL,'Peter',1,'1990-12-3',10000,10); INSERT INTO emp VALUES(NULL,'Franc',1,'1994-12-3',6000,30); INSERT INTO emp VALUES(NULL,'Tacy',1,'1991-12-3',9000,10); INSERT INTO emp VALUES(NULL,'Lucy',0,'1995-12-3',10000,20); INSERT INTO emp VALUES(NULL,'Jone',1,'1993-12-3',8000,30); INSERT INTO emp VALUES(NULL,'Lily',0,'1992-12-3',12000,10); INSERT INTO emp VALUES(NULL,'Lisa',0,'1989-12-3',8000,10); INSERT INTO emp VALUES(NULL,'King',1,'1988-12-3',10000,10); INSERT INTO emp VALUES(NULL,'Brown',1,'1993-12-3',22000,NULL); 如上代码,我们建立了数据库 web,包括员工表 emp 和部门表 dept,并插入了若干数据;接下来将写好的脚本文件提交给服务器;在第一个软件 xampp-control 中两次打开 shell 窗口,以下记为 shell1 和 shell2;第一步:在shell1中输入命令:mysql -uroot < 我们刚写的脚本文件路径,模拟服务器端,如图:第二步:在 shell2 中输入命令:mysql -uroot,连接服务器端,模拟客户端,如图:注:第一步与第二步顺序不可颠倒。接下来在客户端也就是 shell2 中进行相关操作即可,但是shell1不可关闭;查询已有数据库,出现了web,说明我们数据库创建成功。进入数据库,查询库中表格;查询表格数据;此时,数据库与数据表均创建完成,具体查询数据信息用到SQL语言,此处省略......

0
0
0
浏览量2045
青椒肉丝加点糖

HTML(二)列表、表格、表单元素

一、列表1. 有序列表(<ol> </ol>)        第一层嵌套内只能包含 <li></li> 列表项标签,列表项标签可以包裹任何标签和文本,属于块级元素。有序列表有以下几个属性:2. 无序列表(<ul> </ul>)       第一层嵌套内只能包含<li></li>列表项标签,同有序列表。有以下几个属性:        有序列表和无序列表第一层内必须包含列表项标签,文本写在列表项标签内。3. 自定义列表(<dl> </dl>)        <dt></dt>  列表标题        <dd></dd> 文本和元素<dl> <dt>国内电影</dt> <dd>流浪地球</dd> <dd>来电狂想</dd> <dt>国外电影</dt> <dd>惊奇队⻓</dd> <dd>美国队⻓</dd> </dl> 4. 嵌套列表        有序、无序以及自定义列表相互嵌套。举例:<!-- 嵌套列表 --> <ul> <li>MOBA类游戏 <ol> <li>王者荣耀 <ul type="circle"> <li>武则天</li> <li>嬴政</li> <li>不知火舞</li> </ul> </li> <li>英雄联盟 <ul type="circle"> <li>无极剑圣</li> <li>疾风剑豪</li> <li>暗裔剑魔</li> </ul> </li> </ol> </li> <li>第一人称射击 <ol> <li>和平精英</li> <li>使命召唤</li> <li>生化危机</li> </ol> </li> <li>经营类 <ol> <li>大富翁</li> <li>模拟人生</li> <li>城市天际线</li> </ol> </li> </ul> 二、表格1. 表格标签2. 表格的行列3. 表格标签相关属性4. 拆分与合并        拆分合并之后需要删除多余的行或列。三、表单元素1. 表单标签(<form></form>) 表单用于搜集不同类型的用户输入,该标签不能单独使用,需要在 form 元素中加入 input 等标签共同使用。2. input标签及控件      <input/>元素是最重要的表单元素,有不同的type属性3. 标记标签(<label> </label>) 不会向用户呈现任何特殊效果,内联元素,不自占一行 label 标签的 "for" 属性可把 label 绑定到另外一个元素,把 "for" 属性值设为相关元素的id 值即可。4. 菜单标签(<select> </select>)下拉菜单标签,不能单独存在,只能包裹option。 <option></option> 菜单选项,multiple 属性代表该下拉菜单可以多选。<select name="cd" id="city" multiple> <option value="0">请选择</option> <option value="1">北京</option> <option value="2">天津</option> </select>5.文本域(<textarea> </textarea>)具有滚动条的多行文本输入控件。

0
0
1
浏览量2043
青椒肉丝加点糖

MySQL(一)认识MySQL、常用管理命令、列类型列约束、查询语句

一、软件生命周期和计算机数据存储方式1. 软件生命周期        定义期:可行性研究阶段/需求分析阶段;        开发期:概要设计阶段/详细设计阶段/编码实现阶段/测试阶段;        维护期:部署阶段/维护阶段。2. 计算机对数据的存储,有4个方面通过特定的文件如excel、word等存储,只适用于存储小量数据且速度慢;内存,临时存储,运行时会有数据产生并存储,结束运行后数据即销毁;速度快;第三方云服务器,共享;数据库服务器。MySQL属于数据库服务器存储的范畴。二、数据库        数据库的作用就是按照一定的形式组织存放数据,目的是为便于操作数据,即增、删、改、查。数据库的发展历程为:网状数据库-->层次型数据库-->关系型数据库(RDBMS)-->非关系型数据库。1. 常见的关系型数据库SQLite——微型数据库,常用于移动端MySQL——开源RDBMS,是一种关联数据库管理系统,将数据库保存在不同的库中,每个库可包含多个表,表中可以有多行多列的数据,可用于各种操作系统SQL Server——Microsoft开发的中型数据库,只适用于Windows操作系统Oracle——Oracle开发的中大型数据库,可用于各种操作系统DB2——IBM开发的中大型数据库,常与IBM服务器搭配2. MySQL部署结构        MySQL部署分服务器端和客户端,服务器端负责存储维护数据,客户端负责连接服务器端,对数据进行增删改查操作。使用客户端连接服务器端时只需要执行命令:mysql.exe -h127.0.0.1 -P3306 -uroot -p -h,host IP地址/域名 eg:127.0.0.1/localhost(永远指向自己本身的电脑) -P,port 端口(此处为3306端口) -u,user 用户名(root是管理员账户,在root下密码为空) -p,password 密码 此命令也可以简写为:mysql -uroot3. 常用管理命令(必须以英文“;”结尾)quit;  退出连接show databases;  显示当前所有数据库use 数据库名称;  进入指定的数据库show tables;  显示当前数据库下的所有数据表desc 数据表名称;  描述数据表中都有哪些列4. 常用SQL命令以及举例(1)定义数据结构(DDL)drop database if exists jd; //丢弃数据库jd(存在的基础上) create database jd; //创建数据库jd use jd; //进入数据库jd create table student ( id int, name varchar ( 8 ), sex varchar ( 1 ), score int ); //创建表student,包括id、name、sex、score四列(2)操作数据(DML)insert into student values('1','张三','M','99'); //向student表中插入一行数据 delete from user where uid="2";  //删除uid为2的行数据 update user set upwd="666666",isOnline="n" WHERE uid="3"; //修改uid为3的行密码为666666,在线状态为n(3)查询数据(DQL)select * from student; //查询student表中的所有数据三、列类型        列类型指在创建数据表时,指定的列所能存储的数据类型。1. 数值型2. 日期时间型3. 字符串型   字符串型和日期时间型 必须加引号四、列约束列约束的意思是MySQL对要插入的数据进行特定的验证,只有符合条件才允许插入(位于列类型之后)。1. 主键约束  primary key声明了主键约束的列,不允许插入重复,一个表中只能有一个主键约束,通常用于编号列,可加快数据查找速度。自增列 Auto_increment:自动增长,声明了自增列,插入数据时只需要赋值为 null,就会获取最大值然后加1插入。声明了自增列也允许手动赋值。2. 非空约束  not null声明了非空约束的列上禁止插入Null。3. 唯一约束  unique声明了唯一约束的列不允许插入重复的值,但是 unique 允许插入重复的 null 甚至多个 null,一个表中可以有多个唯一约束。4. 默认值约束  defaul可以使用 default 关键字设置默认值,default使用时不加引号。5. 检查约束  check也称自定义约束,用户可以制定约束的条件。但是 MySQL 不支持检查约束,认为会极大影响数据插入数据,后期需要通过 JS 实现。6. 外键约束  foreign声明了外键约束的列称为外键列,这一列取值范围到另一个表的主键中,是为了让两个表建立关联。外键约束用法特殊,常用于创建表的最后一行,外键列要和对应的主键列的列类型保持一致。格式如下:格式:foreign key(外键列) references 另一个表(主键列) eg:foreign key(familyId) references family(fid)五、MySQL查询语句注:以下举例中 ,emp为员工表,dept为部门表1. 简单查询(1)查询特定的列     eg:查询所有员工的编号和姓名 select eid,ename from emp;(2)查询所有的列    eg:查询员工表emp中所有信息 select * from emp;(3)给列起别名       eg:查询所有员工的编号和姓名并起别名 select eid as 编号,ename as 姓名 from emp;(4)显示不同的记录eg:查询有哪些性别的员工 select distinct sex from emp;(5)查询时执行计算eg:查询所有员工姓名及年薪 select ename,salary*12 from emp;(6)查询结果排序     eg:查询所有部门数据,结果按照编号升序排列 select * from dept order by did asc;(7)条件查询             eg:查询编号为5的员工的数据 select * from emp where eid=5;(8)模糊条件查询     eg:查询姓名中含有“e”的员工 select * from emp where ename like "%e%"; % 表示匹配任意个字符, _ 表示匹配一个字符,以上两个匹配符须结合like关键字使用(9)分页查询        当查询的结果中数据太多,一次显示不完,就可以使用分页显示。分页查询需要两个已知条件:当前页码+每页数据量。语法:select * from emp limit 开始查询的值, 每页的数据量;eg:假设每页显示五条数据,分别查出前三页 第1页:select * from emp limit 0,5; 第2页:select * from emp limit 5,5; 第3页:select * from emp limit 10,5; 注意:开始查询的值=(当前的页码-1)* 每页数据量2. 复杂查询(1)聚合查询/分组查询eg:通过员工编号查询员工数量 select count(eid) from emp; eg:查询各部门员工 最高工资,员工数量,平均工资 select max(salary),count(*),avg(salary),deptId from emp group by deptId; eg:查询所有员工出生的年份 select year(birthday) from emp;(2)子查询多个SQL命令的组合,把一个SQL命令的结果作为另一个命令的条件; eg:查询高于平均工资的男员工 select * from emp where sec=1 && salary>(select avg(salary) from emp); eg:查询和Tom同一年出生的员工 select * from emp where year(birthday)=(select year(birthday) from emp where ename="Tom") && ename!="Tom"; (3)多表查询查询的列分布在不同的表中时,用多表查询(前提:表和表之间必须有关联); eg:查询所有员工的姓名及部门名称 select emp.ename,dept.dname from emp,dept where emp.deptId=dept.did;select ename,dname from emp left outer join dept on deptId=did;

0
0
0
浏览量2034
Ned

一道面试题,解锁JavaScript中的Event-Loop事件循环机制(面试必考)

面试题console.log('script start') async function async1() { await async2() console.log('async1 end') } async function async2() { console.log('async2 end') } async1() setTimeout(function () { console.log('setTimeout') }, 0) new Promise(resolve => { console.log('Promise') resolve() }) .then(function () { console.log('promise1') }) .then(function () { console.log('promise2') }) console.log('script end') 大家看看上面这道题!能告诉我输出结果是什么吗?如果你还不能确定,那么学完今天的内容,你就知道这道题该怎么做了!我们会在今天的结尾为大家揭示答案,及分析过程!那么,接下来就开始我们今天的学习吧!一、进程和线程1、什么是进程?在计算机科学中,进程是指在系统中运行的程序的实例。它是计算机中的一个独立执行单元,包含了程序代码、数据以及程序的执行状态。每个进程都有其独立的内存空间,不同进程之间一般是相互隔离的,这样可以确保它们不会直接干扰彼此的执行。就好比你打开电脑的任务管理器,你看到一个又一个的程序就是你的电脑的进程!也可以理解为CPU运行指令和保存上下文所需的时间!2、什么是线程?进程中的更小的单位,描述了一段指令执行所需的时间,在计算机科学中,线程是指进程内的一个执行单元,它包含了执行程序的代码和相关的上下文信息。线程是进程的一部分,一个进程可以包含多个线程,这些线程共享相同的资源,如内存空间和文件句柄。线程之间的切换相对于进程切换来说更加轻量级,因为它们共享相同的地址空间。有一点我们要记住一点JS引擎线程和浏览器的渲染进程是互斥的,会造成不安全的渲染!面试题:打开一个tap页面,输入一个url回车到页面展现的过程。问:这中间发生了什么?我们新开的一个页面,就是新开一个进程,需要多个线程配合才能完成页面的展示,其中有很多的细节,大致可以分为三步:1、渲染线程(GPU) ,2、http请求进程,3、JS引擎线程**什么是GPU?**GUP它是属于浏览器的,具有绘制功能,将页面上的展示绘制出来!就比如找到哪个物理发光点 应该亮什么灯,我们可以把它理解成一个画笔,作用就是把整个页面画出来。3、JS是单线程JavaScript语言是一门单线程语言,这意味着,在同一时间只能执行一个任务。正是因为JS单线程的这种特点,给它带来一些优点!简单性: 单线程模型使得编写和调试JavaScript代码相对简单。开发人员不必担心多线程的同步和竞态条件问题,这降低了代码的复杂性。避免竞态条件: 多线程环境下,如果没有正确处理同步,可能会导致竞态条件(Race Condition)。单线程避免了这种情况,因为在任何给定时刻只有一个任务在执行。前端开发中的简便性: 在Web开发中,JavaScript主要用于操作DOM、处理用户交互等,这些任务通常不需要多线程。单线程的模型对于处理这些任务是足够的,并且简化了前端开发的复杂性。更好的可控性: 单线程模型使得代码的执行流程更加可控。事件循环(Event Loop)机制确保任务按照特定的顺序执行,使得开发者更容易理解代码的执行流程。资源节省: 单线程模型节省了在多线程切换上的一些开销。在多线程环境中,线程的切换可能会引入额外的开销,而单线程模型避免了这个问题。避免死锁: 多线程应用程序中,死锁是一个潜在的问题,可能会导致程序无响应。单线程模型避免了这个问题,因为只有一个执行线程。但是,在某些情况下,也可能导致性能问题,特别是在处理大量计算或需要等待的异步任务时。为了克服这些限制,JavaScript使用异步编程模型,允许开发者利用单线程的同时,通过异步操作提高并发性。有人就要问了,为什么JS不设计成多线程的?这是因为JS设计之初是打算设计成浏览器的脚本语言,多线程 高并发高功耗,多线程运行的时候会多占一些内存,是为了遏制同时干多个事情的能力,节约进程内存的开销。接下来,我们就为大家介绍JavaScript中异步编程!二、JavaScript中的异步JavaScript异步编程中存在两个概念!宏任务和微任务!1、宏任务(异步很凶的代码)整体的代码(Script): 整体的 JavaScript 代码作为一个宏任务执行。定时器事件(setTimeout、setInterval): 设置定时器的回调函数会作为一个宏任务执行。事件监听器(Event Listeners): 通过事件监听器绑定的回调函数会作为宏任务执行。I/O 操作: 执行某些 I/O 操作时,例如文件读写、网络请求,会作为宏任务执行。用户交互事件: 用户的交互事件,例如点击、键盘输入,会触发相应的回调函数,作为宏任务执行。UI-rendering: 页面渲染 重要2、微任务Promise 的回调函数: Promise 的 then 和 catch 方法中的回调函数会作为微任务执行。MutationObserver: 使用 MutationObserver 监听 DOM 变化的回调函数会作为微任务执行。process.nextTick(Node.js): 在 Node.js 中,process.nextTick 中的回调函数会作为微任务执行。queueMicrotask: queueMicrotask 函数添加的回调函数会作为微任务执行。Object.observe(已废弃): Object.observe 中的回调函数会作为微任务执行(注意:Object.observe 已被废弃)。我们了解这两个概念有什么用呢?接下来就介绍我们今天的应用!三、事件循环机制event-loop 面试必考事件循环机制的步骤如下:执行同步代码(这属于宏任务)当执行栈为空,去查询是否有异步代码需要执行执行微任务如果有需要,会渲染页面d执行宏任务,(这也叫下一轮的event-loop的开启)接下来我们看看这个案例:let a = 1 console.log(a); // v8决定定时器耗时 setTimeout(()=>{ console.log(a); },1000) let b = 2 //for循环是由我们CPU说要耗时的,v8眼里它是不耗时的 for(let i = 0;i<10000;i++) { console.log(b); } 在这个案例当中,在浏览器引擎眼里,for循环是不会耗时的,但是我们的CPU运行需要耗时,我们假设for执行完需要1s,那么,我们的setTimeout需要耗时多少?答案是2s!for执行完的时间由我们的CPU决定,它是一个同步代码。你也许会疑惑,这里也没有用到事件循环机制阿?对!那我们用事件循环机制来分析下面这个案例console.log('starting'); setTimeout(()=>{ console.log('settimeout'); setTimeout(()=>{ console.log('inner'); }) console.log('end'); },1000) new Promise((resolve,reject)=>{ console.log('promise'); resolve() }) .then(()=>{ console.log('then'); }) .then(()=>{ console.log('then2'); }) .then(()=>{ console.log('then3'); }) 这个案例的执行结果是什么?我们后台数据存在两个队列!我们开始分析这个案例:浏览器从上往下执行,根据事件循环机制的步骤:第一轮事件循环机制一、执行同步代码​ 1、第一行console.log('starting');这是一个同步代码,直接执行!​ 2、往下是第一个定时器,我们把它推入到宏任务队列:宏任务队列:setTimeout​ 3、然后来到new Promise这个语句是一个同步代码,我们执行它的内部:console.log('promise');同步代码,输出promise,执行 resolve()​ 4、第一个.then,这个是微任务,推入到微任务队列当中(我们用数字[1]表示先后,区别相同的标签):微任务队列:.then()[1]​ 5、第二个.then,这个是微任务,推入到微任务队列当中:微任务队列:.then()[2],.then()[1]​ 6、第三个.then,这个是微任务,推入到微任务队列当中:微任务队列:.then()[3],.then()[2],.then()[1]二、当执行栈为空,去查询是否有异步代码需要执行(意思就是如果没有同步代码需要执行了,就接着往下走)三、执行微任务​ 1、获取微任务队列微任务队列:.then()[3],.then()[2],.then()[1],我们知道队列是先进先出,所以我们从头开始执行!​ 2、执行.then()[1],输出then此时微任务队列:微任务队列:.then()[3],.then()[2]​ 3、执行.then()[2],输出then2此时微任务队列:微任务队列:.then()[3]​ 4、执行.then()[3],输出then3此时微任务队列:微任务队列:四、如果有需要,会渲染页面d五、执行宏任务,(这也叫下一轮的event-loop的开启)​ 1、获取宏任务队列:宏任务队列:setTimeout​ 2、新的一轮事件循环:宏任务队列:第二轮事件循环一、执行同步代码​ 1、console.log('settimeout');同步代码直接输出settimeout​ 2、setTimeout,推入宏任务队列:宏任务队列:setTimeout​ 3、console.log('end');同步代码直接输出end二、当执行栈为空,去查询是否有异步代码需要执行(意思就是如果没有同步代码需要执行了,就接着往下走)三、执行微任务(没有微任务)四、如果有需要,会渲染页面d五、执行宏任务,(这也叫下一轮的event-loop的开启)​ 1、获取宏任务队列:宏任务队列:setTimeout​ 2、新的一轮事件循环:宏任务队列:第三轮事件循环一、执行同步代码​ 1、console.log('inner');同步代码,直接输出:inner由于没有代码了,后续内容结束!总结下来,我们的输出应该是:输出: starting promise then then2 then3 settimeout end inner 没错!这就是我们想要的答案!值得注意的是!我们看看这个案例:function a(){ setTimeout(()=>{ console.log('a'); },1000) } function b(){ setTimeout(()=>{ console.log('b'); },500) } a() b() //输出: //b //a 为什么这里是先输出b再输出a呢?这是因为setTimeout定时器比较特殊,在宏队列中,几乎是同步执行,时间短的先输出,像上述案例,执行完成总共花费的时间为1s好了学到这里,你也就基本懂了事件循环机制,接下来为解决我们今天的"大人物"面试题而准备吧!async函数我们参考MDN官方文档介绍!async 函数 - JavaScript | MDN (mozilla.org)async 函数是使用async关键字声明的函数。async 函数是 AsyncFunction 构造函数的实例,并且其中允许使用 await 关键字。async 和 await 关键字让我们可以用一种更简洁的方式写出基于 Promise 的异步行为,而无需刻意地链式调用 promise。返回值一个 Promise,这个 promise 要么会通过一个由 async 函数返回的值被解决,要么会通过一个从 async 函数中抛出的(或其中没有被捕获到的)异常被拒绝。描述async 函数可能包含 0 个或者多个 await 表达式。await 表达式会暂停整个 async 函数的执行进程并出让其控制权,只有当其等待的基于 promise 的异步操作被兑现或被拒绝之后才会恢复进程。promise 的解决值会被当作该 await 表达式的返回值。使用 async/await 关键字就可以在异步代码中使用普通的 try/catch 代码块。备注: await关键字只在 async 函数内有效。如果你在 async 函数体之外使用它,就会抛出语法错误 SyntaxError 。备注: async/await的目的为了简化使用基于 promise 的 API 时所需的语法。async/await 的行为就好像搭配使用了生成器和 promise。async 函数一定会返回一个 promise 对象。如果一个 async 函数的返回值看起来不是 promise,那么它将会被隐式地包装在一个 promise 中。面试题答案console.log('script start') async function async1() { await async2() console.log('async1 end') } async function async2() { console.log('async2 end') } async1() setTimeout(function () { console.log('setTimeout') }, 0) new Promise(resolve => { console.log('Promise') resolve() }) .then(function () { console.log('promise1') }) .then(function () { console.log('promise2') }) console.log('script end') 我们拿到面试题,然后进行分析。根据我们的事件循环机制进行分析!第一轮事件循环一、执行同步代码​ 1、console.log('script start')同步代码,直接输出script start​ 2、async函数async1和async2的声明,不用管​ 3、async1()函数调用,进入函数内部,碰到await async2(),原本我们会把它和它之后当作微任务放入微任务队列当中,现在它只会把它后面的代码放入微任务当中,而它接着的代码,被强行提前!所以这里会先调用async2,而console.log('async1 end')进入微任务队列:微任务队列:console.log('async1 end'),而async2()会立即调用​ 4、紧接着第三步,进入async2函数,里面没有awiat,console.log('async2 end')为同步代码,输出async2 end​ 5、跳出函数调用,往下执行,一个定时器的声明。加入宏任务:宏任务队列:setTimeout[1]​ 6、new promise为同步代码,执行里面的逻辑,console.log('Promise')输出Promise,再调用resolve()​ 7、.then,推入微任务队列:微任务队列:.then[1],console.log('async1 end')​ 8、又一个.then,推入微任务队列:微任务队列:.then[2],.then[1],console.log('async1 end')​ 9、console.log('script end')同步代码,输出script end二、当执行栈为空,去查询是否有异步代码需要执行(意思就是如果没有同步代码需要执行了,就接着往下走)三、执行微任务​ 1、获取微任务队列:微任务队列:.then[2],.then[1],console.log('async1 end')​ 2、开始执行,输出async1 end然后微任务队列:.then[2],.then[1]​ 3、再执行.then[1],内部有一个输出代码console.log('promise1')输出promise1此时微任务队列:.then[2]​ 4、执行.then[2],内部有一个输出console.log('promise2'),输出promise2,此时微任务队列:四、如果有需要,会渲染页面d五、执行宏任务,(这也叫下一轮的event-loop的开启)​ 1、获取宏任务队列:宏任务队列:setTimeout​ 2、新的一轮事件循环:宏任务队列:第二轮事件循环​ d定时器当中只有一个console.log('setTimeout')直接输出setTimeout输出结束!!最终结果为:输出: script start async2 end Promise script end async1 end promise1 promise2 setTimeout 这样,我们这道面试题就解决啦!!是不是很简单呢?不知道大家,看完这篇文章有没有对事件循环机制有一定的理解!希望大家看完能够有所收获!

0
0
0
浏览量2081