Spring Data Rest实战

一 新建Spring Boot项目 1 新增依赖spring-boot-starter-data-jpa、spring-boot-starter-data-rest和ojdbc6 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-rest</artifactId> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0.2.0</version> </dependency> </dependencies> 2 配置application.properties spring.datasource.driverClassName=oracle.jdbc.OracleDriver spring.datasource.url=jdbc\:oracle\:thin\:@localhost\:1521\:xe spring.datasource.username=system spring.datasource.password=oracle #配置jpa #Hibernate提供了根据实体类自动维护数据库表结构的功能 #create:启动时删除上一次生成的表,并根据实体类生成表,表中的数据会被清空 #create-drop:启动时候根据实体类生成表,sessionFactory关闭时表会被删除 #update:启动时会根据实体类生成表,当实体类属性表动时,表的结构也会更新,在初期开发阶段使用此选项 #validate:启动是验证实体类和数据表是否一致,在数据结构稳定时采用此选项 #none:不采取任何手段 spring.jpa.hibernate.ddl-auto=update #用来设置Hibernate操作的时候在控制台显示真实的sql语句。 spring.jpa.show-sql=true spring.jackson.serialization.indent_output=true debug=true 二 实体类 package com.wisely.ch8_3.domain; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Person { @Id @GeneratedValue private Long id; private String name; private Integer age; private String address; public Person() { super(); } public Person(Long id, String name, Integer age, String address) { super(); this.

常用数据结构代码--C语言版(笔记)

代码目录: 第3章 线性表 01线性表顺序存储_List 02线性表链式存储_LinkList 03静态链表_StaticLinkList 第4章 栈与队列 01顺序栈_Stack 02两栈共享空间_DoubleStack 03链栈_LinkStack 04斐波那契函数_Fibonacci 05顺序队列_Queue 06链队列_LinkQueue 第5章 串 01串_String 02模式匹配_KMP 第6章 树 01二叉树顺序结构实现_BiTreeArray 02二叉树链式结构实现_BiTreeLink 03线索二叉树_ThreadBinaryTree 第7章 图 01邻接矩阵创建_CreateMGraph 02邻接表创建_CreateALGraph 03邻接矩阵深度和广度遍历DFS_BFS 04邻接表深度和广度遍历DFS_BFS 05最小生成树_Prim 06最小生成树_Kruskal 07最短路径_Dijkstra 08最短路径_Floyd 09拓扑排序_TopologicalSort 10关键路径_CriticalPath 第8章 查找 01静态查找_Search 02二叉排序树_BinarySortTree 03平衡二叉树_AVLTree 04B树_BTree 05散列表_HashTable 第9章 排序 01排序_Sort 注:1、这是《大话数据结构》一书的笔记; 2、文章太长,需要用啥搜索即可; 3、部分重要的知识点会慢慢更新出来; 第3章、线性表 //01线性表顺序存储_List #include "stdio.h" #include "stdlib.h" #include "io.h" #include "math.h" #include "time.h" #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXSIZE 20 /* 存储空间初始分配量 */ typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */ typedef int ElemType; /* ElemType类型根据实际情况而定,这里假设为int */ Status visit(ElemType c) { printf("

influxDB的端口和配置

influxDB的端口和配置 此文档包含infuxDB的常用信息,比如:监控的端口,配置文件位置,常用的配置等,方便以后查找和修改. 端口 默认influxDB使用以下端口 8086: 用于客户端和服务端交互的HTTP API8088: 用于提供备份和恢复的RPC服务 配置 配置文件通过安装包安装,在linux上默认位置: /etc/influxdb/influxdb.conf 查看默认配置: # 列出当前使用的配置 influxd config 使用指定配置文件启动 influxd -config /etc/influxdb/influxdb.conf 使用路径 默认数据保存路径/var/lib/influxdb/data 默认`write-ahead-log(WAL)保存路径/var/lib/influxdb/wal 默认metadata 保存路径/var/lib/influxdb/meta 网络时间协议(NTP) influxDB使用所在主机的本地时间的UTC时间(比国内晚8个小时)来设置timestamp,多个主机之间使用NTP协议同步时间,如果时间不同步,会导致数据的时间戳不准确.

RBMQ消息的消费,确认,防丢失

RBMQ消息的消费,确认,防丢失 参考翻译自: RabbitMQ官网 向多消费者分发消息 当有多个消费者时: 使用Round-robin方法,也就是循环发送,一个消息发送给一个消费者,下一条消息发送给下一个消费者,依次循环.每个消息只发送给一个消费者 消息确认机制 每个消费者消费后,需要反馈给MQ,确认消息已经被消费,MQ可以删除掉如果一个消费者挂掉(channel关闭,connection 关闭,或者TCP连接丢失),MQ便会得知消费者挂掉,如果此时还有别的消费者,MQ将消息发给存活的消费者消费者消费消息没有超时的概念,消费者处理一条消息不管都长时间只要没有挂掉,MQ都不会重发消息确认消息必须和接收消息是同一个channel,如果使用不同的channel确认消息,会引发channel-level protocol exception 如果忘记确认消息,MQ将会吃掉很大的内存来维持未确认的消息,而且一旦一个消费者挂掉,那么它没有确认的消息会再次发给其他消费者. 可以通过使用rabbitmqctl打印为确认的消息: sudo rabbitmqctl list_queues name messages_ready messages_unacknowledged 消息防丢 当MQ宕机时,内存中的消息队列和消息会丢失,为了避免可以通过设置避免队列和消息丢失 避免队列丢失 声明队列时,设置durable为true boolean durable = true; channel.queueDeclare("hello", durable, false, false, null); 一个队列只有在第一次声明的时候,设置的参数才起作用,当对一个已经存在的消息队列再次声明,设置参数的时候,不会起作用. 避免消息丢失 通过设置MessageProperties的值为PERSISTENT_TEXT_PLAIN将消息持久化: channel.basicPublish("", "task_queue", MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes()); 消息持久化到磁盘,并不能完全避免消息丢失,因为在写到磁盘时也有缓存. 均匀分发消息(Fair dispatch) 当MQ中消息有的容易处理,有的处理慢,会导致个别的消费者的压力大,比如第一个,第三个等消息处理起来慢,如果有两个消费者,这样会导致第一个消费者压力大,为了避免这样情况,可以通过设置参数,只有消费者消费完一个消息才会给它再分发消息: int prefetchCount = 1; channel.basicQos(prefetchCount); 队列大小 如果所有消费者都慢,会导致队列消息满了,此时需要增加消费者或者使用其他策略

RBMQ发布和订阅消息

RBMQ发布和订阅消息 exchange 参考翻译自: RabbitMQ官网 生产者并非将消息直接发送到queue,而是发送到exchange中,具体将消息发送到特定的队列还是多个队列,或者是丢弃,取决于exchange的类型 exchange的类型 directtopicheadersfanout bindings(绑定队列) 当生产/消费exchange时,可以绑定队列到exchange中: channel.queueBind(queueName, EXCHANGE_NAME, ""); bind方法将一个队列和一个exchange绑定到一起,第三个参数 routing key,相当于描述这个绑定关系的key,会根据不同类型的exchange,来决定将消息发送到queue中,多个queue中,或者消费时,将消息递送到绑定的queue中 fanout类型 fanout将收到的所有消息发送到所有的已知队列中. 定义一个fanout类型的exchange channel.exchangeDeclare("logs", "fanout"); 发送消息到exchange中 channel.basicPublish( "logs", "", null, message.getBytes()); 消费exchange 当我们消费一个fanout类型的exchange时,exchange发送消息到多个queue,而我们想要消费所有的queue,而不是其中一部分,而我们不知道消息具体被发送到哪个queue,也没法指定多个queue,此时需要一个临时queue Temporary Queue String queueName = channel.queueDeclare().getQueue(); 这样定义了一个临时queue,这个队列非持久,消费者独有的,会被自动删除,当消费者断开连接时,临时queue自动被删除 为了告诉exchange发送消息到我们定义的临时queue,需要进行绑定操作: channel.queueBind(queueName, "logs", ""); direct类型 生产队列 channel.queueBind(queueName, EXCHANGE_NAME, "black"); channel.queueBind(queueName1, EXCHANGE_NAME, "white"); 当exchange为direct类型时,会将exchange和queuename绑定到一起绑定key为black,将exchange和queuename1绑定到一起,绑定key为white.fonout类型会忽略第三个参数,当发送消息时: channel.basicPublish(EXCHANGE_NAME, "black", null, message.getBytes()); channel.basicPublish(EXCHANGE_NAME, "white", null, message1.getBytes()); 此时,会将message发送到绑定的queuename队列中,message1发送到绑定的queuename1队列中. 绑定多个队列到一个binding key时,相当于广播,会将消息发送到多个队列中 消费队列 String queueName = channel.queueDeclare().getQueue(); for(String severity : argv){ channel.queueBind(queueName, EXCHANGE_NAME, severity); } 当消费一个direct类型的exchange时,通过binding key 决定消费哪个队列

Asp.net Core 过滤器(AuthorizationFilter,ActionFilter)

asp.net core 里面的过滤器有这么多(还提供的异步的过滤器): IActionFilter IResourceFilter IResultFilter IAuthorizationFilter IPageFilter IExceptionFilter 一、身份验证过滤器AuthorizationFilter using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace CoreTest.Filter { public class AuthFilter : Attribute, IAuthorizationFilter { public void OnAuthorization(AuthorizationFilterContext context) { if (context.HttpContext.User.Identity.Name != "1") //只是个示范作用 { //未通过验证则跳转到无权限提示页 RedirectToActionResult content = new RedirectToActionResult("NoAuth", "Exception",null); context.Result = content; } } } } 二、行为过滤器ActionFilter using Microsoft.AspNetCore.Mvc.Filters; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.

数据导入的几种方法

Pima Indians 数据集 从 UCI 中获取的,这是一个分类问题的数据集,主要记录了印第安人最近五年内是否患糖尿病的医疗数据。 (数据集文件见最后。) 使用标准 Python 类库导入数据 import csv import numpy as np filename = 'pima_data.csv' with open(filename, 'rt') as raw_data: readers = csv.reader(raw_data, delimiter=',') # csv.reader 读出来的是字符串 x = list(readers) # 将字符串转换成浮点型 data = np.array(x).astype('float') print(data.shape) print(data) 使用 NumPy 导入数据 from numpy import loadtxt # 使用 numpy 导入 CSV 数据 filename = 'pima_data.csv' with open(filename, 'rt') as raw_data: data = loadtxt(raw_data, delimiter=',') print(data.shape) print(data) 使用 Pandas 导入数据 import pandas as pd # 使用 Pandas 导入 CSV 数据 filename = 'pima_data.

ResNets

ResNets 背景: 非常非常深的神经网络是很难训练的,因为存在梯度消失和梯度爆炸问题。 《转载+更改》 https://blog.csdn.net/qq_29893385/article/details/81207203 ResNets是由残差块(Residual block)构建的 首先解释一下什么是残差块。 这是一个两层神经网络,在 relu层进行激活,得到a^(l+1) ,再次进行激活,两层之后得到a^(l+2) 。计算过程是从a^1 开始,首先进行线性激活,根据这个公式: ,通过 算出 ,即 乘以权重矩阵,再加上偏差因子。然后通过ReLU非线性激活函数得到 , 计算得出。 接着再次进行线性激活,依据等式 ,最后根据这个等式再次进行ReLu非线性激活,即 ,这里的 是指ReLU非线性函数,得到的结果就是 。换句话说,信息流从 到 需要经过以上所有步骤,即这组网络层的主路径。 在残差网络中的变化: 前面的输入,将直接传向后,拷贝到神经网络的深层,在ReLU非线性激活函数前加上 ,形成一条捷径。 a^1 的信息直接到达神经网络的深层,不再沿着主路径传递,ReLU非线性函数,对 二个输入进行函数处理,即: ,产生一个残差块。 在上面这个图中,画一条捷径,直达第二层。 这条捷径在进行ReLU非线性激活函数之前加上的,而这里的每一个节点都执行了线性函数和ReLU激活函数。插入的时机是在线性激活之后,ReLU激活之前。 除了捷径,另一个术语“跳跃连接”,就是指跳过一层或者好几层,从而将信息传递到神经网络的更深层。 ResNet的发明者是何恺明(Kaiming He)、张翔宇(Xiangyu Zhang)、任少卿(Shaoqing Ren)和孙剑(Jiangxi Sun),他们发现使用残差块能够训练更深的神经网络。所以构建一个ResNet网络就是通过将很多这样的残差块堆积在一起,形成一个很深神经网络。 这并不是一个残差网络,而是一个普通网络(Plain network),这个术语来自ResNet论文。 把它变成ResNet的方法是加上所有跳跃连接,每两层增加一个捷径,构成一个残差块。如图所示,5个残差块连接在一起构成一个残差网络。 如果我们使用标准优化算法训练一个普通网络,比如说梯度下降法,或者其它热门的优化算法。如果没有残差,没有这些捷径或者跳跃连接,凭经验你会发现随着网络深度的加深,训练错误会先减少,然后增多。而理论上,随着网络深度的加深,应该训练得越来越好才对。也就是说,理论上网络深度越深越好。但实际上,如果没有残差网络,对于一个普通网络来说,深度越深意味着用优化算法越难训练。实际上,随着网络深度的加深,训练错误会越来越多。 但有了ResNets就不一样了,即使网络再深,训练的表现却不错,比如说训练误差减少,就算是训练深达100层的网络也不例外。有人甚至在1000多层的神经网络中做过实验,尽管目前我还没有看到太多实际应用。但是对 的激活,或者这些中间的激活能够到达网络的更深层。这种方式确实有助于解决梯度消失和梯度爆炸问题,让我们在训练更深网络的同时,又能保证良好的性能。也许从另外一个角度来看,随着网络越来深,网络连接会变得臃肿,但是ResNet确实在训练深度网络方面非常有效。

IP地址自动封与解封的shell脚本

本脚本学习与阿铭的脚本课程。 用于防止公司网站被DDos攻击时,封禁“”肉机“” 的IP地址。 共分为以下步骤: 1、每分钟分析一次访问日志/data/logs/access_log。 2、把访问量超过100的IP给封掉。 3、将封过的IP地址全部记录到一个日志log中。 4、每隔一段时间检查一次被封的IP,将不在超过100的访问的IP解封。 5、解封的IP记录到另外的日志中。 #!/bin/bash #用途:防止DDos攻击,将访问量超过100的IP地址禁掉 #作者:Caron maktini #日期:2018年10月17日 #版本:v0.1 t1='date -d "-1 min " +%Y:%H:%M' log=/data/logs/access_log block_ip() { egrep "$t1:[0-5]+ " ¥log > /tmp/tmp_last_min.log #把一分钟内访问量高于100的ip地址记录到一个临时文件中。 awk '{print $1}' /tmp/_last_min.log | sore -n | uniq -c | awk '$1>100 {print $2}' > /tmp/bad_ip.list #计算ip的数量 n=`wc -l /tmp/bad_ip.list | awk '{print $1}'` #当ip数大于0时,才会用iptables封掉。 if [ $n -ne 0 ] then for ip in `cat /tmp/bad_ip.list` do iptables -I INPUT -s $ip -j REJCT done #将这些被封的ip记录到日志里 echo "

AJAX数据传输的四大步骤

AJAX数据传输的四大步骤 1、XHR 创建对象 2、XHR 请求 3、XHR 响应 4、XHR readyState AJAX - 创建 XMLHttpRequest(XHR) 对象 所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)。 XMLHttpRequest 用于在后台与服务器交换数据。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。 创建 XMLHttpRequest 对象的语法: variable=new XMLHttpRequest(); 老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象: variable=new ActiveXObject("Microsoft.XMLHTTP"); 为了应对所有的现代浏览器,包括 IE5 和 IE6,请检查浏览器是否支持 XMLHttpRequest 对象。如果支持,则创建 XMLHttpRequest 对象。如果不支持,则创建 ActiveXObject : AJAX - 服务器请求(连接与发送) send()请求是同步的,意味着后续的js代码必须等到服务器响应之后才继续执行。所以在收到响应后, 响应的数据会自动填充到XHR对象的属性。 如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open() 和 send() 方法: var url="ajax_info.txt"; xmlhttp.open("GET",url,true); xmlhttp.send(); 方法描述open(method,url,async)规定请求的类型、URL 以及是否异步处理请求。 method:请求的类型;GET 或 POST url:文件在服务器上的位置 async:true(异步)或 false(同步)send(string)将请求发送到服务器。 string:仅用于 POST 请求,null或不填用于get请求 信息传输方式是 GET 还是 POST?

bootstrap--表格(table的各种样式)

目录 bootstrap--表格(table的各种样式) Bootstrap 表格类样式 ☑ .table:基础表格,为任意 <table> 添加基本样式 (只有横向分隔线) ☑ .table-striped:斑马线表格 ☑ .table-bordered:带边框的表格 ☑ .table-hover:鼠标悬停高亮的表格 ☑ .table-condensed:紧凑型表格 ☑ .table-responsive:响应式表格 1、“.table”主要有三个作用: ☑ 给表格设置了单元内距及底部边距margin-bottom:20px ☑ 在thead底部设置了一个2px的浅灰实线 ☑ 每个单元格顶部设置了一个1px的浅灰实线 样式图如下: 2、table-striped:斑马线表格 样式图如下: 3、table-bordered:带边框的表格 样式图如下: 4、table-hover:鼠标悬停高亮的表格 样式图如下: 5、table-condensed:紧凑型表格(单元格的内距由8px调至5px。) 样式图如下: 6、table-responsive:响应式表格(当浏览器可视区域小于768px时,表格底部会出现水平滚动条;可视区域大于768px时,表格底部水平滚动条就会消失) 样式图如下: 7、综合应用 样式图如下: 源代码如下: <div class="container"> <h2>表格</h2> <p>联合使用所有表格类:</p> <table class="table table-striped table-bordered table-hover table-condensed"> <thead> <tr> <th>#</th> <th>Firstname</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>Anna</td> </tr> <tr> <td>2</td> <td>Debbie</td> </tr> <tr> <td>3</td> <td>John</td> </tr> </tbody> </table> </div> Bootstrap的JS,CSS等我就不贴出来了,自行引入,具体可参考Bootstrap 中文网

RocketMQ的消息发送方式

目录 同步发送 异步发送 单向发送 总结 同步发送 简单来说,同步发送就是指 producer 发送消息后,会在接收到 broker 响应后才继续发下一条消息的通信方式。 由于这种同步发送的方式确保了消息的可靠性,同时也能及时得到消息发送的结果,故而适合一些发送比较重要的消息场景,比如说重要的通知邮件、营销短信等等。在实际应用中,这种同步发送的方式还是用得比较多的。 异步发送 接着就是异步发送,异步发送是指 producer 发出一条消息后,不需要等待 broker 响应,就接着发送下一条消息的通信方式。需要注意的是,不等待 broker 响应,并不意味着 broker 不响应,而是通过回调接口来接收 broker 的响应。所以要记住一点,异步发送同样可以对消息的响应结果进行处理。 由于异步发送不需要等待 broker 的响应,故在一些比较注重 RT(响应时间)的场景就会比较适用。比如,在一些视频上传的场景,我们知道视频上传之后需要进行转码,如果使用同步发送的方式来通知启动转码服务,那么就需要等待转码完成才能发回转码结果的响应,由于转码时间往往较长,很容易造成响应超时。此时,如果使用的是异步发送通知转码服务,那么就可以等转码完成后,再通过回调接口来接收转码结果的响应了。 单向发送 单向发送,见名知意,就是一种单方向通信方式,也就是说 producer 只负责发送消息,不等待 broker 发回响应结果,而且也没有回调函数触发,这也就意味着 producer 只发送请求不等待响应结果。 由于单向发送只是简单地发送消息,不需要等待响应,也没有回调接口触发,故发送消息所耗费的时间非常短,同时也意味着消息不可靠。所以这种单向发送比较适用于那些耗时要求非常短,但对可靠性要求并不高的场景,比如说日志收集。 总结 下面通过一张表格,简单总结一下同步发送、异步发送和单向发送的特点。 发送方式发送TPS发送结果响应可靠性同步发送小有不丢失异步发送中有不丢失单向发送大没有可能丢失 可以看到,从发送 TPS 来看,由于单向发送不需要等待响应也没有回调接口触发,发送速度非常快,一般都是微秒级的,在消息体大小一样的情况下,其发送 TPS 最大。而同步发送,需要等待响应结果的返回,受网络状况的影响较大,故发送 TPS 就比较小。异步发送不等待响应结果,发送消息时几乎不受网络的影响,故相比同步发送来说,其发送 TPS 要大得多。 关于可靠性,大家需要牢记前面提过的,异步发送并不意味着消息不可靠,异步发送也是会接收到响应结果,也能对响应结果进行处理。即使发送失败,也可以通过一些补偿手段进行消息重发。和同步发送比起来,异步发送的发送 TPS 更大,更适合那些调用链路较长的一些场景。在实际使用中,同步发送和异步发送都是较为常用的两种方式,大家要视具体业务场景进行合理地选择。 转载自:冯先生的笔记 

VMware虚拟机屏幕太小,解决方案(windows)

问题描述: 调整全屏也不行虚拟机设置自适应同样不行 解决办法 系统分辨率不正确 调整虚拟机里的系统分辨率 2.保存后屏幕会调整(一次调整不行多调整基础分辨率,直到调整到合适的范围)

vue.js实现左边导航切换右边内容

<template> <div class="layout-container"> <y-header> <div slot="nav"></div> </y-header> <div class="w"> <div class="content"> <div class="account-sidebar"> <div class="gray-box "> <div class="box-inner"> <ul class="account-nav"> <li v-for="(item,i) in nav" :key='i'> <a href="javascript:;"> <div class="account-nav-primary" @click="tabPrimary(item)" :class="{active:item.isActive}"> <span>{{item.name}}</span> <i class="el-icon-arrow-right"></i> </div> </a> <div v-if="item.secondNav==true"> <ul class="account-nav-second" v-show="show"> <li v-for="(itemT,j) in item.navSecond" :key='j' :class="{active:itemT.name===title}" @click="tabSecond(itemT)"> <span>{{itemT.name}}</span> </li> </ul> </div> </li> </ul> </div> </div> <div class="gray-box sidebar-bottom content-center"> <div class="img-code"> <img src="../../assets/static/img-code.png" width="100"/> </div> <span>扫一扫下载APP</span> </div> </div> <div class="

【ORACLE】Oracle提高篇之DECODE

DECODE含义 decode(条件,值1,返回值1,值2,返回值2,…值n,返回值n,缺省值) 这个是decode的表达式,具体的含义解释为: IF 条件=值1 THEN RETURN(翻译值1) ELSIF 条件=值2 THEN RETURN(翻译值2) ...... ELSIF 条件=值n THEN RETURN(翻译值n) ELSE RETURN(缺省值) END IF DECODE的用法 这里主要说的就是decode的用法,在很多时候这个函数还是很有用的。 1.翻译值 数据截图: 需求:查询出的数据,1表示男生,2表示女生 select t.id, t.name, t.age, decode(t.sex, '1', '男生', '2', '女生', '其他') as sex from STUDENT2 t 结果: 2.decode比较大小 说明:sign(value)函数会根据value的值为0,正数,负数,分别返回0,1,-1 数据: 需求:年龄在20以上的显示20以上,20以下的显示20以下,20的显示正好20 select t.id, t.name, t.age, decode(sign(t.age - 20), 1, '20以上', -1, '20以下', 0, '正好20', '未知') as sex from STUDENT2 t 结果: 3.decode分段 数据暂无 需求:工资大于5000为高薪,工资介于3000到5000为中等,工资小于3000为底薪 select name, sal, decode(sign(sal - 5000), 1, '高薪', 0, '高薪', -1, decode(sign(sal - 3000), 1, '中等', 0, '中等', -1, '低薪')) as salname from person; 结果暂无

自动关机批处理bat,一行代码实现自动关机

新建文本,复制以下代码: @echo off shutdown.exe -s -t 10 保存,把后缀名txt改成bat,双击打开 10秒后自动关机,10的单位是s(秒),自行换算可以设定自己想要的时间。 取消自动关机,新建文本,复制以下代码: @echo off shutdown.exe -a 保存,把后缀名txt改成bat,双击打开,取消自动关机任务。

C/C++中int型上下限INT_MAX INT_MIN以及溢出

C中常量INT_MAX和INT_MIN分别表示最大、最小整数,定义在头文件limits.h中。 1.常量INT_MAX和INT_MIN值的大小 int占4字节32位,根据二进制编码的规则,INT_MAX = 2^31-1,INT_MIN= -2^31。C中int类型范围是-2147483648到2147483647 。 C/C++中,所有超过该限值的数,都会出现溢出,出现warning,但是并不会出现error。 2.关于INT_MAX INT_MIN的运算 由于二进制编码按原码、补码和反码的规则进行运算,所有程序中对INT_MAX和INT_MIN的运算应当格外注意,在出现溢出的时候,不遵循数学规则。 INT_MAX + 1 = INT_MIN INT_MIN - 1 = INT_MAX abs(INT_MIN) = INT_MIN 特别的:INT_MAX + 1 < INT_MAX, INT_MIN - 1 > INT_MIN, abs(INT_MIN) < 0. 另外,在C/C++语言中,不能够直接使用-2147483648来代替最小负数,因为这不是一个数字,而是一个表达式。表达式的意思是对整数21473648取负,但是2147483648已经溢出了int的上限,所以定义为(-INT_MAX -1)。 (1)最轻微的上溢是INT_MAX + 1 :结果是 INT_MIN; (2)最严重的上溢是INT_MAX + INT_MAX :结果是-2; (3)最轻微的下溢是INT_MIN - 1:结果是是INT_MAX; (4)最严重的下溢是INT_MIN + INT_MIN:结果是0 。

Cascaded Pyramid Network for Multi-Person Pose Estimation

Cascaded Pyramid Network 是2017年 COCO 人体姿态点检测时提出的网络,并获得了冠军。 CPN 的网络结构如下 GlobalNet 中分别提取了 ResNet 中4个不同blocks里的特征,利用不同尺度的语义信息来进行预测,RefineNet 主要对困难关键点进行定位。 其主要结构代码如下: resnet_fms = resnet101(image, is_train, bn_trainable=True) # 提取 ResNet101 中四个不同block中的 feature maps global_fms, global_outs = create_global_net(resnet_fms, is_train) # 将 ResNet feautre maps 输入到 GlobalNet 输出 global feature maps 和 global outputs,分别用于输入到 RefineNet 和计算 loss refine_out = create_refine_net(global_fms, is_train) GlobalNet的代码如下 def create_global_net(blocks, is_training, trainable=True): global_fms = [] global_outs = [] last_fm = None initializer = tf.contrib.layers.xavier_initializer() for i, block in enumerate(reversed(blocks)): with slim.

Golang 处理错误,panic defer PK try catch 机制

go 语言使用 panic defer 机制处理错误,但可能你喜欢使用 try catch 机制。因此,需知道两种机制之间的关系。演示代码如下: package main import ( "errors" "fmt" ) var ( internalError = errors.New("Don't need send out") KnowError = errors.New("Excepted error!") ) func main() { fmt.Println("Hello, 世界") //use `func() {}()` wrap try catch final blocks v, e := func() (v int, e error) { defer func() { //just like catch block if r := recover(); r != nil { e, _ = r.(error) switch e { case internalError: // do something here, such as: v += 5 e = nil case KnowError: fmt.

JavaSE多线程

锁的基础知识: 锁的类型: 悲观锁和乐观锁: 乐观锁:认为读多写少,遇到并发写的可能性极低,即每次去拿数据的时候认为别人不会修改,所以不会上锁,但是在更新的时候会判断在此期间有没有 人更新这个数据。 判断依据:在写时先读出当前版本号,然后加锁操作(比较跟上一次的版本号,如果一样就更新),如果失败就重复 读 -> 比较 ->写的操作 Java中的乐观锁基本都是通过CAS操作实现的,CAS是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败 CAS: 简单的来说,CAS有三个操作数,内存值 V, 旧的预期值 A,要修改的新值B。当且仅当预期值A与内存值V相等时,将内存值修改为B,否则返回V。 这是一种乐观锁的思路。它相信在它之前没有线程去修改内存值 缺点:会发生 ABA问题,即A被修改成B,然后又被修改成A,不能感知到修改 悲观锁:认为写多读少,遇到并发写的可能性高,每次在读写数据的时候都会上锁,如果别的线程想读写这个数据就会block直到拿到锁 1.Synchronized底层实现(*****): Java对象头:锁的对象保存在对象头中,synchronized锁的是对象 锁的状态分为:自旋锁,偏向锁,轻量级锁,重量级锁) 自旋锁:加锁后,只有一个线程进入代码块,其他线程等待(自旋等待),为重量级锁(monitorenter,重量级锁标志) 自旋锁:1.相当于怠速停车,具有不公平性,处于自旋状态的锁比重量级锁(它处于阻塞状态)更容易获得锁 2.自旋锁不会引起调用者立即睡眠,如果自旋锁已经被别的执行单元保持,调用者不放弃处理器的执行时间,进行忙循环(自旋), 跑的是无用的线程,JDK1.6后默认开启了自旋锁,自旋次数默认10次 3.自旋锁一直占用CPU,在未获得锁的情况下,一直进行运行 - - - 自旋,若不能在很短的时间内获得锁,将会使CPU效率降低 自适应自旋:1.减少无用线程占用CPU的问题 2.自旋的时间不再是固定的,由前一个在同一个锁上的自旋时间及锁拥有者的状态来决定。 3.如果在同一个锁对象上,自选等待刚好成功获得锁,并且持有锁的线程正在运行中,那么虚拟机就认为这次自旋很有可能会获得锁, 将会允许自旋等待更长的时间 重量级锁(Java头中的monitorenter对象):os需要从用户态 -> 内核态,开销较大。同一时刻多个线程竞争资源 轻量级锁(CAS操作):多线程在不同时刻访问共享资源,乐观锁的一种 偏向锁:更为乐观的锁,假定从始至终都是同一个线程在访问共享资源 JDK中锁只有升级过程,没有降级过程。 无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁 锁消除:消除类似于Vector等线程安全集合不存在共享资源竞争时,JVM将代码优化,解锁 2.synchronized 与 ReentrantLock 区别 synchronized: synchronized是Java中最基本同步互斥的手段,可以修饰代码块,方法,类 在修饰代码块的时候需要一个reference对象作为锁的对象 在修饰方法的时候默认当前对象作为锁的对象 修饰类的时候默认当前类的class对象作为锁的对象 synchronized会在进入同步块的前后分别形成monitorenter和monitorexit字节码指令,在执行monitorenter指令时会尝试获取对象的锁,如果 此对象没有被锁,或此对象已被当前线程锁住,则锁的计数器+1,如果monitorexit被锁的对象的计数器-1,直到为0就释放该对象的锁,由此 synchronized是可重入的,不会将自己锁死。 ReentrantLock: 除了synchronized的功能,多了三个高级功能 1.等待可中断 2.公平锁 3.绑定多个Condition 1.等待可中断 在持有锁的线程长时间不释放锁的时候,等待的线程可以放弃等待. tryLock(long timeout,TimeUnit unit)

Android 通过ADB Shell 强行关闭和启动应用

1.在PC上通过adb 关闭/启动应用 1)通过adb连接设备 adb connect 192.168.1.XX , 当然也可以通过USB 直接连接; 2) 执行adb shell ps 查看当前正在运行的进程列表,可以获取进程的名字; 3)执行adb shell am force-stop 包名 即可强行关闭进程,eg: adb shell am force-stop com.xxx.xxx 执行adb shell am start -n 包名/启动类的名称 , eg: adb shell am start -n com.xxx.xxx/com.xxx.xxx.SplashActivity 2.在代码中: try { //关闭其他应用 Process exec = Runtime.getRuntime().exec("am force-stop 包名"); //打开其他应用 Process exec = Runtime.getRuntime().exec("am start -n 包名/启动类名称"); if (exec.waitFor() == 0) { //执行成功 } } catch (Exception e) { e.

基于轨迹的游客行为特征分析

--------------------------------------------------------------------------------------------- [版权申明:本文系作者原创,转载请注明出处] 文章出处:https://blog.csdn.net/sdksdk0/article/details/83068473 作者:朱培 ID:sdksdk0 -------------------------------------------------------------------------------------------- 大数据时代,深度“数据挖掘”高级分析技术成为大势所趋,对于旅游景区来说,谁先掌握互联网平台、善用大数据,谁就最有可能先人一步破除体制壁垒与管理围墙,实现转型升级和跨越式发展。通过在旅游景区部署移动信号监测设备,就可以发现该群体游客的相关属性,例如在一个区县,在不同景点之间部署,可以发现游客移动的轨迹是怎么样,本文主要就是用于分析游客在不同景点之间的浏览情况,这样可以更加合理的设计景区与景区之间的交通路线,销售相关旅游产品和应急预案等方面的东西。本文所涉及的内容使用mysql+springboot来实现。 首先来看一下清洗完成后的数据:浏览线路的格式为: 景区A=>景区C=>景区B=>景区D。 现在有数据格式如下(完整的数据集在文末提供下载链接): 第一列为id,第二列为景区编号,第三列为用户编号,第四列为时间,第五列为景区名称。 1 18C8E750176E 3478D7E2C139 20180503000000 嵩溪村 2 18C8E750182A C46699E01080 20180503000000 江南第一家花海 3 18C8E750180E 084ACF3E591F 20180503000000 水晶城 4 18C8E75017DA 386EA2788110 20180503000000 高速路 5 18C8E7501806 205D479A3020 20180503000001 翠湖 6 18C8E750181E 442C05543BED 20180503000001 水晶城 7 18C8E750182E F06D781D8FAF 20180503000002 通济桥水库大坝 8 18C8E75017EE B4EFFAC7D0C7 20180503000002 汽车客运站 9 18C8E75017EE 6C5C14743F6F 20180503000002 汽车客运站 10 18C8E75017A6 F4B7B356B876 20180503000003 檀溪镇 11 18C8E750181A 4C0FC7DF8C8E 20180503000003 金狮湖 12 18C8E750180A B436A9063032 20180503000003 翠湖

div内的scroll局部滚动

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> *{ padding: 0; margin: 0; } .box { width: 300px; height: 200px; overflow: auto; background: red; margin: auto; top: 100px; position: relative; } .auo { width: 100%; height: 1000px; background: yellow; } .hh { width: 100%; height: 50px; text-align: center; background: green; } </style> </head> <body> <div class="box"> <div class="auo"> 22222222222222 <div class="hh">1</div> <div class="hh">2</div> <div class="hh">3</div> <div class="hh">4</div> <div class="

zabbix搭建及使用

一、server:redhat6 192.168.1.224 client:windows、redhat6 192.168.1.125、192.168.1.122 二、Linxu 服务端安装(源码包安装) 1、配置网络yum源 https://blog.csdn.net/weixin_36524613/article/details/80855481 2、安装mysql 1)yum -y install mysql mysql-server mysql-devel 2)MySQL 配置文件/etc/my.cnf中加入default-character-set=utf8 vim /etc/my.cnf 加入default-character-set=utf8 3)开启mysql服务 service mysqld start 4)创建 Root 管理员,设置root密码 mysqladmin -u root password 123456 5)登陆 MySQL mysql -uroot -p123456 6)创建 zabbix 数据库,并设置登陆权限 mysql> create database zabbix character set utf8 collate utf8_bin; 7)添加zabbix用户并设置密码和访问权限 mysql> grant all privileges on zabbix.* to zabbix@localhost identified by 'zabbix'; 8)如果需要本地连接数据库,添加权限 mysql> GRANT ALL PRIVILEGES ON *.* TO 'zabbix'@'192.

live2d看板娘一览图

模型下载地址:https://github.com/xiazeyu/live2d-widget-models/tree/master/packages 搭建教程:https://www.jianshu.com/p/3a6342e16e57 epsilon2_1 chitose gf izumi koharu miku ni-j nico nietzsche nipsilon nito shizuku tororo tsumiki unitychan wanko z16 hibiki hijiki haruto

精彩的一期,龌龊的一期

我就是演员又迎来了精彩的一期,除了两段上乘的表演,一开始的影视化拍摄是我个人认为有史以来最好的一部,理想与现实的冲突、个人与家庭的关系,在一个中年演员的身上表现得淋漓尽致。老何(于和伟)对表演的执着痴迷和面对婚姻家庭的无力将张力推向了极致,当他看到妻子提出第二天再次来办离婚时,经过极度痛苦的挣扎后,终于向现实妥协,那一刻他的无奈、他恳求妻子时流露出的感情,深深打动了我。老何妻子的表现也入情入理,扣人心弦。 士兵突击这场戏也看得我眼泪打转。我没看过原版的电视剧,本来还担心军旅题材的作品会演得像战狼一样打鸡血,充斥民族主义的情绪,没想到是这样一段兄弟情、同袍谊,离别的时分总是伤感的,平时有泪不轻流的铮铮男儿此刻的眼泪就格外动人。经纬和曹骏的表演都十分饱满真挚。要说剧情和安排的瑕疵,我觉得是两处用力过猛。经纬谈自己的两个愿望,一是到天安门广场照相留念,二是吃北京烤鸭,这两点为了突出情怀和丰满人物设计得过分正确了,一个在北京卫戍7年(还是九年我忘了)的战士,再怎样忙,做到这两点也是没问题的。第二处就是最后全班战士集合送别班长,加起来竟然有23个人,难道是这个班伙食太好,其他班的战士都志愿加入吗。导演估计是想用人数形成气势,但此时的表演本身就已经很动人了,夸张反而会破坏作品的真实性和感染力。 左右这场戏,三个演员都很棒,现实主义的经典。选择哪个演员是见仁见智的事情,我偏向王阳,但感觉真的是难分伯仲,各有千秋,所以最后那个唯一没有被导师肯定的女演员也要给自己鼓一下气,说自己百分之百满意。 接下来就要说说本期节目的最大败笔。我就是演员的立意和制作,我一贯赞赏推崇,但有几点真的是像老鼠屎坏了一锅汤。上一季就是通过剪辑故意丑化袁立,就算双方发生一些不愉快,用这种手段来报复实在是器量狭小。再有就是一直有人诟病的晋级黑幕。节目既然采用竞赛的形式,公平就是至关重要的。虽然文无第一,武无第二,但是过分偏向某个演员就明显不是导师独具慧眼所能解释的。究其原因,要么是节目组看中偶像的市场号召力,要么是背后的人脉和利益关系驱使。上一季有些晋级就引起争议,这一季的郭麒麟就简直是明目张胆了。 节目组为了郭麒麟真是煞费苦心,演出后安排于谦上演真情推荐,为了不显得偏心和突兀,又特意为其他两位同台演员也准备了亲友应援。节目真的像徐峥说的那样,变成了狗粮的诞生。看似对三位演员不偏不倚,那和郭麒麟不同场的其他演员呢,谁还找不到个亲友,谁还没有一段感人肺腑的故事? 等到导师选择的环节就更滑稽了,除了章子怡令人钦佩地坚持了专业原则,徐峥说觉得郭麒麟的表演相对更淳朴,以后演员晋级的理由还可以有:表演相对更生涩,年龄相对更小……吴秀波也心虚了,说欣赏郭麒麟无词状态下的表演,郭麒麟无词状态下的表演胜过曹骏,还是说他的戏最少,你给他的同情分?两位导师这么没有说服力的选择理由,是由于节目组的内定安排,还是出于和郭德纲的个人情谊,我就不加揣测了。不过依照吴秀波八面玲珑让身边人都感到舒服的处事风格,调侃郭麒麟的演技超过郭德纲,一是因为父亲听到这样的话不会不开心,二是两人关系似乎不错。真要是严格的竞赛,这就算是有利益冲突了。不过毕竟是一档综艺节目,也彰显了中国人处处讲关系的特色。 不仅如此,为了给最后的结果做铺垫,徐峥和吴秀波在点评的时候就已经不断给郭麒麟加分了。为了不让最差的选手晋级这样的吃相太难看,又安排刘嘉玲为真正的好演员经纬爆灯,问题是这对曹骏多么不公平,对下一场表演的遗珠又多么不公平? 有人或许会为郭麒麟辩护,他的戏份最少。但作为一位经验最少的跨界演员,这样的角色安排才是公平的,就像假如经纬跨界去说相声,郭德纲肯定不会让郭麒麟去做他的捧哏。再说说郭麒麟的星二代身份,也有人会因此为他抱不平,从小就生活在父亲的光环之下。但我想说,每个人的出生都是他必须欣然接受的。有的人生在钟鸣鼎食之家,有的人在孤儿院长大,有的人身体健康,有的人先天残疾,但只有每个人后天的所作所为,才是它的价值所在。星二代固然有星二代的压力和烦恼,但也有别人欠缺的优势和环境。谢霆锋也是星二代出生,从小居无定所,在日本学艺几个月归来后出道,香港的观众是怎样对待他的?嘘声倒彩声淹没了他的歌声,还是没有挡住他靠自己的努力和才华闯出一条路。像郭麒麟这样,年纪轻轻就抱怨可能一辈子都超不过父亲,同时又利用父执辈的关系当自己成功的垫脚砖,只会印证人们对星二代的偏见。

uri=http://java.sun.com/jsp/jstl/core 出错问题

转载:https://blog.csdn.net/steven_sisi/article/details/79793146?utm_source=copy 1.遇到这种错误,说明少了两个架包,如果使用maven直接添加两个依赖 <dependency> <groupId>org.apache.taglibs</groupId> <artifactId>taglibs-standard-impl</artifactId> <version>1.2.5</version> </dependency> <dependency> <groupId>org.apache.taglibs</groupId> <artifactId>taglibs-standard-spec</artifactId> <version>1.2.5</version> </dependency> 转载:https://blog.csdn.net/hlg5555/article/details/7008689?utm_source=copy 有些时候,<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>会报错,错误提示为: Can not find thetag library descriptor for "http://java.sun.com/jsp/jstl/core" 解决此问题的方法为以下: 先导入这2个包jstl.jar ,standard.jar 在WEB-INF/lib里加入 jstl.jar standard.jar两个包即可解决这个问题 如果还不行就 把 uri=http://java.sun.com/jsp/jstl/core 这句重新手动输入下也许就行了 把c.tld导入WEB-INF下 ok 转载:https://blog.csdn.net/hlg5555/article/details/7008689?utm_source=copy 

MySQL之理解视图的with check option

视图定义: 视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个select语句保存在数据字典中的。 视图创建: CREATE VIEW 视图名(列表名) AS SELECT 查询子句 [WITH CHECK OPTION] 那么问题来了,WITH CHECK OPTION 的作用是什么??? 软考书上的解释:WITH CHECK OPTION 表示对UPDATE、INSERT和DELETE操作时保持更新、插入或删除的行满足视图定义的 的谓词条件(即子查询中的条件表达式) 怎么理解呢? 比如我创建如下视图 当我插入数据的id小于15时会报错 如果我插入数据的id大于15就没事

【计算机视觉算法岗面经】“吐血”整理:2019秋招资料

相关链接:【计算机视觉算法岗面经】“吐血”整理:2019秋招面经 //2018/09/27 兵荒马乱、浩浩荡荡的秋招终于差不多要结束了。 秋招这段时间真是感慨很多,一时得意一时失意,还要平衡一不小心就来的心理落差。 先写点废话吧,毕竟最近感受挺多的,在自己的博客里也不用顾忌措辞。强行给自己灌一波鸡汤~ 1、努力永远和收获成正比,即使这个比率很小。一直觉得自己没有特别的天赋,只能一点一点努力,而这点努力还经常被“比你优秀的人比你更努力”所击溃。但这又怎样呢,不努力连现在的自己都超越不了。个人觉得“比上不足”比“比下有余”更有分量。 2、向优秀的人看齐。忘记在哪看的一句话了,“当你超过别人一点点时,他们会嫉妒你,当你超过别人一大截时,他们只会羡慕你”,是啊,因为换位思考放在自己身上也是这样,我会嫉妒何恺明,嫉妒陆奇吗,很明显不会,我只会仰望。还是要脚踏实地啊。 3、对于秋招,运气真的蛮重要。因为你不知道刚好哪次就是你的人生际遇。但运气也是实力的一部分,若不是之前的厚积薄发,若不是敢于尝试,又哪里有这些机会呢。所以要不要海投呢?看你的精力是否支撑这些,看你想得到什么。 好了,下面整理面经。主要是自己整理的一些经常被问到的问题,然后搜集的一些资料(附了很多链接,如果侵权请告知删除),主要分为几大模块:HR面、深度学习、机器学习、图像处理、数学、计算机基础、C++、Python等。看整理的面经长度就知道哪个模块经常被问到了。 再说下面试基本会问的内容,目前个人所碰到的,占比可能有所不同,有些面试官喜欢问项目,有些喜欢问基础。 介绍项目、实习,一般会问很久,在你介绍中会问各种开放性问题;通常我的面试中这个占很大篇幅,60%-90%;问算法相关,包括ML\DL\图像处理等的基础知识,占40%-60%,其中大概ML40%,DL10%,图像处理10%;问数学基础,大部分是概率论,占5%;问语言,C++,STL容器之类的,占10%;python也会问一点;编程题,一般2、3题;Linux命令,一般问几个,不经常问到; 1、HR面 自我介绍你和竞争者相比的优势是什么实习收获了什么从实习导师身上学到了什么导师给你的意见是什么从面试官身上学到了什么.秋招意向的企业有哪些你为什么想来我们公司?你来了之后的三年怎么打算的?讲一讲实习公司的产品架构,比如一个新的需求产生到落地的流程是怎样?优缺点介绍项目,难点,从中学到什么,重新做如何改进期望薪资自己主动学习过哪些知识,通过什么方式学的后面打算学习什么知识,为什么英语怎么样兴趣竞赛、考研保研团队合作遇到的分歧有没有投过其他公司,有拿到offer吗?项目中怎么分工的,有遇到过水平低的吗,是怎么沟通的对你帮助很大的一个人学习的路径,怎么学习被批评以后的心里状态课题研究进展以及创新点、课题遇到的困难实习经历是否读博实习时间最有挫败感的事三-五年的规划人生理想最成功的一件事小时候印象最深的一件事 2、深度学习 2.1、Inception系列网络 https://blog.csdn.net/liuxiao214/article/details/81914743 2.2、Resnet系列网络 https://blog.csdn.net/liuxiao214/article/details/81914743 https://blog.csdn.net/u014380165/article/details/71667916 2.3、目标检测系列 RCNNFast RCNN ROI Pooling https://blog.csdn.net/lanran2/article/details/60143861 https://blog.csdn.net/auto1993/article/details/78514071 Faster RCNNYOLOSSDYOLO V2YOLO V3SSD V2FCN 2.4、主流CNN网络在imagenet上的准确率 2.5、attention机制 https://www.zhihu.com/question/68482809/answer/264070398 https://zhuanlan.zhihu.com/p/31547842 https://blog.csdn.net/yideqianfenzhiyi/article/details/79422857 2.7、loss - triple loss - center loss: https://blog.csdn.net/u014380165/article/details/71181256 https://blog.csdn.net/u014380165/article/details/76946339 https://blog.csdn.net/LIYUAN123ZHOUHUI/article/details/77100650?locationNum=7&fps=1 2.8、Normalization https://blog.csdn.net/liuxiao214/article/details/81037416 Batch NormalizationLayer NormalizationInstance NormalizationGroup NormalizationSwitchable Normalization 2.9、NLP系列 RNNLSTM 2.10、优化方法 https://www.baidu.com/link?url=ws6cxNIhWmVA1gbrUgFMRtACQhCMdYvcwZtLWOZfWZ0Iuujyt5Y4w08KNj7gn2ExUBD4jIybSJ8e3xb95cMWcL6hZXEn4IUJ5mRYnPoQbNC&wd=&eqid=ce9adcb10004685c000000035b5d4fb6 https://blog.csdn.net/chenchunyue11/article/details/51290638 SGDMomentumRMSpropAdam 2.11、最优化方法 1、梯度下降 2、牛顿法 3、拟牛顿法 4、共轭梯度法 https://www.cnblogs.com/happylion/p/4172632.html https://www.cnblogs.com/shixiangwan/p/7532830.html https://www.cnblogs.com/hlongch/p/5734105.html https://www.baidu.com/link?url=8EyCqGYnldJzHuqBBGagV9juEA_nhCYvRElM2Tw0lBdewSmc0qshAy_AHAEegO-wT3vLsrcY1xSDdyLOmL09Ltm_UICAFX_C02QdkkSCcWW&wd=&eqid=ce9adcb10004685c000000035b5d4fb6

SpringBoot中使用Jackson导致Long型数据精度丢失问题、处理jdk8日期类型转换

spring boot默认使用了jackson 处理请求映射,下面通过三种方案配置,对Long类型、jdk8日期类型的自定义转换处理 方案一:注解方式: @JsonSerialize(using=ToStringSerializer.class) private Long bankcardHash; 方案二:自定义ObjectMapper (推荐) /** * 配置spring boot内嵌的Jackson序列化与反序列化类型映射 * * -日期配置: * map.put(LocalDateTime.class, localDateTimeSerializer()); * Spring Boot 提供了 spring.jackson.date-format配置可以让我们进行日期格式化, * 但它只能格式化 java.util.Date。 * 定义一个配置类,在配置类注入Bean 实现日期全局格式化,同时还兼顾了 Date 和 LocalDateTime 并存。 * 需要配置 * spring: * jackson: * date-format: yyyy-MM-dd HH:mm:ss * time-zone: GMT+8 * * -Long类型转为字符串: * map.put(Long.class, ToStringSerializer.instance); * 解决Long类型数据返回到前端精度丢失问题 */ @Configuration public class JacksonSerializerConfig { @Value("${spring.jackson.date-format}") private String pattern; @Bean public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { Map<Class<?

ThreadLocal使用注意:线程不安全,可能会发生内存泄漏

先说可能会发生内存泄漏: 前言 ThreadLocal 的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度。但是如果滥用ThreadLocal,就可能会导致内存泄漏。下面,我们将围绕三个方面来分析ThreadLocal 内存泄漏的问题 ThreadLocal 实现原理ThreadLocal为什么会内存泄漏ThreadLocal 最佳实践 ThreadLocal 实现原理 ThreadLocal的实现是这样的:每个Thread 维护一个 ThreadLocalMap 映射表,这个映射表的 key 是 ThreadLocal实例本身,value 是真正需要存储的 Object。 也就是说 ThreadLocal 本身并不存储值,它只是作为一个 key 来让线程从 ThreadLocalMap 获取 value。值得注意的是 ThreadLocalMap 是使用 ThreadLocal 的弱引用作为 Key 的,弱引用的对象在 GC 时会被回收。 ThreadLocal为什么会内存泄漏 ThreadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal没有外部强引用来引用它,那么系统 GC 的时候,这个ThreadLocal势必会被回收,这样一来,ThreadLocalMap中就会出现key为null的Entry,就没有办法访问这些key为null的Entry的value,如果当前线程再迟迟不结束的话,这些key为null的Entry的value就会一直存在一条强引用链:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value永远无法回收,造成内存泄漏。 其实,ThreadLocalMap的设计中已经考虑到这种情况,也加上了一些防护措施:在ThreadLocal的get(),set(),remove()的时候都会清除线程ThreadLocalMap里所有key为null的value。 但是这些被动的预防措施并不能保证不会内存泄漏: 使用static的ThreadLocal,延长了ThreadLocal的生命周期,可能导致的内存泄漏(参考ThreadLocal 内存泄露的实例分析)。分配使用了ThreadLocal又不再调用get(),set(),remove()方法,那么就会导致内存泄漏。 首先区分强 软 若 虚引用: 强引用:任何时候都不会被回收,即使报了OOM错误。清除方法需要手动将对象置null,如调用List的clear方法等 软引用:soft,内存不够时,为了避免oom问题,会回收软引用对应的对象。 弱引用:weak,无论内存是否足够,只要发生了垃圾回收,就会进行回收 虚引用:phantom,任意时候都会被回收 引用类型转化方式: String str=new String("abc"); // 强引用 // 软引用 ,注意此时str还是强引用,softRef被垃圾回收时,但是 str还在内存中

iOS开发 webview禁止视频全屏播放

有时候在webview里面并不希望视频能够全屏播放,于是最好的办法是隐藏全屏播放的按钮 - (void)webViewDidFinishLoad:(UIWebView *)webView{ if (webView&&[webView isKindOfClass:[UIWebView class]]) { [webView stringByEvaluatingJavaScriptFromString: @"document.getElementsByClassName('vjs-fullscreen-control')[0].style.display = \"none\"" ]; } }

hive和mysql(传统数据库)的区别

1.查询语言不同:hive是hql语言,mysql是sql语句; 2.数据存储位置不同:hive是把数据存储在hdfs上,而mysql数据是存储在自己的系统中; 3.数据格式:hive数据格式可以用户自定义,mysql有自己的系统定义格式; 4.数据更新:hive不支持数据更新,只可以读,不可以写,而sql支持数据更新; 5.索引:hive没有索引,因此查询数据的时候是通过mapreduce很暴力的把数据都查询一遍,也造成了hive查询数据速度很慢的原因,而mysql有索引; 6.延迟性:hive延迟性高,原因就是上边一点所说的,而mysql延迟性低; 7.数据规模:hive存储的数据量超级大,而mysql只是存储一些少量的业务数据; 8.底层执行原理:hive底层是用的mapreduce,而mysql是excutor执行器;

Spring配置过程出现的错误

配置<construtor-arg>时需在<beans>标签加上 xmlns:p="http://www.springframework.org/schema/p 配置<tx:advice>时 需在<beans>标签加上xmlns:tx="http://www.springframework.org/schema/tx" 和xsi:schemaLocation加上http://www.springframework.org/schema/t http://www.springframework.org/schema/tx/spring-tx.xsd 配置<aop:aspectj-autoproxy /> 需在<beans>标签加上xmlns:aop="http://www.springframework.org/schema/aop" 和xsi:schemaLocation加上http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"

Redis 有序集合(sorted set)实现消息重试

先了解Redis 有序集合(sorted set)** Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。 不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。 有序集合的成员是唯一的,但分数(score)却可以重复。 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。 常用Redis sorted_set 命令: http://doc.redisfans.com/sorted_set/index.html 实现简要消息重试 实现思路: 消息重试要考虑消息发送的优先级,高优先级的需要先进先出,但是实际情况发送消息消息发送时候优先级是不均匀的,有的时候会一大波峰消息过来,如果某一段时间高优先级消息一直在发送,那么早发送的低优先级的消息一直无法发送,导致实际情况是一直在发高优先级的,低优先级的一直在积压。 这里通过流程讲解一下通过Redis 有序集合(sorted set) 来解决这个问题,score存入消息优先级1-5,优先级为5的在指定区间范围内优先发送,具体解决思路如下: 1、对重试数据进行拆分 A sorted set和 B sorted set,按照优先级存入sorted set A或 B 2、设置状态机器来记录A sorted set和 B sorted set的读写状态,进而识别是写入A还是B 3、当读取A为空的时候 且 B 也为空的情况下,休眠指定时间(可配置,例如5分钟),这个时候读队列进行休眠,写入数据通过状态机器识别写入B 4、5分钟休眠(可配置,例如5分钟)完成后状态机切换到A写,B读取,如果队列都为空则继续休眠5分钟(可配置,例如5分钟),则等待数据写入A 5、第4、5步 逻辑通过状态机器进行反复切换,可以达到在指定时间范围内数据高优先级读取 GetRangeFromSortedSetDesc 6、同时考虑到数据量太大情况,每天消息写入量设置最大限额2000万,超量不写入队列 7、考虑到sorted set读取并发问题,每个队列写入的时候进行sharding 拆分到较小的key中,例如WaitSend1-10个管道、 每个管道都分A、B读写队列,例如:如WaitSend1A、如WaitSend1B 、如WaitSend2A、如WaitSend2B等,通过job对每个管道进行消费,逻辑实现中自动识别读取A、B队列 实现流程 状态机为0 的情况Sort Set A写入,B读取,B读取时候跟进条件设置状态机状态值,达到切换队列切换效果。如果写队列和读取队列同时为空的情况下休眠指定时间, 到达指定休眠时间到到后自动切换状态机状态,否则直接切换状态机。 状态机为1 的情况Sort Set B写入,A读取,A读取时候跟进条件设置状态机状态值,达到切换队列切换效果。如果写队列和读取队列同时为空的情况下休眠指定时间, 到达指定休眠时间到到后自动切换状态机状态,否则直接切换状态机。 验证状态机状态,状态机=0 A写入 B读取,反之 A读取、B写入,状态机切换时候验证A、B是否都为空进行休眠操作,否则则直接读取队列中数据

spring在web.xml中的配置

把如下代码添加到web.xml即可完成spring的基本配置 把如下代码添加到web.xml即可完成spring的基本配置 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd" version = "3.1"> <!-- 配置过滤器 --> <filter> <filter-name>SetCharacterEncoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>SetCharacterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 指定spring配置文件位置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> <!-- 加载多个spring配置文件 --> /WEB-INF/applicationContext.xml, /WEB-INF/action-servlet.xml </param-value> </context-param> <!-- 定义SPRING监听器,加载spring --> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener> </web-app>

ubuntu使用qtcretor查看qt源码

一:测试环境 qtcretor:2.7.1 qt:4.8.3 ubuntu:14.04 qt库安装路径:/usr/local/Trolltech/Qt-4.8.3/ qt源码下载路径:http://download.qt.io/archive/qt/4.8/4.8.3/ qt下载源码解压路径:/home/yangtq/qtSet/qtCode/qt-everywhere-opensource-src-4.8.3 二:引入环节 (1):因为windows下安装qt库时是安装了源码的,以windows查找源码为例: 我们随便建立一个工程,然后再查看#include<QApplication>的绝对路径,如我的是在 (2)然后进入此路径查看相关 QApplication的内容为:#include "qapplication.h" qapplication.h的内容为:#include "../../src/gui/kernel/qapplication.h" 然后顺藤摸瓜找到src/gui/kernel/qapplication.h,此目录下还包含了qapplication.cpp 所以使用qtcretor快捷键能找到源码。因为头文件和源文件在同一级目录下 三:ubuntu查找源码 (1)我们随便建一个工程,如上面一样查看QApplication在ubuntu下的绝对路径如我的是在 (2)然后进入/usr/local/Trolltech/Qt-4.8.3/include/QtGui/ QApplication的内容为:#include "qapplication.h" qapplication.h的内容为:函数声明,所以问题就出在这里了。这是跟windows不一样的地方。我们只要映射成windows一样就可以了。 (3)下载源码,然后我们在源码解压路径在相同目录下查看各个文件的内容如我的(/home/yangtq/qtSet/qtCode/qt-everywhere-opensource-src-4.8.3/include/QtGui) QApplication的内容为:#include "qapplication.h" qapplication.h的内容为:#include "../../src/gui/kernel/qapplication.h" 这种目录的结构就跟在windows下看到的一摸一样到这里我们就成功了一半,接下来只要把qt的include映射到源码的include中就完成了。 四:映射源码include路径(上面都可以不看这个是关键) (1)这里我们要使用qt.conf文件来达到 目的.关于qt.conf的说明文档可以在qt帮助文档->索引->qt.conf查看 (2)首先我们到qt库安装路径中找到qmake。我的是在:/usr/local/Trolltech/Qt-4.8.3/bin/qmake 执行 ./qmake -query查看相关内容,建议拍照保存,与下一步对照如我的 (3)我们目的是要改变QT_INSTALL_HEADERS的值而它可以通过qt.conf改变,我们在qmake的同一级目录建一个 qt.conf,并往里面填入此内容 [Paths] Prefix=/usr/local/Trolltech/Qt-4.8.3/ //(qt库的安装路径) Headers=/home/yangtq/qtSet/qtCode/qt-everywhere-opensource-src-4.8.3/include //(qt源码include绝对路径) 上图是我的。然后 我们执行./qmake -query查看内容,除了QT_INSTALL_HEADERS是我们自己设置的其它的都应该跟之前一样 这是有qt.conf的查询结果 (4)验证我们的设置。重启qtcretor,然后在查看#include<QApplication>的路径是否改变以及是否可以跳转源码,最后编译运行 最终效果图,然后在进入,F4进入app文件,成功 如果此方法验证不行。大方向只要保证你载入的头文件和源文件在同一级目录就能切换到源码文件

生活感悟(转)

朋友圈看到的一段话,感觉写的很好,记录一下: 请你一定看二次,著名的清华大学教授王洪亮的一段话!好经典! 人静时,躺下来仔细想想,人活着真不容易,明知以后会死,还要努力的活着,人活一辈子到底是为什么?复杂的社会,看不透的人心,放不下的牵挂,经历不完的酸甜苦辣,走不完的坎坷,越不过的无奈,忘不了的昨天,忙不完的今天,想不到的明天,最后不知道会消失在哪一天,这就是人生。所以再忙再累别忘了心疼自己,一定要记得好好照顾自己!人生如天气,可预料,但往往出乎意料。不管是阳光灿烂,还是聚散无常,一份好心情,是人生唯一不能被剥夺的财富。把握好每天的生活,照顾好独一无二的身体,就是最好的珍惜。得之坦然,失之泰然,随性而往,随遇而安,一切随缘,是最豁达而明智的人生态度。多好的一段话: 我们都有缺点,所以彼此包容一点。我们都有优点,所以彼此欣赏一点。我们都有个性,所以彼此谦让一点。我们都有差异,所以彼此接纳一点。我们都有伤心,所以彼此安慰一点。我们都有快乐,所以彼此分享一点。因为我们有缘相识,请珍惜生命中的每一位家人、朋友!开心的过好每一天! 十年后,您把现在的奔驰宝马给孩子,他们会说太旧了! 十年后,您把现在的苹果9s给孩子,他们会说别逗了! 十年后,你躺在病床上抱着一堆存折,要儿女天天给你端屎端尿,儿女们会说,雇保姆吧! 十年后,你保持了健康的体魄,还能到处旅游,打拳、跳舞。您的孩子会说,老爸老妈你们太明智了! 给孩子最好的礼物是自己的健康! 重要的事情,再说一遍,请大家记住最后一句话:给孩子最好的礼物是保养好自己的身心健康。 其实人生就是做好两件事:第一,教育好孩子,不要危害社会;第二是照顾好自己,别拖累孩子。 ‘再过若干年,我们都将离去,对这个世界来说,我们彻底变成了虚无。 ‘我们奋斗一生,带不走一草一木。我们执着一生,带不走一分虚荣爱慕。 今生,无论贵贱贫富,总有一天都要走到这最后一步。到了天国,蓦然回首,我们的这一生,形同虚度。 所以,从现在起,我们要用心生活,天天开心快乐就好。三千繁华,弹指刹那,百年之后,不过一捧黄沙。请善待每个人,因为没有下辈子。 一辈子真的好短,有多少人说好要过一辈子,可走着走着就剩下了曾经。又有多少人说好要做一辈子的朋友,可转身就成为最熟悉的陌生人。有的明明说好明天见,可醒来就是天各一方。 所以,趁我们都还活着,爱人、战友、同学、朋友、同事、能相聚就不要错过,能爱时就认真的爱,能拥抱时就拥入怀,能牵手时就不放开。 能玩的时候玩,能吃的时候吃。请好好珍惜身边的人,不要做翻脸比翻书还快的人。 互相理解才是真正的感情,不要给你的人生留下太多的遗憾。再好的缘份也经不起敷衍,再深的感情也需要珍惜。 没有绝对的傻瓜,只有愿为你 装傻的人。原谅你的人,是不愿失去你。真诚才能永相守,珍惜才配长拥有。 有利时,不要不让人;有理时,不要不饶人;有能时,不要嘲笑人。太精明遭人厌;太挑剔遭人嫌;太骄傲遭人弃。 人在世间走,本是一场空,何必处处计较,步步不让。话多了伤人,恨多了伤神,与其伤人又伤神,不如不烦神。 一辈子就图个无愧于心,悠然自在。世间的理争不完,争赢了失人心;世上的利赚不尽,差不多就行。财聚人散,财散人聚。 心幸福,日子才轻松;人自在,一生才值得!想的太多,容易烦恼;在乎太多,容易困扰;追求太多,容易累倒。 好好珍惜身边的人,因为没有下辈子的相识 ! 好好感受生活的乐,因为转瞬就即逝 ! 好好体会生命的每一天,因为只有今生,没有来世。 献给家人,老师,同学,同事、战友、好朋友,好弟兄,好姐妹,以及爱我的和我爱的人。 读过的,若能再读一次,没准让你自己体会人生真谛。

利用Redis锁解决并发问题

用redis处理高并发是个很常见的方式,因为redis的访问效率很高(直接访问内存),一般我们会用来处理网站一瞬间的并发量。 那如果要使用redis来进行高并发问题的解决的话,应注意以下几点: 1、首先我们要先知道,我们在存储时,应使用redis的setnx方法,不应该使用set方法,因为setnx拥有原子操作命令(正确点说法应该是使用setnx,根据其属性可以保证共享资源的原子性操作),当资源锁存在不能设置值,则返回0,而当锁不存在,则设置锁,返回1; 但如果使用set方法,则会出现在高并发情况下,进程同时获取锁状态为null,同时设置,锁之间相互覆盖,但是俩进程仍在并发执行业务代码的情况。 2、为了防止死锁,我们不应直接使用jedis.setnx(lock, 1) 来进行简单的加锁,这样会导致当进程执行出现问题,锁未释放,则其他进程永远处于阻塞状态,出现死锁。 为了避免死锁,我们在加锁时带上时间戳,setnx(lock, 时间戳+超时时间),当发现锁超时了,便可以对锁进行重置,避免死锁。 接下来,实际操作! 设置锁: //其中currentTimeMullis为当前时间、valideTime为超时时间,key为资源 //对该资源进行锁获取,如果存在锁则会返回false,不存在则设置值并返回true boolean lock = redisService.setnx(key, currentTimeMullis+valideTime); //如果不存在并设置了值,则可以直接返回,因为已经获取资源锁成功 //否则,则代表存在这个锁,则进行锁是否超时的判断。获取该资源的锁时间,用于判断是否超时了 String keyTime = redisService.get(key); if((Long.valueOf(currentTimeMullis)-Long.valueOf(keyTime))>valideTime){ //该判断代表该资源锁已经超时,那么便进行资源锁的重置,也就是进行资源锁的重新设置(删除并重新设置) //重新设置成功后也返回,因为获取锁成功,可以进行操作啦。 } //如果以上操作都没有成功,则返回失败,代表获取锁失败,不可以进行操作。 释放锁: 当对资源处理结束后,则调用释放方法释放锁资源 (经提醒,我发现我这里少了个判断逻辑…) //在删除前,应该先对该资源锁进行获取,判断值与此时释放锁的线程所携带的值是否相等,也就是我们上面创建时用的currentTimeMullis+valideTime。 String keyLockTime = redisService.get(key); if(keyLockTime!=null&&keyLockTime.equals(currentTimeMullis+valideTime)){ //此时锁还由当前线程保持则释放锁 redisService.del(key); }else{ //此时说明该资源锁被其他线程重置或释放,已不再拥有锁的释放权 //结束 }

web-app标签

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd" version = "3.1"></web-app>

c#EntityFormwork框架工具类

using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Web; using System.Linq.Expressions; namespace CompanyWeb.Content.Tools { /// <summary> /// Entity FrameWork帮助类(提供各种对数据的操作方法) /// </summary> /// <typeparam name="TDbContext"></typeparam> public class EFTools<TDbContext> where TDbContext : DbContext, new() { /// <summary> /// 获取所有的实体 zhaolin /// </summary> /// <typeparam name="T"> 泛型实体类型 在调用前必须制定 且只能为引用类型</typeparam> /// <returns>结果集</returns> public List<T> GetAllEntity<T>() where T : class { try { using (TDbContext db = new TDbContext()) { return db.Set<T>().ToList(); } } catch (Exception ex) { Console.

@Aspect创建简单切面

1.首先,要使用@Aspect注解需要引入依赖 <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.0</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.9.0</version> </dependency> 2.开启自动自动代理功能 2.1创建切面 import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Component @Aspect public class MyAspect { @Pointcut("execution(* com.example.demo.TestController.getMessage(..))") public void perform(){ } @Before("perform()") public void beforeRun(){ System.out.println("before do it"); } } package com; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration //自动代理启用 @EnableAspectJAutoProxy public class Config { @Bean public MyAspect aspect(){ return new MyAspect(); } } 在执行com.example.demo.TestController.getMessage()方法之前都会先调用beforeRun方法。 

mysql - navicat介绍

mysql - navicat 介绍 20世纪90年代诞生于瑞典 2008年被SUN收购 2009年SUN被ORICAL收购 官网 安装目录及配置 windows: my.inimac: my.conf 配置参数 # 以下选项会被MySQL客户端应用读取。 # 注意只有MySQL附带的客户端应用程序保证可以读取这段内容。 # 如果你想你自己的MySQL应用程序获取这些值。 # 需要在MySQL客户端库初始化的时候指定这些选项。 [client] port = 3306 socket = /usr/local/mysql/mysql.sock # MySQL 服务端 [mysqld] #默认存储引擎INNODB default-storage-engine=INNODB #GROUP_CONCAT长度 group_concat_max_len =99999 #端口号 port = 3306 #socket位置 socket = /usr/local/mysql/mysql.sock #pid写入文件位置 pid-file = /usr/local/mysql/mysqld.pid #数据库文件位置 datadir = /home/data/mysql/data user = mysql #SQL模式具体查阅相关资料 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES #当外部锁定(external-locking)起作用时,每个进程若要访问数据表, #则必须等待之前的进程完成操作并解除锁定。由于服务器访问数据表时经常需要等待解锁, #因此在单服务器环境下external locking会让MySQL性能下降。 #所以在很多Linux发行版的源中,MySQL配置文件中默认使用了skip-external-locking来避免external locking。 skip-external-locking #跳过DNS反向解析 skip-name-resolve #关闭TIMESTAMP类型默认值 explicit_defaults_for_timestamp Mysql命令行模式

基于Redis简易缓存对象存储设计

项目中性能需要使用redis做数据缓存,主要是存储业务必须对象,为了提高性能就简要设计了下简易缓存,通过过期时间特性来及时更新缓存数据。具体实现思路如下图Redis存储在内存,读取性能好,但是不能存放太大数据,单个key数据太大,在大流量高并发情况下会打爆网卡,使用redis缓存时候数据量较大一定要谨慎。我抽空简单整理了下实现流程和思路,希望对刚入门学习者有帮助,不到之处勿喷。 Redis 优势 Redis是key-value存储非关系型数据库,数据存储在内存中,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 等; • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。 • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。 • 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。 • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。 本次实现使用到redis hash、string、ttl、过期设置等相关操作,封装到基类中方便重用; 这里通过流程建议说下当时考虑的流程和时间解决思路,BaseCahe代码可以根据自己理解去实现,主要实现是采用了抽象类和抽象方法进行实现,目的是为了使用方只需要写DB查询业务方法和简单参数设置,使用方无需关系内部getData的实现。 Redis缓存实现流程 内部代码实现思路 其中内部实现需要考虑的细节点以及解决办法: 1、redis读取失败的时候需要考虑需要做异常处理返回数据库数据 redis读写失败我是直接返回DB查询数据 2、读取对象时候如果读取DB方法返回数据为空是否要缓存到Redis中,是否需要使用方通过传入参数开关 返回数据为空一种是无数据,一种可能是异常返回,这种情况需要考虑是否要存储到缓存中。目前由于业务场景下未做自定义开关,而是通过设置相对较短的缓存时间过期后DB进行查询 3、缓存设置过期时间未成功如果处理 采用ttl方法对缓存时间进行验证,如果反响设置未成功通过重试方式进行补偿设置 4、缓存过大如何处理,是采用监控方式还是禁止写入到缓存当中 目前通过缓存写入的时候获取存入序列化后字符串字节数进行监控,跟进应用号配置对应提醒邮箱,提醒使用方进行优化 5、多应用缓存重复如何重用 正常情况下缓存前缀每个应用统一设置,但是可以通过设置参数对象可设置自定义缓存前缀,方便多应用缓存重用 6、缓存方法实现请求参数不一致如何解决 目前采用Object[] params来实现,后期可通过泛型来进行参数传入 7、对象存储目前支持常用类型 HashMap、Map、List、Class对象,对象采用fastjson序列化后存储,同时采用hash可以支持多个field存储和获取 使用代码示例 方便理解这里贴一下使用代码DEMO,最外层只调用getData即可; /** * 数据对象缓存实现示例 */ @Component public class SaleUserCache extends BaseCache<SaleUserInfo> { /** * 数据库数据查询时间 * * @param params 查询参数 * @return 缓存输出对象 * @throws CacheException 缓存内部抛出异常 */ @Override protected SaleUserInfo getExternalData(Object[] params) throws CacheException { return null; } /** * hash缓存key * * @param params 查询参数,可以支持动态key参数使用 * @return 缓存key */ @Override protected String cacheKey(Object[] params) { return "

Gin 框架的路由结构浅析

Gin 是 go 语言的一款轻量级框架,风格简单朴素,支持中间件,动态路由等功能。 gin项目github地址 路由是web框架的核心功能。在没有读过 gin 的代码之前,在我眼里的路由实现是这样的:根据路由里的 / 把路由切分成多个字符串数组,然后按照相同的前子数组把路由构造成树的结构;寻址时,先把请求的 url 按照 / 切分,然后遍历树进行寻址。 比如:定义了两个路由 /user/get,/user/delete,则会构造出拥有三个节点的路由树,根节点是 user,两个子节点分别是 get delete。 上述是一种实现路由树的方式,且比较直观,容易理解。对 url 进行切分、比较,时间复杂度是 O(2n)。 Gin的路由实现使用了类似前缀树的数据结构,只需遍历一遍字符串即可,时间复杂度为O(n)。 当然,对于一次 http 请求来说,这点路由寻址优化可以忽略不计。 Engine Gin 的 Engine 结构体内嵌了 RouterGroup 结构体,定义了 GET,POST 等路由注册方法。 Engine 中的 trees 字段定义了路由逻辑。trees 是 methodTrees 类型(其实就是 []methodTree),trees 是一个数组,不同请求方法的路由在不同的树(methodTree)中。 最后,methodTree 中的 root 字段(*node类型)是路由树的根节点。树的构造与寻址都是在 *node的方法中完成的。 UML 结构图 trees 是个数组,数组里会有不同请求方法的路由树。 node node 结构体定义如下 type node struct { path string // 当前节点相对路径(与祖先节点的 path 拼接可得到完整路径) indices string // 所以孩子节点的path[0]组成的字符串 children []*node // 孩子节点 handlers HandlersChain // 当前节点的处理函数(包括中间件) priority uint32 // 当前节点及子孙节点的实际路由数量 nType nodeType // 节点类型 maxParams uint8 // 子孙节点的最大参数数量 wildChild bool // 孩子节点是否有通配符(wildcard) } path 和 indices 关于 path 和 indices,其实是使用了前缀树的逻辑。

Linux之终端信息输出到日志文件

在做调试的时候,需要观察终端输出的内容,有时候终端输出太多会被覆盖掉,并且直接在终端观察不太方便。将终端输出的内容保存在日志文件中,一方面可以便于查看输出内容,另一方面可以永久保存,便于回看。因此本文对相关的方法进行整理总结。 方法一 把命令运行的结果保存到文件当中:用 > 把输出转向就可以了,如 $ ls > ls.txt #或者 ls-->ls.txt #把ls命令的运行结果保存到文件ls.txt中 说明: > 是把输出转向到指定的文件,如文件已存在的话也会重新写入,文件原内容不会保留 >> 是把输出附向到文件的后面,文件原内容会保留下来 方法二 上面的方法在写入文件的时候,终端没有任何输出,如果想要同时在终端显示,需要用tee指令 $ ls | tee ls.txt #将会在终端上显示ls命令的执行结果,并把执行结果输出到ls.txt 文件中 $ ls | tee -a ls.txt #保留ls.txt文件中原来的内容,并把ls命令的执行结果添加到ls.txt文件的后面 方法三 上面的方法是写一句指令的输出,如果需要运行多条指令,还用同样的方法,就会比较麻烦,这个时候就用到了script指令 $ script #Script. started, file is typescript $ ls #…… 内容省略 $ exit #exit #Script. done, file is typescript 我们在启动script时没有指定文件名,它会自动记录到当前目录下一个名为 typescript的文件中。也可以用 -a参数指定文件名,比如 $script. -a example.txt #终端的输出内容被记录到 example.txt这个文件中 退出script时,用exit,事实上script就是启动了一个shell

在最新Spring官网下载jar包

Spring官网改版后,想要去下载相应的jar包却发现无从下手,不知道在哪里下载,链接都被‘隐秘’起来了,今天我跟大家说说,如何在2018的Spring官网下载所需的jar包, 首先,百度Spring 或者通过网站https://spring.io/进入官网,点击PROJECTS 接着 进入SPRING FRAMEWORK 接着点击小猫 进入到github界面,往下面拉,在Access to Binaries,点击 Spring Framework Artifacts 进去之后,拉到最后面,在Downloading a Distribution下面点击http://repo.spring.io. 进去之后,在Most Downloaded Artifacts中找到 ibs-release-local/org/springframework/spring-beans/maven-metadata.xml 点击进去 接着在ibs-release-local下拉中找到springframework下拉中找到Spring ,接着你就可以选择你需要的版本去下载了 喜欢的话记得点关注哦!!!

HttpRunner使用中的一些问题记录

背景:在了解接口自动化框架的过程中,看到有介绍说HttpRunner是一款不错的开源框架。所以,简单试用了一下。虽然有中文使用手册的帮助,但在结合自己项目接口的使用中还是遇到一些问题。在解决这些问题之后,也对这一框架的使用有了更深的了解。 环境:Python3.6 + HttpRunner1.5.13 + har2case 0.1.10 问题: 1. 录制脚本时,保存成 HAR 格式的文件。 1)使用Fiddler4抓包,并接口的请求和响应结果保存为 .har 格式的文件。选中接口,然后点击 Decode。 2)选择菜单栏中,File-》Export Sessions-》Selected Sessions,选择HTTPArchive v1.1类型。 3)保存文件类型如图所示。 2. 文件格式的转换。 上述步骤中保存的.har文件,需要转换成yaml或json文件。在文件所在目录,使用cmd,执行命令: har2case xx.har xx.json 3. 认识JSON文件。引用中文手册中的例子 [ { "config": { "name": "testset description", "variables": [], "request": { "base_url": "", "headers": { "User-Agent": "python-requests/2.18.4" } } } }, { "test": { "name": "/api/get-token", "request": { "url": "http://127.0.0.1:5000/api/get-token", "headers": { "device_sn": "FwgRiO7CNA50DSU", "user_agent": "iOS/10.3", "os_platform": "ios", "app_version": "2.8.6", "