首页 文章 精选 留言 我的

精选列表

搜索[学习],共10003篇文章
优秀的个人博客,低调大师

Java基础学习1

1Java的数据类型 l基本类型(8种) l引用类型 2八种基本类型 byte 1 -128到127,-27到27-1 short 2 -215到215-1 int 4 -231到231-1 long 8 -263到263-1 float 4 单精度 IEEE 754规范 美国电子电气工程师协会浮点数表示规范 double 8 双精度 char 2 0到65535 0到216-1 boolean 1 真true00000001 假false00000000 2.1计算机的存储单位 lbit -比特,电位 lbyte -字节,8bit lKb - 1024 byte lMb - 1024 Kb lGb - 1024 Mb lTb - 1024 Gb lPb - 1024 Tb 2.2二进制 lbyte 10000000-128 ... 11111100-4 11111101-3 11111110-2 11111111-1 000000000 000000011 000000102 000000113 000001004 000001015 000001106 000001117 000010008 ... 01111111127 84608 8*104 4*103 6*102 8*100 11011 24 23 21 20 853 8530 85300 110 1100 11000 674 除2取余法 674 /2337余0 337 /2168余1 168 /284余0 84 /242余0 42 /221余0 21 /210余1 10 /25余0 5 /22余1 2 /21余0 1 /20余1 11 102 1004 10008 1000016 10000032 100000064 10000000128 100000000256 1000000000512 100000000001024 1000个苹果,分装机箱, 不管客户要多少苹果,都可以整箱交付 变量交换 //项目:变量交换 package; importjava.util.Scanner; publicclassTest1 { publicstaticvoidmain(String[]args) { //提示输入 System.out.print("输入整数a:"); //获得输入的值,保存到变量a inta=newScanner(System.in).nextInt(); System.out.print("输入整数b:"); intb=newScanner(System.in).nextInt(); //变量交换,三步转圈赋值 intc=a; a=b; b=c; System.out.println("a = "+a); System.out.println("b = "+b); } } 自由落体距离 //项目:自由落体距离 package; importjava.util.Scanner; publicclassTest1 { publicstaticvoidmain(String[]args) { System.out.println("输入降落时间(秒):"); //获得输入的值,保存到变量t doublet= newScanner(System.in).nextDouble(); //调用f()方法 //把时间t的值,传递到f()方法计算 //得到f()方法的计算结果,保存到变量d doubled=f(t); System.out.println(t+"秒降落了"+d+"米"); } staticdoublef(doublet) { doubled= 0.5*9.8*t*t; returnd;//把计算结果返回到上面调用位置 } } 2.3char类型(2字节) l字符、字符的整数编码 Unicode编码表 0 nil 1 ? 2 ? 3 ? ... 97 a 98 b ... 20013 中 ... 65535 lchar c1 = 97 char c2 = 'a' 2.4基本类型的字面值(5条规则) 1.整数字面值是int类型 int a = 56456; //右侧字面值是int类型,但超出int范围 long a =9999999999; 2.byte,short,char三种比int小的整数,可以用范围内的值,直接赋值 //右侧是byte,不是int byte a = 127; //右侧是int byte a =128; 3.浮点数字面值是double类型 double a = 3.14; //右侧是double,不是float float a =3.14; 4.字面值后缀 L - long long a = 9999999999L; F - float float a = 3.14f; D - double double a = 3.0; double a = 3d; 5.进制前缀 16进制: 两个16进制字符,可以表示一个字节 8进制: 1个8进制字符,可以表示3位 0x - 16进制 0xff255 0- 8进制 0377255 \u - char类型16进制 必须表示char类型完整的两个字节值 'a''\u0061' '中''\u4e2d' 2.5基本类型的运算规则(5条规则) 1.计算结果的数据类型,与最大的类型一致 3/2得1 3d/2得1.5 2.byte,short,char比int小的整数,运算时,会自动转成int byte a = 3; byte b = 4; //错,右侧是int+int,结果是int byte c = a+b; 3.整数运算溢出 Integer.MAX_VALUE+1 得负数最小值 300000000*60*60*24*365 300000000L*60*60*24*365 01111111111111111111111111111111 +1 10000000000000000000000000000000 4.浮点数运算不精确 2-1.9 得0.10000000000000009 4.35*100 得434.9999999999999999994 Java中有精确运算方法,后面会讲 5.浮点数的特殊值 nInfinity(无穷大) 3.14/0 Double.MAX_VALUE*2 nNaN(Not a Number) Math.sqrt(-3) 2.6基本类型的类型转换 l小的类型转成大的类型 byte a = 127; int b = a; 01111111 00000000 00000000 0000000001111111 byte a = -1; int b = a; 11111111 11111111 11111111 1111111111111111 l大的类型转成小的类型 n必须强制转型 int a = 356; byte b = (byte) a; 00000000 00000000 0000000101100100 01100100 牛郎织女 两颗星相距16.4光年 光速299792458米/秒 喜鹊身长0.46米 牛郎织女相会,需要多少只喜鹊 //项目:牛郎织女 package; publicclassTest1 { publicstaticvoidmain(String[]args) { System.out.println("两颗星相距16.4光年"); System.out.println("光速299792458米/秒"); System.out.println("喜鹊身长0.46米"); System.out.println("牛郎织女相会,需要多少只喜鹊"); //1光年是多少米 longly= 299792458L*60*60*24*365; //16.4光年是多少米 doubled=ly*16.4; //求喜鹊数量 doubler=d/0.46; //向上取整 //Math.ceil(r) //取整结果是double类型6436345.0 longn= (long) Math.ceil(r); System.out.println(n); } } 3运算符 +-*/ + 数学运算 字符串的连接运算 % 取余、求模 判断变量a能否被4整除, a%4余数是0 == != 相等 不相等 > >= < <= 大小比较 && 逻辑与 左边是真,并且右边是真,结果是真 短路与,左边是假,右边忽略不执行 || 逻辑或 左边是真,或者右边是真,结果都是真 短路或,左边是真,右边忽略不执行 ! 非 非真是假,非假是真 对布尔值做相反判断 判断“非a”是真,即a是假 if(!a) { } & 位与 两位都是1结果是1 | 位或 有一位是1,结果就是1 ^ 异或 不同是1 对同一个值异或两次,得到原值 ~ 求反 1变0,0变1 >> 带符号向右移位 符号位是0,左边补0 符号位是1,左边补1 >>> 不带符号向右移位 不管符号位是0还是1,左边都补0 << 向左移位 ++ -- 自增1、自减1 int a=5 print(a++)先取值后自增 1)先取出a的原值等待打印 2)a自增变成6 3)打印原值5 int a=5 print(++a)先自增后取值 1)a自增变成6 2)取出a的新值等待打印 3)打印a的新值6 ? : 三项运算 1 ? 2 : 3 1是真,取2的值 1是假,取3的值 = 赋值 += ^= >>= ... 复合的赋值运算 a += 2; //a = a+2; 自动转型 byte a = 2; a = (byte) (a+2); a += 2; a += 3.94; () 转型运算 l向右移1位相当于除2 l向左移1位相当于乘2 3.1运算符优先级 l不用记优先级表,多加小括号 (1+(2-3))*4/5 平年闰年 输入年号,显示是平年还是闰年 闰年条件: *)能被4整除,并且不能被100整除 *)能被400整除 2000 1000 2016 2018 //平年闰年 package; importjava.util.Scanner; publicclassTest1 { publicstaticvoidmain(String[]args) { System.out.print("输入年号:"); inty=newScanner(System.in).nextInt(); //调用runNian()方法 //对年号y的值判断是否闰年 //该方法返回boolean值 if(runNian(y)) { System.out.println("闰年"); }else{ System.out.println("平年"); } } staticbooleanrunNian(inty) { booleanrun=false;//假设不是闰年 /*if(y%4 == 0) {//能被4整除 //能被4整除的情况下 if(y%100 != 0) {//再判断不能被100整除 run = true; } } if(y%400 == 0) {//能被400整除 run = true; }*/ if((y%4==0 &&y%100 != 0) ||y%400==0) { run=true; } returnrun; } } 3.2位运算 00000000000000000000000001110011 00000000000000000000000001010101 & ---------------------------------- 00000000000000000000000001010001 00000000000000000000000001110011 00000000000000000000000001010101 | ---------------------------------- 00000000000000000000000001110111 00000000000000000000000001110011 00000000000000000000000001010101 ^ ---------------------------------- 00000000000000000000000000100110 00000000000000000000000001110011 ~ ---------------------------------- 11111111111111111111111110001100 00000000000000000000000001110011>>2 00000000000000000000000000011100 10000000000000000000000001110011>>2 11100000000000000000000000011100 10000000000000000000000001110011>>>2 00100000000000000000000000011100 10000000000000000000000001110011<<2 00000000000000000000000111001100 位运算 10011001100001001011100011110011 10011001 10000100 10111000 11110011 r 10011001100001001011100000000000 11111111 11111111 11111111 11110011 //项目:int拆分4字节 package*; importjava.util.Scanner; publicclassTest1 { publicstaticvoidmain(String[]args) { System.out.print("输入整数:"); //获得输入的值,保存到变量n intn=newScanner(System.in).nextInt(); /* * n向右移动24,16,8,0位 *再强转成byte类型 *分别保存到b1,b2,b3,b4变量 *再打印显示 */ byteb1= (byte) (n>>24); byteb2= (byte) (n>>16); byteb3= (byte) (n>>8); byteb4= (byte) (n>>0); System.out.println(b1); System.out.println(b2); System.out.println(b3); System.out.println(b4); // intr= 0; /* * b1,b2,b3,b4 *左移24位, *再不带符号右移0,8,16,24位 *结果再与r求或,保存到r */ //r = r | (b1<<24>>>0); //r = r | (b2<<24>>>8); //r = r | (b3<<24>>>16); //r = r | (b4<<24>>>24); /* * b1,b2,b3,b4 *对0x000000ff求与 *再左移24,16,8,0位 *结果再与r求或,保存到r */ r=r| ((b1& 0x000000ff) << 24); r=r| ((b2& 0x000000ff) << 16); r=r| ((b3& 0x000000ff) << 8); r=r| ((b4& 0x000000ff) << 0); System.out.println(r); } } 三个整数的最大值 项目:day0108_三个数最大值 类:day0108.Test1 packageday0108; importjava.util.Scanner; publicclassTest1 { publicstaticvoidmain(String[]args) { System.out.println("输入三个整数"); inta=newScanner(System.in).nextInt(); intb=newScanner(System.in).nextInt(); intc=newScanner(System.in).nextInt(); //a,b的最大值保存到max //max,c的最大值保存到max //intmax = a>b ? a : b; //max = max>c ? max : c; intmax=a>b? (a>c?a:c) : (b>c?b:c); System.out.println("最大值:"+max); } }

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

ADO.net学习

<1>在VS2017中建立Windows 窗体应用(.NET Framework)项目。 <2>在解决方案资源管理器中,打开Form1.cs,主题窗口会出现Form1.cs[设计]的标题。 <3>打开工具栏,找到Button控件,将该控件拖拽到设计面板中,右键这个控件,点击属性,在Text栏目中输入该按钮的名称。在"设计"的(Name)栏目中输入该按钮的响应函数的名字。我设计的是:btnCreateConnection。软后双击这个按钮,就会转向Form.cs中的btnCreateConnection_Click。也就是该按钮的点击的响应函数。设置这个函数的目的是第一次连接数据库。 <4>[注:本文连接的是SQLserver数据库]。 <5>增加命名空间: System.Data.SqlClient命名空间是用于 SQL Server 的 .NET 数据提供程序 System.Data.Common用于使用DbConnection,DbCommand,DbDataReader类等。 System.Configuration命名空间包含提供用于处理配置数据的编程模型的类。 数据库文件:链接:https://pan.baidu.com/s/1GT-eyEtK9K06TYYUrLPrdg 密码:8jjw 下载后所包含的数据库文件有: BulkCopy.mdf, BulkCopy_log.ldf; PUBS.MDF, PUBS_LOG.LDF; 我将这些数据库文件附加到了SQL Server2014的数据库管理系统中,这样的话接下来写的程序对数据库的更改变化就可以通过Navicat直观地查看内容的变化。 <6>在btnCreateConnection_Click响应函数中连接数据库,这里遇到了分支。第一种情况是数据库文件在解决方案资源管理器中,第二种情况是数据库附加到数据库管理系统或者该数据库由数据库管理系统创建。 第一种情况:数据库文件在解决方案管理器中。 A,当直接在响应函数中写连接数据库的语句时: DbConnection con = new SqlConnection(); con.ConnectionString = @"Data Source=.\SQLEXPRESS;" + "AttachDbFilename=|DataDirectory|PUBS.MDF;" + "Integrated Security=True;User Instance=True"; con.Open(); //Do lots of cool work here con.Close(); B,当用配置文件里面封装的内容连接数据库时,语句为: 配置文件(也就是App.config)里面封装的内容需要添加: <connectionStrings> <add name="PubsData" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|PUBS.MDF;Integrated Security=True;User Instance=True;" providerName="System.Data.SqlClient" /> <add name="PubsDataMars" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\PUBS.MDF;Integrated Security=True;User Instance=True;MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" /> <add name="BulkCopy" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\BulkCopy.mdf;Integrated Security=True;User Instance=True;" providerName="System.Data.SqlClient" /> </connectionStrings> (在<configuration></configuration>也就是XML的根元素中添加内容) 在响应函数中写的语句为: ConnectionStringSettings pubs = ConfigurationManager.ConnectionStrings["PubsData"]; DbConnection con = new SqlConnection(pubs.ConnectionString); con.Open(); //Do lots of cool work here con.Close(); 为了验证连接数据库成功,可以通过在//Do lots of cool work here中查询数据库中表的内容验证: DbCommand cmd = con.CreateCommand(); cmd.CommandText = "select * from sales"; con.Open(); DbDataReader dr = cmd.ExecuteReader(); if (dr.HasRows) { while (dr.Read()) { string stor_id = dr["stor_id"].ToString(); string ord_num = dr["ord_num"].ToString(); string ord_date = dr["ord_date"].ToString(); string title_id = dr["title_id"].ToString(); Console.WriteLine(stor_id+" "+ord_num+" "+ord_date+" "+title_id); } }这里就可以体现了将数据库文件附加到数据库管理系统之后通过Navicate查看表的优势。表中的各个关键字都可以查看,以便写出while(dr.Read())中的语句。 第二种情况:数据库附加到数据库管理系统或者该数据库由数据库管理系统创建。 A,当直接在响应函数中写连接数据库的语句时: DbConnection con = new SqlConnection(); con.ConnectionString = @"Initial Catalog=PUBS;Persist Security Info=True;User ID=sa;password=hl123456789"; con.Open(); //Do lots of cool work here con.Close(); 尤其要根据自己的数据库管理系统设置相应的User ID跟password。 B,当用配置文件里面封装的内容连接数据库时,语句为: 配置文件里的语句为: <connectionStrings> <add name="dbstconnectionstring" connectionString="Initial Catalog=PUBS;Persist Security Info=True;User ID=sa;password=hl123456789" providerName="System.Data.SqlClient"/> </connectionStrings> 响应函数中的语句为: string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString; DbConnection conn = new SqlConnection(connectionString); DbCommand cmd = conn.CreateCommand(); cmd.CommandText = "select * from authors"; conn.Open(); //Do a lot of work conn.Close(); [注:]第<6>个内容中,如果想通过响应函数来查看配置文件的具体内容时候,语句可以写成:(这里接的是第<6>个内容的第一种情况的B类) ConnectionStringSettings pubs = ConfigurationManager.ConnectionStrings["PubsData"]; DbConnection connection = new SqlConnection(pubs.ConnectionString); //name = "PubsData" string name = pubs.Name; //provider = "System.Data.SqlClient" string provider = pubs.ProviderName; //cnString = "Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\PUBS.MDF;Integrated Security=True;User Instance=True" string cnString = pubs.ConnectionString; MessageBox.Show("From App.Config: " + cnString+"\n"+name+"\n"+provider); <7>使用DataGridView控件,和按钮的响应事件,来显示SqlConnection的数据源的架构信息 其中: SQL Server架构集合 GetSchema():返回此SqlConnection的数据源的架构信息 GetSchema(String):使用表示架构名称的指定字符串返回此SqlConnection的数据源的架构信息 我设计了两个DataGridView控件,分别为dataGridView1,dataGridView2,第一个用于GetSchema(),第二个用于GetSchema(String),其中dataGridView2用于点击dataGridView1中的行的内容,显示具体的内容。 准备: 按钮,响应函数为:btnGetSchema_Click 自己写一个dataGridView事件变化函数ataGridView_SelectionChange 并在dataGridView1属性(闪电栏目)中的SelectionChange响应事件中添加写的这个函数。 源程序为: private void btnGetSchema_Click(object sender, EventArgs e) { //Get the settings from the configuration file ConnectionStringSettings pubs = ConfigurationManager.ConnectionStrings["PubsData"]; DbConnection connection = new SqlConnection(pubs.ConnectionString); connection.Open(); DataTable schema = connection.GetSchema(); connection.Close(); dataGridView1.DataSource = schema; } private void dataGridView1_SelectionChanged(object sender, EventArgs e) { DataTable schema = (DataTable)dataGridView1.DataSource; DataRow currentRow = schema.Rows[dataGridView1.CurrentCell.RowIndex]; string collection = (string)currentRow["CollectionName"]; //Get the settings from the configuration file ConnectionStringSettings pubs = ConfigurationManager.ConnectionStrings["PubsData"]; DbConnection connection = new SqlConnection(pubs.ConnectionString); connection.Open(); DataTable schema2 = connection.GetSchema(collection); connection.Close(); dataGridView2.DataSource = schema2; }

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

flask学习笔记(一)

思来想去,还是放弃用word记笔记的习惯吧,写了又不会回头看。 虚拟环境 每创建一个项目,就一定要给该项目创建一个虚拟环境。 虚拟环境用来隔离项目之间因为版本不同而产生的差异。 Flask服务器搭建步骤 1、从flask包里面导入Flask类 2、实例化Flask。 我们管falsk的实例化对象叫app。括号里面的__name__是flask实例化核心对象的一个标志。 实例化时传入参数“__name__”的原因是让我们实例化的这个对象与其他对象有所区分(揣测的意思,以后看了源码可能会改) (课下了解:基于类的视图——即插视图) 3、视图函数实现的功能复用性不高,get一个新名词 “基于类的视图——即插视图” ,传送门(打马,以后仔细看看): http://docs.jinkan.org/docs/flask/views.html 扩展知识:重定向 将@app.route(/hello“)改成@app.route(/hello/“)就可以兼容用户输入网址时,末尾带“/”之后无法访问网页的弊端。 浏览器申请访问url1,服务器并没有把url1的资源返回给浏览器,而是返回一个url2的location,并把状态码(status code:301或者302)设置成301或者302。浏览器获得返回值时,会先看一下状态码,如果状态码是301或者302,他就知道服务器希望他做一次重定向,他会再一次向服务器发送请求,这个请求就是url2。 Flask的实质是把末尾不带“/”的url重定向到“/”的url里面来。 重定向是为了保证每个资源都是唯一的url,否则不同的url可以访问相同的资源,会造成混乱 4、路由 在视图函数hello()中,用装饰器@app.route(‘/hello’) 来注册路由的原因是因为Python支持这样的一种装饰器。 路由注册的另一种方法 如果你要使用基于类的视图(即插视图)的时候,你就要使用app.add_url_rule的方式来注册路由。 @app.route在底层的作用就是调用上面的add_url_rule,flask封装出装饰器,就是为了让界面看起来更优雅。 装饰器可以解决很多问题,尤其是代码耦合的问题(不明觉厉)。 如果只是写debug=True,那么你做的网页只能通过服务器所在的主机进行访问。 host=‘0.0.0.0’代表我可以接受外网的访问。 port=81代表端口号为81。 5、生产模式时,不能开启debug=True。原因有二: 首先调试模式(即开启debug=True)时的性能比较差;其次,我们不能向用户展示我们任何服务器的详细信息 6、部署的基本原则是开发模式和生产模式要保持镜像关系(也就是说两份源代码是一模一样的)。这个问题的解决办法就是写配置文件 建议:配置文件里面的参数全部大写 导入配置文件的方法一 导入我们写的配置文件(这里的语句是from config import DEBUG),导入之后,你就可以使用他了(把debug=True改成debug=DEBUG) 导入配置文件的方法二 由于config和Fisher在同一个文件夹里面,因此上面函数的路径就是‘config’ 读取配置文件的方式 config其实是Python dict(字典)的一个子类 print函数可以在命令行里面输出东西,来查看我们的功能是否实现 注意:如果你是以“from_object”的形式(即:)载入配置文件,flask要求变量的字母全部大写(因为小写字母会被自动忽略)。 补充:生产环境时,不使用flask自带的服务器,而是采用nginx+uwsgi(nginx作为前置服务器来接收浏览器发来的请求,之后请求会被转发给uwsgi);启动服务器不再是“Python ***.py”,而是由uwsgi加载模块,进而启动相关代码。在生产环境下,***就不再是入口文件了,他只是被uwsgi加载的模块文件,因此在生产环境下,app.run()是根本就不会被执行的。 加了 之后,可以保证我们在生产环境下,不去启动flask自带的服务器(即:app.run()) 补充:视图函数和普通函数不同,视图函数除了返回return信息之外,他会还会返回一系列的附加信息: a、status code 200 404 301 b、content-type ——放置于http header的属性中,它的作用是告诉浏览器的接收方如何解析我们return的主体内容。(在flask的默认值为text/html ) 7、response对象——flask会把你返回的东西作为响应的一个内容,同时会把主体内容和上面蓝字说的一些信息封装出一个对象,这个对象就叫做response对象。 创造response对象的流程: 首先导入make_response函数来创建对象 然后在视图函数中作出相应的更改 如此,返回页面会显示出文字<html></html>(因为response的content-type为text/plain) 补充:状态码只是一个标志,他并不会影响你要返回的一个内容,比如上面的视图函数会返回状态码404,但是网页依旧会有显示的内容。 如果把response改成如图 访问我们的主页时,就会直接重定向跳转到bing的首页。 8、如何返回json格式的内容: 假如我们视图函数的接口是为我们的小程序或者移动端的app来提供数据的话,通常我们把他叫做api,而api的数据通常是json格式的,如何返回json格式的内容?——只要把response对象的content-type的值改成 “application/json” 即可。 response返回对象的简写方式: 补充:如果你想在客户端生成cookie,就调用response的set_cookie方法就可以了。 数据与flask路由 搜索图书数据需要调用外部的api来获取图书检索数据 一、获取图书信息的两种方式: 1、关键字搜索: 2、isbn搜索: 补充:api一定要设置访问频率的控制,否则很容易被人搞瘫痪。 补充:编写网站和编写api没有太大的区别,只要搞清楚网站返回的是什么,api返回的是什么即可。 二、传递参数的方式 1、在url路径里传递参数 当中url里面加入了"<>",那么尖括号中的内容会被识别为是传入的参数,而不是固定的字符串 补充:Python里面的函数isdigit()可以自动识别参数是不是数字 用法: if q.isdigit(): 编程知识——看源代码的方法:分层去看,首先理清代码的结构线索即可,了解各个函数的功能即可,无需依次查看函数的源码;当你需要看源码的时候再去看函数的源码即可。 2、在Python里面调用api 创建文件——http.py 将http请求封装在http模块里 在Python中,发送和http请求有两种方案 1、使用Python自带的urllib模块来发送http请求(比较难用) 2、用requests这样一个第三方的库来发送http请求(推荐)。 用requests这样一个第三方的库来发送http请求的方法: 首先需要安装requests包 补充:api的地址——url 返回json格式的api的通用返回方法: 兼容返回json格式和字符串格式的api 简化if else 的方法 1、三元表达式: 2、巧妙的用if + return 来简化代码 3、把if和else里面的内容再提取成一个函数,然后再if和else里面调用我们的函数。 补充:Python爬虫可以用 scrapy(适合并发或者多线程的爬虫) 或者 requests+beautiful soap Python静态方法 1、@staticmethod 2、@classmethod——如果没有用到类里面相关的类变量时,没必要使用classmethod 补充:把方法封装到http对象里(如上图,函数被封装到class HTTP里),是为了以后便于扩展。 补充:在Python3里面class HTTP(object):和class HTTP:没有区别。在Python2里面,有经典类和新式类的区别。 三、从api获取数据 补充:json在Python里面会被准换成一个dict,也就是字典。 封装一个class,把获取的数据拼合出url,调用htp.py,获取json格式的返回值数据 在主函数中调用封装好的类,如此,实现输入一个关键词,返回json格式的数据 四、使用jsonify jsonify是flask的一个功能,用之前要import一下 此时我们将json格式的数据返回到了客户端。 五 、深入了解flask路由 flask的路由机制图解 不传endpoint,视图函数依然可以被找到,这是因为flask里面,如果不传endpoint,会把视图函数的函数名作为endpoint的默认值。 补充:flask调试模式如果启动,他会把你的代码执行两次,会有一个restart的过程(这也就是debug的默认值为什么是false的缘故) 装饰器在底层会调用add_url_rule函数 循环引入流程分析 下面两个代码互相import对方 book模块的导入用蓝线标示 由于第二次判断if语句的时候,name不等于main(因为这个模块是有book模块导入的),因此不会执行app.run()方法。 book模块会执行一次,为什么Fisher会执行两次?原因就是启动Fisher时,我们没有把Fisher当成模块导入,而是当作启动文件,因此他一共执行两次(启动时一次,导入时一次)。 补充:查看对象地址的方法(比如,查看app核心对象的地址:) 应用、蓝图与视图函数 蓝图 蓝图不能独立存在,他要插入到flask核心对象里。每一个蓝图又可以插入很多视图函数,蓝图还可以指定他自己的静态文件夹和模板文件夹。 思路——视图函数注册到蓝图里,蓝图注册到核心对象app里 补充:让一个文件夹成为一个包的方法——在文件夹下面(不是里面)加一个_init_.py文件 该文件用于核心对象的初始化工作。 应用级别的初始化工作 1、在_init_.py中初始化实例对象 2、在主执行程序里面调用函数来创建实例化对象: 蓝图的基本用法 蓝图的初始化工作会放到蓝图文件夹里面的_init_.py中进行 1、实例化蓝图对象(不再使用app来注册路由,我们使用蓝图来注册路由) 2、把视图函数注册到蓝图上 3、把蓝图注册到app里 蓝图的特性:蓝图不能替代视图函数核心对象,两个不是同一回事。 蓝图分模块管理——把不同的视图函数拆分到不同的文件 1、实例化蓝图 2、将蓝图导入并注册路由 3、将视图函数的模块导入执行 防止循环导入的方法: 1、把init.py里面的数理化导入到blueprint里面

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

HashMap源码学习笔记

最近忙于各种事情,只能陆陆续续也看了一些东西,Java的HashMap应该算比较基础的东西,也是最近在看<<Redis设计与实现>>,其中也有HashMap的数据结构,又回去看了一下Java本身实现,这篇也就再记录一下。 Java数据结构中定义了Map接口,该接口有四个常用实现类:HashMap,Hashtable,LinkedHashMap和TreeMap。 针对上面四个常用类简单的介绍一下: 1. Hashtable: 从下面的Java doc就可以看出,其本身是线程安全的,但是并发性不如concurrent中的ConcurrentHashMap,而不需要线程安全时候,也推荐使用HashMap,故可以算是一个遗留类,不推荐使用。 Hashtable Java doc 2. LinkedHashMap:它是HashMap的一个子类,保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的。 LinkedHashMap java doc 3. TreeMap:TreeMap实现SortedMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的。如果使用排序的映射,建议使用TreeMap。 TreeMap Java doc 4. HashMap:它根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。 HashMap最多只允许一条记录的键为null,允许多条记录的值为null。HashMap非线程安全,可能会导致数据的不一致。如果需要满足线程安全,可以使用之前提及的ConcurrentHashMap(不建议用Hashtable)。 本篇主要简单介绍的就是HashMap的实现,也是由于HashMap是最最常用的一个,可以满足大部分场景。自己工作了一年时间,基本也只用过HashMap= = 内部结构 HashMap内部的数据结构,就是最经典的数组+链表实现的哈希桶(JDK 1.7之前),从1.8之后,链表节点数量满足一定条件后,会自动转换成红黑树的数据结构,进一步提高查询效率。简单来说,HashMap的结构就是一个指针数组。 数据结构 图中的黑点则是存放Key-Value的Node,其数据结构如下: Node数据结构 其中 hash是用来定位数组索引位置, next是链表的下一个node。 字段 Map.put("key", "value") 在不考虑扩容的情况下,put操作会首先计算key的hash值,并通过取高位运算 + 取模运算两步,就能计算出该key在哈希桶的位置了。 当两个key定位在了同一个位置,则表示发生了Hash碰撞。因此,良好的Hash算法,能够尽量减少Hash碰撞,提高Map的存取效率。然而,即使很好的Hash算法,如果哈希桶的size很小(相比于Node数量),无论怎么计算,总是在这几个位置,也会出现很多碰撞。因此,解决碰撞,不仅需要良好的Hash算法,还需要一个良好的扩容机制。 要讨论扩容机制,就先看一下HashMap中的几个字段(附默认值): capacity: Hash桶容量 load_factor: 负载因子 size:已有node数量,modCount:内部结构变化次数,threshold=capacity * factor: 最大node数量 从上面几个字段可以看出,当put操作,使得size > threshold时,HashMap就会发生扩容。 并且从Java 动doc可以看出,Hash桶的大小一定是2的n次方。(正是这个限制,使得HashMap在扩容和计算key位置的运算效率提升了很多) 实现 Hash算法的实现,其实只有下面三行代码: int hashcode = key.hashCode(); // 获取hashcode int hashInt = hashcode ^(hashcode >>> 16 ); // 高位运算 int index = hashInt & (length - 1) // 取模运算,lenght是数组大小 第二步通过hashCode()的高16位异或低16位实现的:(h = k.hashCode()) ^ (h >>> 16),主要是从速度、功效、质量来考虑的,这么做可以在数组table的length比较小的时候,也能保证考虑到高低Bit都参与到Hash的计算中,同时不会有太大的开销。 第三步也是非常巧妙,因为Lenght是2的n次方,因此length - 1 永远是n个1,其实相当于对hashInt做了一次取模,但是效率极高。 下面是JDK 1.8的put代码实现: JDK1.8中put实现 line 627-628: table为空则创建. line 629-630: 计算index,并且check null, 如果为null, 直接创建一个index; line 633-635: 如果需要put的key和该位置原来的key一样,则直接覆盖value, 否则进行下面的追加操作 line 676-637: 红黑树操作,追加Node到红黑树 line 638-650: 链表操作,追加node到链表,并且判断是否需要转化为红黑树。 line 661-662: 判断是否需要扩容 扩容机制 扩容机制里的算法相对也比较复杂,HashMap的线程不安全性,也正是由于扩容时,链表操作可能导致的Infinite Loop引起。因此下一篇再具体举例说明吧。顺便可以一起把redis的HashMap resize机制一起说一下,基本都是大同小异。 总结 本篇就从源码角度,简单讲解HashMap的基本数据结构和关键操做的实现,以及简单介绍了扩容机制,由于JDK1.8以后的红黑树,导致扩容的代码更加复杂,但是扩容的算法相对于1.8之前,也有了不少优化,不过之后也不会深入算法方便,主要还是会介绍扩容的流程和原理。同事会结合redis的哈希表实现。

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

TweenMax学习笔记整理

因为要做一个案例,里面用到了很多动画,TweenMax真的是一个很强大的动画库,所以就学了一点里面的方法,现在整理出来 官网:https://greensock.com/tweenmax 注意:这个动画库是基于jQuery的,所以使用前要先引入jQuery哦! 下面的所有方法都在TimelineMax对象下,要先得到动画实例,所以使用我下面的方法的时候要注意先写下面的代码: var t = new TimelineMax(); 用到的方法整理: to():添加动画; 参数说明: 元素选择器或对象 持续时间 对象(变化的属性->值) 【可选】动画延迟发生的时间(可写数字,“-=0.5”,“+=0.5”) 一例胜千言,嗯,先看看下面的小实例 在这个例子中,等待1s后,元素"#div1"的left和width同时变化,left用时1s后到达目标点,width用时2s到达目标点,过1s钟高度开始变化,高度到达目标点后(用时2s),元素围绕z轴旋转180deg(用时2s),旋转后,透明度发生变化(用时2s) 注意:第四个参数是可选参数,如果我们没有写第四个参数,意味着,下面的动画执行都会在上一动画执行完之后开始执行,如果加了第四个参数,就是在上一动画的时间基础上加上或减少延迟时间(针对"+="或"-="),当然如果是数字num,那么 如果num>=0,那就是延迟num执行(注意:不是相对于前一个动画,而是相对于动画的开始时间哦),如果num<0,对于第一个t.to(),延迟负数就相当于0,第二个及以后的t.to,如果延迟时间小于0,则一打开页面运动已经执行完毕(看不到运动的过程) 2、staggerTo():添加动画 参数说明:1. 元素选择器或对象2. 持续时间3. 对象 变化的属性->值 4.【可选】一组动画间的延迟时间,数字 5. 【可选】一组动画整体延迟发生时间 可写数字,“-=0.5”,“+=0.5“ 这个方法和t.to()方法语法和使用都一样,那两者不一样的地方就是,先看下面的例子吧! 在这个例子中,如果我们没有加第四个参数的时候,两者的效果是一样的,即所有的div都同时执行,然后同时到达目标点 但是如果我们加了第四个参数的话,使用t.to()方法的时候,所有的div还是同时执行,但是如果我们使用的是t.staggerTo(),后面的div都会等到前面的div执行完成之后再执行(不是一起执行,而是依次执行) 注意:个人比较建议使用这个方法,一般是针对一类元素,然后,第四个参数,如果为正数,代表正序执行,绝对值代表延迟时间,如果是负数,则表示倒序执行,绝对值也是延迟时间(个人测试得出的结论) 如果是不同的类别元素使用t.staggerTo()方法,我测试发现,其实第四个参数并不起作用,不管时间是多少,都是按照写的顺序依次执行,并且中间是没有间隔的 <div class="div1"> </div> <div class="div2"> </div> <div class="div3"> </div> $(function(){ var t = new TimelineMax(); t.staggerTo( ".div1",1,{width:300},2 ); t.staggerTo( ".div2",3,{height:300},0); t.staggerTo( ".div3",1,{background:"blue"},-1); }); 上面的执行顺序是先div1宽度变化,然后div2的height发生变化,最后是div3的background发生变化 第五个参数,代表一组动画整体提前或延迟多少执行 上面的是我自己经过不断测试得出的结论,如果有什么地方不正确,欢迎指正哦 3、下面的比较好理解,看字面意思就知道了 stop():停止动画 play():开始动画 reverse():反向开始动画 onComplete():运动结束后触发对应的函数 onReverseComplete():反向运动结束后触发对应的函数 看例子吧 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style> #div1{ width: 100px; height: 100px; background: red; position: absolute; left: 0; top:50px; } </style> <script type="text/javascript" src="./js/jquery-1.8.3.js"></script> <script type="text/javascript" src="./js/TweenMax.js"></script> <script> $(function(){ var t = new TimelineMax(); t.stop(); t.to( "#div1",1,{left:300,onComplete:function(){ alert("left:300") },onReverseComplete:function(){ alert("反向left:0"); }} ); t.to( "#div1",2,{width:300,onComplete:function(){ alert("width:300") },onReverseComplete:function(){ alert("反向width:100") }} ); $("#play").click(function (){ t.play(); }) $("#stop").click(function (){ t.stop(); }) $("#reverse").click(function (){ t.reverse(); }) }) </script> </head> <body> <input type="button" id="play" value="播放" /> <input type="button" id="stop" value="停止" /> <input type="button" id="reverse" value="反向动画" /> <div id="div1"></div> </body> </html> 注意:如果我们没有加t.stop()方法的时候,元素都是在打开页面后便开始执行动画,当我们加了t.stop()方法后,所有的的动画都不会执行,只有我们调用t.play()方法的时候,才会开始执行 4、add---添加状态 参数说明: 1. 字符串或一个函数 TweenTo---完成指定的动画(过渡) 参数说明: 1. 指定时间或状态的字符串 这两个方法一般都是结合使用的,所以先看例子呗 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style> #div1{ width: 100px; height: 100px; background: red; position: absolute; left: 0; top:50px; } </style> <script type="text/javascript" src="./js/jquery-1.8.3.js"></script> <script type="text/javascript" src="./js/TweenMax.js"></script> <script> $(function(){ var t = new TimelineMax(); t.add("state1"); t.to( "#div1",1,{left:300} ); t.to( "#div1",2,{width:300} ); t.add("state2"); t.to( "#div1",3,{height:300} ); t.add("state3") t.tweenTo( "state2" ); }) </script> </head> <body> <div id="div1"></div> </body> </html> 注意:当我们使用t.tweenTo()方法的时候,即便我们添加了t.stop()方法,也不会影响t.tweenTo()方法的执行,比如在这个例子中,即便我们添加了t.stop()方法,页面在打开的时候,还是会立即执行到状态2 5、seek():完成指定的动画(无过渡) 参数说明: 1. 指定时间或状态 2. 【可选】布尔值 true:不执行函数 默认 false: 执行函数 和上面的t.tweenTo()方法很相似,不同的是,这个没有过渡效果,如果把上面的例子中t.tweenTo()方法换成t,seek()方法,结果就是一打开页面,元素的left和width就为300,看不多动画效果 5、下面两个很好理解了,就不啰嗦了 time():动画已执行的时间 clear:清除所有动画 6、 totalDuration():获取动画的总时长 getLabelTime():返回从开始到当前状态的时间参数说明:1. 状态的字符串返回值是一个数字 currentLabel():获取当前状态 返回值是状态的字符串 没什么好解释的,看例子就都懂了 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style> #div1{ width: 100px; height: 100px; background: red; position: absolute; left: 0; top:50px; } </style> <script type="text/javascript" src="./js/jquery-1.8.3.js"></script> <script type="text/javascript" src="./js/TweenMax.js"></script> <script> $(function(){ var t = new TimelineMax(); t.add( "state1" ); t.to( "#div1",1,{left:300}); t.to( "#div1",2,{width:300,onComplete:function(){ getCurrentLabel(); }} ); t.add( "state2" ) t.to( "#div1",3,{height:300,onComplete:function(){ getCurrentLabel(); }} ); t.add( "state3" ) alert( t.totalDuration() ) alert( t.getLabelTime( "state3" ) ) alert( t.currentLabel() ) getCurrentLabel(); function getCurrentLabel(){ //alert( t.currentLabel() ) alert( t.getLabelTime( t.currentLabel() ) ) } }) </script> </head> <body> <div id="div1"></div> </body> </html> 7、getLabelAfter():获取下一个状态 参数说明:1. 时间数字返回值是状态的字符串,如果没有下一个状态返回null getLabelBefore():获取上一个状态参数说明:1. 时间数字 返回值是状态的字符串,如果没有上一个状态返回null <!DOCTYPE html> <html lang="zh-cn"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style> #div1{ width: 100px; height: 100px; background: red; position: absolute; left: 0; top:50px; } </style> <script type="text/javascript" src="./js/jquery-1.8.3.js"></script> <script type="text/javascript" src="./js/TweenMax.js"></script> <script> $(function(){ var t = new TimelineMax(); t.add( "state1" ); t.to( "#div1",4,{left:300}); t.to( "#div1",5,{width:300,onComplete:function(){ getCurrentLabel(); }} ); t.add( "state2" ) t.to( "#div1",6,{height:300,onComplete:function(){ getCurrentLabel(); }} ); t.add( "state3" ) //alert( t.totalDuration() ) //alert( t.getLabelTime( "state3" ) ) //alert( t.currentLabel() ) getCurrentLabel(); function getCurrentLabel(){ //获取当前的时间 var currentTime = t.getLabelTime( t.currentLabel() ); //获取到上一个状态 var beforeLabel = t.getLabelBefore( currentTime ); //获取到下一个状态 var afterLabel = t.getLabelAfter( currentTime ); var str = "<p>上一个状态:"+ beforeLabel +"</p><p>当前状态:"+ t.currentLabel() +"</p><p>下一个状态:"+ afterLabel +"</p>"; $("#label").html( str ); } }) </script> </head> <body> <div id="label"></div> <div id="div1"></div> </body> </html> 原文发布时间:2018年06月18日 作者:冰雪为融 本文来源:CSDN如需转载请联系原作者

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

Java 学习(12)--接口

一、接口 (1)猫钻火圈,狗跳高等功能,不是动物本身就具备的,是在后面的培养中训练出来的, 这种额外的功能, java提供了接口表示。 (2)接口的特点: A:接口用关键字 interface修饰 interface 接口名 {} B:类实现接口用 implements修饰 class类名 implements 接口名 {} C:接口不能实例化 ,类可以有多个接口 D:接口的实现类 a:是一个抽象类。b: 是一个具体类,这个类必须重写接口中的所有抽象方法。 (3)接口的成员特点: A:成员变量 只能是常量,不能是变量 默认修饰符: public static final(默认添加) B:构造方法 没有构造方法,接口主要是拓展功能的,没有具体存在 C:成员方法 只能是抽象方法 默认修饰符: publicabstract 示例 输出:我是一个抽烟的人 示例2(接口与多态相配合,实现程序设计和程序运行相分离) 输出:开着飞机去邮信 (4)类与类 ,类与接口 ,接口与接口间的关系 A:类与类 继承关系,只能单继承,可以多层继承 B:类与接口 实现关系,可以单实现,也可以多实现。 还可以在继承一个类的同时,实现多个接口 C:接口与接口 继承关系,可以单继承,也可以多继承(不常用) (5)抽象类和接口的区别 A:成员区别 抽象类:成员变量:可以变量,也可以常量 构造方法:有 成员方法:可以抽象,也可以非抽象 接口;成员变量:只可以常量 成员方法:只可以抽象 B:关系区别 : 类与类 继承,单继承 类与接口 实现,单实现,多实现 接口与接口 继承,单继承,多继承 C:设计理念不同 抽象类: is a,抽象类中定义的是共性功能,概念上是相同的(猫、狗和动物)。 接口: like a,接口中定义的是扩展功能,概念上可以没关系(飞 、鸟、飞机)。 案例 项目分析是从具体到抽象的过程;项目实现是从抽象到具体的过程 写接口 调用实现 输出: 调用实现2 调用实现3 输出:

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Apache Tomcat

Apache Tomcat

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

Sublime Text

Sublime Text

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