应用层是网络应用程序和网络协议存放的分层,因特网的应用层包括许多协议,例如我们学 web 离不开的 HTTP,电子邮件传送协议 SMTP、端系统文件上传协议 FTP、还有为我们进行域名解析的 DNS 协议。应用层协议分布在多个端系统上,一个端系统应用程序与另外一个端系统应用程序交换信息分组,我们把位于应用层的信息分组称为 报文(message)。
因特网的网络层负责将称为 数据报(datagram) 的网络分层从一台主机移动到另一台主机。网络层一个非常重要的协议是 IP 协议,所有具有网络层的因特网组件都必须运行 IP 协议,IP 协议是一种网际协议,除了 IP 协议外,网络层还包括一些其他网际协议和路由选择协议,一般把网络层就称为 IP 层,由此可知 IP 协议的重要性。
链路层
现在我们有应用程序通信的协议,有了给应用程序提供运输的协议,还有了用于约定发送位置的 IP 协议,那么如何才能真正的发送数据呢?为了将分组从一个节点(主机或路由器)运输到另一个节点,网络层必须依靠链路层提供服务。链路层的例子包括以太网、WiFi 和电缆接入的 DOCSIS 协议,因为数据从源目的地传送通常需要经过几条链路,一个数据包可能被沿途不同的链路层协议处理,我们把链路层的分组称为 帧(frame)
浏览器正式的名字叫做 Web Broser,顾名思义,就是检索、查看互联网上网页资源的应用程序,名字里的 Web,实际上指的就是 World Wide Web,也就是万维网。
我们在地址栏输入URL(即网址),浏览器会向DNS(域名服务器,后面会说)提供网址,由它来完成 URL 到 IP 地址的映射。然后将请求你的请求提交给具体的服务器,在由服务器返回我们要的结果(以HTML编码格式返回给浏览器),浏览器执行HTML编码,将结果显示在浏览器的正文。这就是一个浏览器发起请求和接受响应的过程。
Web 服务器
Web 服务器的正式名称叫做 Web Server,Web 服务器一般指的是网站服务器,上面说到浏览器是 HTTP 请求的发起方,那么 Web 服务器就是 HTTP 请求的应答方,Web 服务器可以向浏览器等 Web 客户端提供文档,也可以放置网站文件,让全世界浏览;可以放置数据文件,让全世界下载。目前最主流的三个Web服务器是Apache、 Nginx 、IIS。
IP 协议的全称是 Internet Protocol 的缩写,它主要解决的是通信双方寻址的问题。IP 协议使用 IP 地址 来标识互联网上的每一台计算机,可以把 IP 地址想象成为你手机的电话号码,你要与他人通话必须先要知道他人的手机号码,计算机网络中信息交换必须先要知道对方的 IP 地址。(关于 TCP 和 IP 更多的讨论我们会在后面详解)
DNS
你有没有想过为什么你可以通过键入 http://www.google.com 就能够获取你想要的网站?我们上面说到,计算机网络中的每个端系统都有一个 IP 地址存在,而把 IP 地址转换为便于人类记忆的协议就是 DNS 协议。
DNS 的全称是域名系统(Domain Name System,缩写:DNS),它作为将域名和 IP 地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。
URI / URL
我们上面提到,你可以通过输入 http://www.google.com 地址来访问谷歌的官网,那么这个地址有什么规定吗?我怎么输都可以?AAA.BBB.CCC 是不是也行?当然不是的,你输入的地址格式必须要满足 URI 的规范。
GET 获取资源,GET 方法用来请求访问已被 URI 识别的资源。指定的资源经服务器端解析后返回响应内容。也就是说,如果请求的资源是文本,那就保持原样返回;
POST 传输实体,虽然 GET 方法也可以传输主体信息,但是便于区分,我们一般不用 GET 传输实体信息,反而使用 POST 传输实体信息,
PUT 传输文件,PUT 方法用来传输文件。就像 FTP 协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求 URI 指定的位置。
但是,鉴于 HTTP 的 PUT 方法自身不带验证机制,任何人都可以上传文件 , 存在安全性问题,因此一般的 W eb 网站不使用该方法。若配合 W eb 应用程序的验证机制,或架构设计采用REST(REpresentational State Transfer,表征状态转移)标准的同类 Web 网站,就可能会开放使用 PUT 方法。
HEAD 获得响应首部,HEAD 方法和 GET 方法一样,只是不返回报文主体部分。用于确认 URI 的有效性及资源更新的日期时间等。
DELETE 删除文件,DELETE 方法用来删除文件,是与 PUT 相反的方法。DELETE 方法按请求 URI 删除指定的资源。
OPTIONS 询问支持的方法,OPTIONS 方法用来查询针对请求 URI 指定的资源支持的方法。
public class MainTest { public static AtomicInteger num = new AtomicInteger(0); public static void main(String[] args) throws InterruptedException { Runnable runnable=()->{ for (int i = 0; i < 1000000000; i++) { num.getAndAdd(1); } System.out.println(Thread.currentThread().getName()+"执行结束!"); }; Thread t1 = new Thread(runnable); Thread t2 = new Thread(runnable); t1.start(); t2.start(); Thread.sleep(1000); System.out.println("num = " + num); } }
public test.StewardTipCategory(java.lang.String,java.util.Map<java.lang.Integer, java.util.List<java.lang.String>>)『C1』public test.StewardTipCategory(java.lang.String,java.util.List<test.StewardTipItem>)『C2』
publicclassAccessibleObjectimplements AnnotatedElement { ...... // NOTE: for security purposes, this field must not be visible booleanoverride; publicbooleanisAccessible() { returnoverride; } publicvoidsetAccessible(booleanflag) throwsSecurityException { ...... } ...... }
publicObjectinvoke(Objectobj, Object... args){ // 是否要进行安全检查 if (!override) { // 进行快速验证是否是 Public 方法 if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { // 返回调用这个方法的 Class Class<?> caller = Reflection.getCallerClass(); // 做权限访问的校验,缓存调用这个方法的 Class,避免下次在做检查 checkAccess(caller, clazz, obj, modifiers); } } ...... returnma.invoke(obj, args); }
字段 override 提供给子类去重写,它的值决定了是否要进行安全检查,如果要进行安全检查,则会执行 quickCheckMemberAccess() 快速验证是否是 Public 方法,避免调用 getCallerClass()。
如果是 Public 方法,避免做安全检查,所以我们在代码中不调用 setAccessible(true) 方法,也不会抛出异常
如果不是 Public 方法则会调用 getCallerClass() 获取调用这个方法的 Class,执行 checkAccess() 方法进行安全检查。
// it is necessary to perform somewhat expensive security checks. // A more complicated security check cache is needed for Method and Field // The cache can be either null (empty cache) volatileObjectsecurityCheckCache; // 缓存调用这个方法的 Class voidcheckAccess(Class<?>caller, Class<?>clazz, Objectobj, intmodifiers){ ...... Objectcache=securityCheckCache; // read volatile if(cache==调用这个方法的Class){ return; // ACCESS IS OK } slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass); ...... } voidslowCheckMemberAccess(Class<?>caller, Class<?>clazz, Objectobj, intmodifiers,Class<?>targetClass){ Reflection.ensureMemberAccess(caller, clazz, obj, modifiers); Objectcache=调用这个方法的Class securityCheckCache=cache; // 缓存调用这个方法的 Class }
Remove method breakpoints and consider using the regular line breakpoints.
删除方法断点并考虑使用常规的 line breakpoints。
官方还是很贴心的,怕你不知道怎么 Remove 还专门补充了一句:
To verify that you don't have any method breakpoints open .idea/workspace.xml file in the project root directory (or .iws file if you are using the old project format) and look for any breakpoints inside the method_breakpoints node.
minId = min(id) maxId = max(id) for(int i = minId; i<= maxId; i+=pageSize){ sele ct * from table_demo where type = ? and id between i and i+ pageSize; }
优化 GROU P BY
提高 GROU P BY 语句的效率, 可以通过将不需要的记录在 GROU P BY 之前过滤掉.下面两个查询返回相同结果但第二个明显就快了许多。
低效:
sele ct job , avg(sal) from table_demo grou p by job having job = ‘manager'
高效:
sele ct job , avg(sal) from table_demo where job = ‘manager' grou p by job
范围查询
联合索引中如果有某个列存在范围(大于小于)查询,其右边的列是否还有意义?
expla in sele ct count(1) from statement where org_code='1012' and trade_date_time >= '2019-05-01 00:00:00' and trade_date_time<='2020-05-01 00:00:00' expla in sele ct * from statement where org_code='1012' and trade_date_time >= '2019-05-01 00:00:00' and trade_date_time<='2020-05-01 00:00:00' limit 0, 100 expla in sele ct * from statement where org_code='1012' and trade_date_time >= '2019-05-01 00:00:00' and trade_date_time<='2020-05-01 00:00:00'
SELE CT id,....,creator,modifier,create_time,update_time FROM statement WHERE (account_number = 'XXX' AND create_time >= '2022-04-24 06:03:44' AND create_time <= '2022-04-24 08:03:44' AND dc_flag = 'C') ORDER BY trade_date_time DESC,id DESC LIMIT 0,1000;
优化前:SQL 执行超时被 kill 了
SELE CT id,....,creator,modifier,create_time,upda te_time FROM statement WHERE (account_number = 'XXX' AND create_time >= '2022-04-24 06:03:44' AND create_time <= '2022-04-24 08:03:44' AND dc_flag = 'C') ORDER BY create_time DESC,id DESC LIMIT 0,1000;
优化后:执行总行数为:6 行,耗时 34ms。
MySQL使不使用索引与所查列无关,只与索引本身,where条件,order by 字段,grou p by 字段有关。索引的作用一个是查找,一个是排序。
业务拆分
sele ct * from order where status='S' and update_time < now-5min limit 500
date = now; minDate = now - 10 days while(date > minDate) { sele ct * from order where order_date={#date} and status='S' and upda te_time < now-5min limit 500 date = data + 1 }
另外,值得注意的是,根据所使用的哈希算法,此方法理论上可能会导致 id 值的[哈希冲突数](https://en.wikipedia.org/wiki/Collision(computer_science))不为零,这在理论上可能导致两个不相同的文档映射到相同的_id,因此导致这些文档之一丢失。对于大多数实际情况,哈希冲突的可能性可能非常低。对不同哈希函数的详细分析不在本博客的讨论范围之内,但是应仔细考虑指纹过滤器中使用的哈希函数,因为它将影响提取性能和哈希冲突次数。
下面给出了使用指纹过滤器对现有索引进行重复数据删除的简单 Logstash 配置。
input { # Read all documents from Elasticsearch elasticsearch { hosts => "localhost" index => "stocks" query => '{ "sort": [ "_doc" ] }' } } # This filter has been updated on February 18, 2019 filter { fingerprint { key => "1234ABCD" method => "SHA256" source => ["CAC", "FTSE", "SMI"] target => "[@metadata][generated_id]" concatenate_sources => true # <-- New line added since original post date } } output { stdout { codec => dots } elasticsearch { index => "stocks_after_fingerprint" document_id => "%{[@metadata][generated_id]}" } }
#!/usr/local/bin/python3 importhashlib fromelasticsearchimportElasticsearch es = Elasticsearch(["localhost:9200"]) dict_of_duplicate_docs = {} # The following line defines the fields that will be # used to determine if a document is a duplicate keys_to_include_in_hash = ["CAC", "FTSE", "SMI"] # Process documents returned by the current search/scroll defpopulate_dict_of_duplicate_docs(hits): foriteminhits: combined_key = "" formykeyinkeys_to_include_in_hash: combined_key += str(item['_source'][mykey]) _id = item["_id"] hashval = hashlib.md5(combined_key.encode('utf-8')).digest() # If the hashval is new, then we will create a new key # in the dict_of_duplicate_docs, which will be # assigned a value of an empty array. # We then immediately push the _id onto the array. # If hashval already exists, then # we will just push the new _id onto the existing array dict_of_duplicate_docs.setdefault(hashval, []).append(_id) # Loop over all documents in the index, and populate the # dict_of_duplicate_docs data structure. defscroll_over_all_docs(): data = es.search(index="stocks", scroll='1m', body={"query": {"match_all": {}}}) # Get the scroll ID sid = data['_scroll_id'] scroll_size = len(data['hits']['hits']) # Before scroll, process current batch of hits populate_dict_of_duplicate_docs(data['hits']['hits']) whilescroll_size>0: data = es.scroll(scroll_id=sid, scroll='2m') # Process current batch of hits populate_dict_of_duplicate_docs(data['hits']['hits']) # Update the scroll ID sid = data['_scroll_id'] # Get the number of results that returned in the last scroll scroll_size = len(data['hits']['hits']) defloop_over_hashes_and_remove_duplicates(): # Search through the hash of doc values to see if any # duplicate hashes have been found forhashval, array_of_idsindict_of_duplicate_docs.items(): iflen(array_of_ids) >1: print("********** Duplicate docs hash=%s **********"%hashval) # Get the documents that have mapped to the current hashval matching_docs = es.mget(index="stocks", doc_type="doc", body={"ids": array_of_ids}) fordocinmatching_docs['docs']: # In this example, we just print the duplicate docs. # This code could be easily modified to delete duplicates # here instead of printing them print("doc=%s\n"%doc) defmain(): scroll_over_all_docs() loop_over_hashes_and_remove_duplicates() main()
Project name (baoge): -----项目名称,直接回车,按照括号中默认名字(注意这里的名字不能有大写字母,如果有会报错Sorry, name can no longer contain capital letters),阮一峰老师博客为什么文件名要小写 ,可以参考一下。
Project description (A Vue.js project): ----项目描述,也可直接点击回车,使用默认名字
Author (): ----作者,输入dongxili
接下来会让用户选择:
Runtime + Compiler: recommended for most users 运行加编译,既然已经说了推荐,就选它了
Runtime-only: about 6KB lighter min+gzip, but templates (or any Vue-specificHTML) are ONLY allowed in .vue files - render functions are required elsewhere 仅运行时,已经有推荐了就选择第一个了
Use ESLint to lint your code? (Y/n) 是否使用ESLint管理代码,ESLint是个代码风格管理工具,是用来统一代码风格的,一般项目中都会使用。
接下来也是选择题Pick an ESLint preset (Use arrow keys) 选择一个ESLint预设,编写vue项目时的代码风格,直接y回车
Setup unit tests with Karma + Mocha? (Y/n) 是否安装单元测试,我选择安装y回车
Setup e2e tests with Nightwatch(Y/n)? 是否安装e2e测试 ,我选择安装y回车
publicstaticvoidmain(String[] args){ int a =6; int b =0; try{
System.out.println("a/b的值是:"+ a / b); }catch(ArithmeticException e){
System.out.println("程序出现异常,变量b不能为0。"); }
System.out.println("程序正常结束。"); } }制
What we really want is the user experience of the native mobile platforms, combined with the developer experience we have when building with React on the web.
上文摘自React-Native发布稿,React-Native的开发既保留了React的开发效率又拥有媲美原生的用户体验,其运行原理并非使用webview所以不属于Hybrid开发,想了解的可以查看React Native运行原理解析这篇文章。React-Native提出的理念是‘learn once,write every where’,之所以不是‘learn once, run every where’,是因为不同平台的用户体验有所不同,因此要运行全平台仍需要一些额外的适配,这里是Occhino对React-Native的介绍。
const instructions = Platform.select({ ios:'Press Cmd+R to reload,\n'+ 'Cmd+D or shake for dev menu', android:'Double tap R on your keyboard to reload,\n'+ 'Shake or press menu button for dev menu', });
//noinspection BadExpressionStatementJS
type
Props ={}; //noinspection JSAnnotator exportdefaultclassAppextendsComponent<Props>{ render(){ return( <View style={styles.container}> <Text style={styles.welcome}>
Welcome to React Native! </Text> <Text style={styles.instructions}>
To get started, edit App.js </Text> <Text style={styles.instructions}> {instructions} </Text> </View> ); } }
@implementation RCTActionSheetManager { // Use NSMapTable, as UIAlertViews do not implement // which is required for NSDictionary keys
NSMapTable *_callbacks;}
mysql> show variables like 'innodb_file_per_table'; +-----------------------+-------+ | Variable_name | Value | +-----------------------+-------+ | innodb_file_per_table | ON | +-----------------------+-------+ 1 row in set (0.00 sec)
mysql> show variables like 'innodb_page_size'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | innodb_page_size | 16384 | +------------------+-------+ 1 row in set (0.00 sec)
mysql> SELECT b.name, a.name, index_id, type, a.space, a.PAGE_NO FROM information _schema.INNODB_SYS_INDEXES a, information _schema.INNODB_SYS_TABLES b WHERE a.table_id = b.table_id AND a.space <> 0 and b.name='test/user'; +-----------+---------+----------+------+-------+---------+ | name | name | index_id | type | space | PAGE_NO | +-----------+---------+----------+------+-------+---------+ | test/user | PRIMARY | 105 | 3 | 67 | 3 | | test/user | name | 106 | 0 | 67 | 4 | +-----------+---------+----------+------+-------+---------+ 2 rows in set (0.00 sec)
show global variables like "%datadir%" ; +---------------+-----------------------+ | Variable_name | Value | +---------------+-----------------------+ | datadir | /usr/local/var/mysql/ | +---------------+-----------------------+ 1 row in set (0.01 sec)