# 查看物理CPU个数:主板上实际插入的cpu数量,可以数不重复的 physical id 有几个(physical id)
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
或grep 'physical id' /proc/cpuinfo | sort -u | wc -l
# 查看每个物理CPU中core的个数(即核数):单块CPU上面能处理数据的芯片组的数量,如双核、四核等 (cpu cores)
cat /proc/cpuinfo| grep "cpu cores"| uniq
或者grep 'core id' /proc/cpuinfo | sort -u | wc -l
# 查看逻辑CPU的个数:简单来说,它可使处理器中的1颗内核,如2颗内核那样在操作系统中发挥作用。
#所有:逻辑cpu的个数=物理cpu个数*cpu的核数*2
cat /proc/cpuinfo| grep "processor"| wc -l
或者grep 'processor' /proc/cpuinfo | sort -u | wc -l
# 查看CPU信息(型号)
cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
import android.os.Bundle; import android.util.DisplayMetrics; import android.view.View; import android.view.LayoutInflater; import android.widget.ImageView; import android.widget.TextView; import com.example.myapplication.adapter.MainFragmentAdapter; /** * @author:created By ZhangHao * 时间:2019/4/23 20:45 * 邮箱:188660586@qq.com * 当前文件:MainActivity */ //主框架 public class MainActivity extends AppCompatActivity { private final int[] TAB_TITLES = new int[]{ R.string.menu_msg, R.string.menu_history, R.string.menu_mine }; private final int[] TAB_IMGS = new int[]{ R.drawable.tab_main_msg, R.drawable.tab_main_history, R.drawable.tab_main_mine }; @BindView(R.id.view_pager) ViewPager viewPager; @BindView(R.id.tab_layout) TabLayout tabLayout; private PagerAdapter pagerAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.
微信小程序开发过程中,有一个奇葩的事情,要为视频添加关键帧,找了很多方法,只发现一个亲测有效的方法.
每5秒强制插入一个关键帧,你可以使用:
ffmpeg -i 原视频 -force_key_frames expr:gte(t,n_forced*5) 生成的新的视频 ;
下面可以将添加的关键帧以图片的形式展现 :
ffmpeg -i 添加帧视频 -vf select='eq(pict_type\,I)' -vsync 2 -s 1920*1080 -f image2 core-%02d.jpeg
一些说明:
这几个都可以正常发邮件,但是免费的每天都会有限制,发多了就会黑名单。。。
最终选择了exchange付费的版本,每天可以发1万条邮件,也不是很贵,基础的32一个月的就可以了
import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeUtility; import com.sun.mail.smtp.SMTPTransport; import microsoft.exchange.webservices.data.core.ExchangeService; import microsoft.exchange.webservices.data.core.enumeration.misc.ExchangeVersion; import microsoft.exchange.webservices.data.core.enumeration.property.BodyType; import microsoft.exchange.webservices.data.core.service.item.EmailMessage; import microsoft.exchange.webservices.data.credential.ExchangeCredentials; import microsoft.exchange.webservices.data.credential.WebCredentials; import microsoft.exchange.webservices.data.property.complex.MessageBody; import javax.mail.Session; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.util.Date; import java.util.Properties; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Transport; public class SendHtmlMail { public static void main(String[] args) { String to = "******@gmail.com"; StringBuffer theMessage = new StringBuffer(); theMessage.append("<!DOCTYPE html><html lang='en'><head><meta charset='UTF-8'><title>Title</title></head><body>测试一哈</body></html>"); sendMessageByExchange("***","***","Test",to,theMessage.toString()); } //Exchange服务发送 public static int sendMessageByExchange(String username, String password,String subject, String to,String bodyText){ ExchangeService service = new ExchangeService(ExchangeVersion.
一、分析目的
通过分析2B产品中的团队协作管理软件的对比分析,用于为公司团队协作软件的选型做产考。
二、竞品归属市场概况
2.1.目标用户群及需求
主要面向企业用户,用于解决企业不同地域以及不同职能部门之间的团队协作难点。
2.2.市场规模
中国大概有4000万+企业,如采用人均年费制,均价200+/人/年,按平均一个企业或团队最少10人算,市场规模可在千亿左右。因此如果能培养行业使用习惯,市场价值可观。
2.3.针对笔者所在团队的需求详细分析如下:
1、需求管理;能够对需求池进行管理。
2、迭代管理;能够对产品迭代版本进行管理。
3、故事墙;能够查看所有工作任务的状态。
4、缺陷管理;能够对开发中的缺陷进行管理。
5、数据看板;能够查看团队中每个员工的工作动态(剩余工作量),数据看板。
6、知识库管理;能够将项目开发过程中有价值的文档和经验就行汇总;
7、在线分享和讨论;类似于wiki或者BBS功能,作为知识库的一部分,团队人员可以进行知识分享和在线问答等,从而让整个团队能够更加活跃。
8、能够打通企业常用的沟通协作平台。如:钉钉,企业微信,QQ等。
三、竞品选型
基于以上需求,从平台对接(钉钉,企业微信),稳定性,功能符合度,选着teambition和CORNERSTONE进行分析。
产品 可对接平台 稳定性 功能符合度
teambition 钉钉 高 高
CORNERSTONE 企业微信 高 高
总结:从竞品选择来看, Teambition和CORNERSTON的稳定性与功能符合度来看都是比较满足笔者团队需求,由于笔者团队使用企业微信作为OA平台,所以从对接平台来看使用CORNERSTONE会更加方便。
四、竞品定位
[Teambition]:
1.简介:可以把一切计划落实到位。使得团队以全新方式规划管理工作项目,成员执行更到位,而且完成过程也十分轻松。
2013年发布,并于2014年入选中国最具投资价值企业50强,2019年被阿里全资收购。
2.slogan:让团队协作焕然一新。
[CORNERSTONE]:
1.简介:产品定位是解决企业研发痛点,支持持续交付与集成,透过各个维度跟踪记录项目进度。除了一些对比Teambition更简洁更智能化的操作外,里面还有自带的DevOps自动打包工具。通过这个平台,用户可以不借助任何第三方工具完成产品、开发、测试、运维等所有角色的工作流程并记录下来,形成智能化的工作报表。
2.slogan:CORNERSTON新一代智能项目管理平台。
总结:
总体定位差不多,只不过Teambition偏向项目协作,CORNERSTONE更偏敏捷开发的项目管理系统。
五、竞品商业模式对比
[Teambition]
采用人均年费制。
10人以下免费(人数太少对于大项目免费版基本就不可用了),10人以上可选299和699/人/年版本,也就是10人以上,一年大概3000~7000左右,总体上略贵。后面分析各版本的不同。
Teambition价格
[CORNERSTONE]
目前分为永久免费云平台版与私有化部署CORNERSTONE高级版。
云平台版可以管理项目任务,无法进行敏捷迭代管理。电话咨询过费用,较Teambition便宜,可以一次性买断型,更适合大企业使用。
CORNERSTONE价格
总结:
从价格来CORNERSTONE价格更有优势,但是大家可以根据自己团队人数与属性来选择合适自己的产品。
六、竞品市场规模
[Teambition]
目前,已经有超过一百万用户通过Teambition进行团队协作,其中也包括多个行业的龙头企业。包含小米等公司。其实说白了,和钉钉的用户群有很大关系,钉钉总装机量已近达到了接近3000万台。目前Teambition已经完美打通,未来用户规模将持续上升。
Teambition
[CORNERSTONE]
CORNERSTONE没有单独的app,手机端主要是以集成在企业微信与微信服务号的方式存在。
总结:
CORNERSTONE作为新出品的产品,未来还有很长的路要走。
七、竞品运营模式对比
[Teambition]
目前Teambation主要依靠钉钉庞大的用户群,以内部可选插件的方式使用,并非内部固定应用。当然Teambation也可单独下载app以及在pc端使用。
钉钉
[CORNERSTONE]
CORNERSTONE也类似,可单独pc和服务号使用,也可集成在企业微信中使用。
企业微信
八、体验对比
在我们写代码的时候,或者是使用电脑的时候,会遇到ctrl+c不能复制的情况。这个时候,我们就会很懵逼,且无从下手。更何况对于程序员来说,更是天大的恶心,大家都懂得。
那么我们应该怎么解决这个问题呢?我们废话不多说,直接说问题解决的办法即可。
第一步也差不多最后一步,我们只需要重启电脑就ok了。 开机后,我们再次使用ctrl+c,发现就可以使用了,是不是很神奇呢? 如果大家有其他的解决办法,大家可以及时发表意见,我会虚心接受,谢谢!
这辈子坚持与不坚持都不可怕,怕的是一直走在独自思考的路上!!!
今天调试的CUDA程序除了点问题,第一步先要增大TDR的值。
在该值的过程中,我遇到了这个说我没有权限的问题:
但是目前我的账户就是唯一的系统管理员账号,因此猜测是可以用 管理员身份运行来解决。
解决办法: 1.若此时已经打开了Nsight monitor,先退出Nsight monitor.。(这儿很重要,我因为没退出源程序墨迹了半天)。
2。找到源程序的位置(我用的everything),用以管理员身份运行,就可以修改了。
3.重启计算机,修改效果生效。
一、目前网上常用的解决方案
//将ajax封装起来启用一个定时器达到三秒抓一次数据 window.function(){ setInterval(ajaxNew(),3000); } 存在的问题是,首次加载缓慢,用户体验性差,数据加载不友好。
二、升级定时刷新方案
// 执行异步请求 var salesinterval; getsales(); clearInterval(salesinterval); //自动刷新; salesinterval = setInterval(function () { getsales() }, 6 * 1000); 首次下载页面即加载数据,然后再定义自动刷新时间;
三、淘汰的方案
在ajax获取数据后,定时刷新页面。虽然数据可以刷新,但是是整体数据的刷新,并非单列数据的更新,会出现“闪屏”
//定时更新数据,会出现刷屏,而不是单列数据的自动更新 setInterval(function () { window.location.reload() }, 6 * 1000); 漏刻有时(LOCKDATA),数据可视化大屏,挖掘大数据背后的价值。
在头文件定义了一个BOOL类型的数组
BOOL m_blike[4];
在代码中,发现这几个值一直为true。
调试发现,这几个值都是 -842150451,所以才会一直为true,因为C++中非0即为true
使用了未初始化的单元,没有去做初始化,在构造函数中用下面的代码就好了。
memset(m_blike, 0, sizeof(m_blike));
data <- data[complete.cases(data[,5:6]),]#删除第五六列有空值的行
data <- na.omit(data)#删除有空值的行
转载于:https://www.cnblogs.com/shilo930/p/11057331.html
在项目中引用log4net.dll
1、在Models文件夹内,定义一个WebApiMonitorLog ,监控日志对象
/// <summary> /// 监控日志对象 /// </summary> public class WebApiMonitorLog { public string ControllerName { get; set; } public string ActionName { get; set; } public DateTime ExecuteStartTime { get; set; } public DateTime ExecuteEndTime { get; set; } /// <summary> /// 请求的Action 参数 /// </summary> public Dictionary<string, object> ActionParams { get; set; } /// <summary> /// Http请求头 /// </summary> public string HttpRequestHeaders { get; set; } /// <summary> /// 请求方式 /// </summary> public string HttpMethod { get; set; } /// <summary> /// 请求的IP地址 /// </summary> public string IP { get; set; } /// <summary> /// 获取监控指标日志 /// </summary> /// <param name="
(int *)a 将指针变量a强制转换为整型指针,说明a一般不是一个整型指针,也可以是个整型指针。
int *a 定义一个整型指针变量a。
——————
2019.06.19
22:30
先用电脑接光猫输入192.168.1.1,用户名:telecomadmin 密码:nE7jA%5mROS路由器设置
一、安装Git 1、Debian或Ubuntu Linux系统上安装Git
通过一条sudo apt-get install git就可以直接完成Git的安装,非常简单
2、在Mac OS X上安装Git 如果你正在使用Mac做开发,有两种安装Git的方法。
一是安装homebrew,然后通过homebrew安装Git,具体方法请参考homebrew的文档:http://brew.sh/。
第二种方法更简单,也是推荐的方法,就是直接从AppStore安装Xcode,Xcode集成了Git,不过默认没有安装,你需要运行Xcode,选择菜单“Xcode”->“Preferences”,在弹出窗口中找到“Downloads”,选择“Command Line Tools”,点“Install”就可以完成安装了。
Xcode是Apple官方IDE,功能非常强大,是开发Mac和iOS App的必选装备,而且是免费的!
3、在Windows上安装Git 在Windows上使用Git,可以从Git官网直接下载安装程序,(网速慢的同学请移步国内镜像),然后按默认选项安装即可。
安装完成后,在开始菜单里找到“Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明Git安装成功!
安装完成后,还需要最后一步设置,在命令行输入:空格不能省
$ git config --global user.name "Your Name" $ git config --global user.email "email@example.com" 设置完成后查看gitconfig设置
git config user.name
或者 git config --list
因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。
注意git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
二、自己本机项目上传到gitlab (虚拟机上Ubuntu为例) (建议将本地代码仓库放在虚拟机系统磁盘中,不要放在本地系统然后地址映射,速度很慢) 1.先在gitlab上建立项目 拷贝项目地址:
http://192.168.1.105/liaoliao/ttms1.0.git
2.在本地文件夹下,使用git bash 1).git init
2)git remote add origin http://192.168.1.105/liaoliao/ttms1.0.git (这个是刚创建的地址)
3)git add .
4)git commit -m “注释”
MySQL5.7.5后only_full_group_by成为sql_mode的默认选项之一,这可能导致一些sql语句失效。
比如在使用group by进行分组查询报错
1 查看自己的sql_mode配置: 在sql命令行中输入select @@sql_mode;这时我们能够看到自己的sql_mode配置,其中如果有ONLY_FULL_GROUP_BY,那它就是group by查询报错的罪魁祸首了 2 解决办法: 命令行打开mysql.cnf,默认路径为/etc/mysql/conf.d/mysql.cnf,如果找不到可以使用whereis进行查询
sudo vim /etc/mysql/conf.d/mysql.cnf 滚动到文件底部复制并粘贴
[mysqld] sql_mode = 'STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION' 保存退出重启mysql
sudo service mysql restart 为什么5.7.5版本之后默认设置ONLY_FULL_GROUP_BY限制呢?
对于上述的报错信息,我的理解是select字段里包含了没有被group by条件唯一确定的字段fields。
假如一个表内有多个国家,比如
namecountry张三魏国李四魏国王五蜀国霸道蜀国橘子蜀国蛋糕吴国 我们想要查询有多少国家,分别为…
可以
select country from 表名 group by country; 但是如果说我们这样
select name,country from 表名 group by country; 因为执行group_by语句实际上把同一组内多行纪录合并成一行,同一个国家name并不相同,搜索引擎不知道该返回哪一条,所以认为这样的sql是武断的(arbitrary).
解决办法就是上面的解决办法,但是还要提醒朋友们,若非必要还是不要去掉,出现错误最大可能是sql语句本身存在问题.
假设某系统按天记录日志文件,即每天一个日志文件。随着系统的运行,日志文件越来越多。
app.log app.log.2019-06-18 app.log.2019-06-17 app.log.2019-06-16 app.log.2019-06-15 app.log.2019-06-14 app.log.2019-06-13 app.log.2019-06-12 app.log.2019-06-11 app.log.2019-06-10 ... 如何定期清除过期的日志呢?比如,只需要保留最近7天的日志备份?
对于linux系统,实现起来很方便:一个删除脚本 + crontab就可实现这个目标
1. 创建自动清理日志的sheel脚本(假定log日志在目录/var/app下),autoCleanLog.sh
#!/bin/bash searchPath=/var/app cd ${searchPath} declare -i total=`ls app.log.* | wc -l` declare -i nums=$total-7 if [ "${nums}" -ge 1 ];then rm -rf `ls -tr app.log.* | head -${nums}` fi 2. 赋予脚本可执行权限
chmod +x autoCleanLog.sh 3.采用crontab创建定期任务
每天凌晨1点执行(假定清除脚本在目录/var/app下),编辑crontab,增加如下行:
00 01 * * * /var/app/autoCleanLog.sh 让改动的crontab立即生效
sudo /etc/init.d/cron restart 这样就大功告成,此脚本每天凌晨就会启动一次,自动删除7天前备份的log文件。
1.属性:ChartAreas 》Axes 》X / Y 》MajorGrid 》 LineWideth 设置为0
目录
android抓socket数据包,sokit-1.3
CommMonitor 串行端口监视精灵
友善串口调试助手
有需要可以私信,下载地址:https://download.csdn.net/download/qq_38998213/12610380
android抓socket数据包,sokit-1.3 1、服务器模式 用来监听本地端口,接收外部数据包,并且可以回复自定义数据 2、客户端模式 用来连接服务器,发送自定义数据包,并接收远程回复数据 3、转发器模式 用来监听本地端口,将接收到的数据包发送给指定的远程服务器,也可以在转发数据流中插入自定义数据向双发发送 4、支持发送ascii字符串数据,以及十六进制表示的原始字节,单次发送的字符数目没有限制 5、收到的数据会同时以这两种形式显示
CommMonitor 串行端口监视精灵 有需要可以私信,下载地址:https://download.csdn.net/download/qq_38998213/11248000
CommMonitor 串行端口监视精灵是用于RS232 / RS422 / RS485端口监控的专业强大的系统实用程序软件。CommMonitor监视显示,记录和分析系统中的所有串行端口活动。这是追踪应用程序或驱动程序开发,串行设备测试和优化等过程中可能出现的问题的理想方法。还提供过滤、搜索、数据导出和强大的数据拦截功能,可以将指定端口的数据流、控制流信息拦截并保存下来,供分析之用。如察看端口状态的变化(波特率、数据位、校验位、停止位),拦截上行、下行的数据,处理速度快,拦截效率高,并可以以十六进制、ASCII字符形式显示,全面支持Unicode 。
友善串口调试助手 有需要可以私信,下载地址:https://download.csdn.net/download/qq_38998213/11248378
是一个很好而小巧的串口调试助手,完美支持Win7等Windows操作系统。友善串口调试助手支持常用的50-256000bps波特率,能设置校验、数据位和停止位,能以ASCII码或十六进制接收或发送任何数据或字符(包括中文),可以任意设定自动发送周期,并能将接收数据保存成文本文件,能发送任意大小的文本文件。
友善串口调试助手功能介绍
1、友善串口调试助手支持自定义波特率,可支持各种非标准波特率;
2、串口自动设别,自动搜索串口;
3、接收数据可以进行十六进制和ASCII切换;
4、接收数据时,光标始终显示在最后一行或指定行;
5、可以以十六进制或ASCII格式,向指定串口发送数据;
6、定时发送数据;
7、友善串口调试助手自定义波特率,支持非标准波特率;
8、友善串口调试助手支持日志缓冲;
9、友善串口调试助手支持ASCII和Hex数据转换;
10、支持时间戳功能,可显示发送及接受时间。
友善串口调试助手安装步骤
1、首先在本站下载友善串口调试助手软件包,双击运行exe安装文件,选择简体中文语言,然后点击确定
2、进入许可协议界面,选择我接受协议,然后点击下一步
3、选择目标安装位置,可以默认安装到C盘或者点击浏览选择其他安装位置,然后点击下一步
4、选择开始菜单文件夹,无需修改,直接点击下一步
5、选择附加任务界面,选择创建桌面图标,然后点击下一步
6、准备安装友善串口调试助手,点击安装
7、正在安装,耐心等待安装进度条完成
8、友善串口调试助手安装完成,点击完成后就可以打开使用
友善串口调试助手使用方法
1、在本站下载安装好友善串口调试助手后,在桌面找到图标双击运行,主界面如下:
2、首先根据串口发过来的信息选择波特率,这个波特率根据实际需要选择,要保证收发一致,否则可能收不到数据,有的时候可以收到,但是都是乱码
3、根据传输协议,设置数据位,校验位,停止位,这三个也需要与发送端保持一致,一般来说都是默认设置8-N-1
4、连接好硬件后,选择传输端口,对应电脑上的USB口
5、设置数据收发模式,根据实际需要选择
6、点击“运行”,即可收发数据包
7、串口调试助手也可以调试TCP/UDP数据包,在下图位置,其使用方法与前者类似。
友善串口调试助手同类软件对比
1、串口调试助手
优点:使用方便,用户群最多,有书介绍及免费源代码。
缺点:1)因采用多线程接收技术,接收有时丢数,特别在高波特率或使用USB转串口时丢数较多。
2)只支持115.2K波特率。
3)只能选COM1~COM4,使用USB转串口时,要重新映射串口。
2、PCOMAPR(pcomtest)
优点:波特率高,高达921.6K,接收不丢数。
缺点:只有COM1~COM4可选,使用USB转串口时,要重新映射串口。
3、友善串口调试助手
优点:功能强,支持单界面双串口,可自动探测USB映射的COM口
缺点:日志记录按钮不太方便。
package main import ( "crypto/md5" "crypto/sha1" "encoding/hex" "fmt" "hash/crc32" ) // 生成md5 func MD5(str string) string { c := md5.New() c.Write([]byte(str)) return hex.EncodeToString(c.Sum(nil)) } //生成sha1 func SHA1(str string) string{ c:=sha1.New() c.Write([]byte(str)) return hex.EncodeToString(c.Sum(nil)) } func CRC32(str string) uint32{ return crc32.ChecksumIEEE([]byte(str)) } func main() { fmt.Println(CRC32("123456")) fmt.Println(MD5("123456")) fmt.Println(SHA1("123456")) }
前面写过 maptalks plugin ( ArcGISTileLayer ),有读者留言说文章写得太精简,根据文章给出的核心代码没办法写出一个完整的 plugin ( 文中有完整 demo 地址,可能太隐蔽 ),这篇文章具体地说下 plugin 如何编写,并实现一个 plugin ( WMTSTileLayer )。
学习一个新东西,最好的方式就是找官方文档。这里介绍一种捷径( 个人认为 ),直接模仿已有的插件编写。打开官网 plugins 页面[1],找一个 plugin,如 maptalks.e3.js,下面参考 maptalks.e3.js 写一个 WMTSTileLayer。
1、基本结构 以 maptalks.e3.js 为基本版本,通过对比其他插件,去掉具体业务代码,得到一个 WMTSTileLayer 的基本框架如下:
/*! * 版本申明 * maptalks.wmts v0.1.0 * LICENSE : MIT */ /*! * 依赖申明 * requires maptalks@^0.39.0 */ // UMD 固定写法 (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('maptalks')) :typeof define === 'function' && define.
可以一次性读取,也可以按行读取,也可以按字节读取,一般小文件直接一次性读取,当文件内容太大,内存不足,建议逐行读取处理。
package main import ( "bufio" "fmt" "io" "io/ioutil" "os" ) func main() { //1、一次性读取文件内容,还有一个 ReadAll的函数,也能读取 data, err := ioutil.ReadFile("./util/file.go") if err != nil { fmt.Println(err) return } fmt.Println(string(data)) //2、逐行读取 file, err := os.Open("./util/file.go") //打开 if err != nil { fmt.Println(err); return } defer file.Close() //关闭 line := bufio.NewReader(file) for { content, _, err := line.ReadLine() if err == io.EOF { break } fmt.Println(string(content)) } //3、按照字节数读取 file,err= os.Open("./util/file.go") if err!
betterScroll.js 原理 betterScroll.js 滚动原理。 -- betterScroll官网 此示例图展示了betterScroll.js的滚动原理,基本上理解这张图就可以解决此类库开发使用中碰到的绝大多数问题。
<!-- 示例结构 --> <div class='wrapper'> <div class='content'> <ul> <li>word word word word</li> <li>word word word word</li> ... <li>word word word word</li> <li>word word word word</li> </ul> </div> </div> 复制代码 如上示例代码,betterScroll.js只有当内容区域 - ‘content’ 部分的高度超过容器区域 - ‘wrapper’ 的高度,才会触发滚动,而只有触发betterScroll.js的滚动,才可以使用对用的下拉、上拉功能。
betterScroll.js 封装类库中碰到的问题及解决方案 1.betterScroll初始化之后无法触发滚动的问题 此问题如上文 原理 中已经作出了解释,在开发的过程中,务必初始化 ‘wrapper’ 容器,且保证子内容 ‘content’ 的高度超过父级容器。
若内容为空,如何触发滚动下拉刷新 实际开发中很多列表为空,此时 ‘content’ 无法通过其子内容自动撑开到超过父容器的程度,则此时需要利用css的计算属性对其高度进行赋值
设置为比父容器的 100% 多 1px 的高度即可
.content { min-height: calc(100% + 1px); } 复制代码 ‘content’ 已设置为比父容器高1px的情况,还是无法触发下拉(滚动) 这种情况往往是因为草率地设置了父级 ‘wrapper’ 的高度为100%,而 ‘wrapper’ 的父级并没有设置高度从而其无法继承父级高度,需要子级撑开导致的
1、上创建一个github账号并将项目上传至github。 2、进入项目生成release版本号。 进入项目 releases Draft a new release Tag version输入你想生成的版本号并记住稍后会用上 Publish release 返回项目更目录并进入你想生成的js或css界面 拼接链接并访问 (重点) https://cdn.jsdelivr.net/gh/用户/库@版本号/资源路径 例如我上面的例子拼接成的链接为
https://cdn.jsdelivr.net/gh/ZhugeXican/electron@v1.0.1/main.js.
注* 不使用jsdelivr直接引用github的文件 content-type 是 text/plain 页面无法解析 第一次写博客喜欢点个关注呗跟我一起学编程花里胡哨多的是
c的发展历史 void 类型 程序的入口成了_tmain(),这个和 VC6.0 中的 main 函数类似, 在前面加个 t,是为了对 unicode 项目的设置兼容,但它们都是程序执行的入口,其中 int argc 是程序的参数个数,_TCHAR* argv[]是参数数组。
程序的编译与链接,PE 格式 一个完整的 PE(Portable Executable)文件由 DOS 头,PE 文件头,块表,块 和调试信息(调试版本有效)组成
在 DOS 头部,以 e_magic 开头,它的值是固定的”0x5a4d”,即(MZ)开头。最开头的 是部分是 DOS 部首,DOS 部首由两部分组成:DOS 的 MZ 文件标志和 DOS stub(DOS 存根程序)。之所以设置 DOS 部首是微软为了兼容原有的 DOS 系统下的程序而设立的。 系统与程序的内存布局 在我们开始内核调试之前,首先我们需要对系统的内存内核层与应用层的布局有一个基本认 识。以 X86 为例,X86 支持 32 位寻址,因此可以支持最大 2^32=4GB 的虚拟内存空间(当然 也可以通过 PAE 将寻址空间扩大到 64GB,PAE 即 Physical address extension,x86 的处理器增加了额外的地址线以选择那些增加了的内存,所以实体内存的大小从 32 位增加到了 36 位。 最大的实体内存由 4GB 增加到了 64GB)。如下图所示,在 4G 的虚拟地址空间中,Windows系统的内存主要分为内核空间和应用层空间上下两部分,每部分各占约 2GB,其中还包括了 一个 64KB 的 NULL 空间以及非法区域,虚拟地址再通过页表机制映射到物理地址以便存取物理内存中的数据和指令。
2019年7月1日开始实施JT808-2019和JT809-2019标准,打算利用这两个星期把这两个协议兼容了。目前JT808-2019协议解析已经兼容,指令部分在完善中。全新的SpringBoot Netty版本JT809-2019正在开发中,这个月底能够完成。
原来是跨页双栏的状态(也就是两页),可以先将第二页中所有的文字选中,
然后在点击‘页面布局-单栏’(将其变为单栏),然后在第二页的最上方添加进表格或图片。
然后再选中表格或图片下方的文字,将其再变为双栏即可。
转载https://www.cnblogs.com/feisky/archive/2010/12/09/1901349.html
说明 使用Python的字符串处理和正则表达式处理实现了一个删除C/C++源程序中所有注释和空行的小脚本。
使用字符串处理 1: # delete all the comments and empty line of a C/C++ source file 2: import os, sys,string 3: 4: #------------------------------------------------------------- 5: def usage(): 6: print u''' 7: help: del_comment.py <filename | dirname> 8: ''' 9: #-------------------------------------------------------------- 10: def deal_file(src): 11: # file exist or not 12: if not os.path.exists(src): 13: print 'Error: file - %s doesn\'t exist.'% src 14: return False 15: if os.path.islink(src): 16: print 'Error: file - %s is a link.
写在前面:
微软官网给的答案(重置网络、设置DNS)在我电脑上不适用,经过一番寻找,最后的解决办法如下。
打开“控制面板”,打开“Internet选项”,转到“高级”标签页,勾选“使用TLS1.2”,“确定”。
PS:不需要重启电脑。
目录、文件的创建、删除、存在与否
package main import ( "fmt" "os" ) //判断文件或者文件夹是否存在,一般判断第一个参数即可,第二个参数可以忽略,或者严谨一些,把err日志记录起来 func FileExists(file string) (bool, error) { _, err := os.Stat(file) if err == nil { return true, nil //文件或者文件夹存在 } if os.IsNotExist(err) { return false, nil //不存在 } return false, err //不存在,这里的err可以查到具体的错误信息 } //判断目录是否存在 func isDir(dir string) bool { info, err := os.Stat(dir) if err == nil { return false } return info.IsDir() } //判断文件是否存在 func isFile(file string) bool { info, err := os.
名称
作者
主CPU
客户CPU
主系统
客户系统
许可
CHARON
Stromasys
x86,x86-64
DEC PDP11,Alpha, VAX, SUN SPARC,HP3000
Windows,Linux, Solaris
Solaris/SunOS,Tru64,OpenVMS,Ultrix
私有
Bochs
Kevin Lawton
任何
x86,x86-64
Windows,Windows Mobile,Linux,IRIX,AIX,FreeBSD,OpenBSD,BeOS,Mac OS X
DOS,Windows,xBSD,Linux
LGPL
DOSBox
Peter Veenstra和Sjoerd与社区帮助
任何
x86
Linux,Windows,Mac OS Classic,Mac OS X,BeOS,FreeBSD,OpenBSD,Solaris,QNX,IRIX,MorphOS,AmigaOS
DOS
GPL
DOSEMU
社区项目
x86,x86-64
x86
Linux
DOS
GPL v2
Hercules
Roger Bowler
任何
z (IBM大型计算机)
Linux, Mac OS X,Solaris,Windows
OS/360,OS/390,z/OS,z/Linux
QPL
Hyper-V
微软
x64+硬件辅助虚拟(AMD-V或Intel VT)
x64,x86
Windows 2008
UndeclaredThrowableException异常背景 最近项目上出现了 JDK动态代理UndeclaredThrowableException异常,此异常之前没有接触过,那么该异常将会导致什么呢?
UndeclaredThrowableException后果:导致该抛出的直接异常信息被包装了好几层,异常看起来很费事,如下图:
产生原因 要了解其原因的前提条件是必须了解检查型异常和非检查型异常,了解的话请查看这个链接:检查型异常和非检查型异常 为什么会产生UndeclaredThrowableException异常呢?通过查阅javadoc官方文档(链接地址:https://docs.oracle.com/javase/6/docs/api/java/lang/reflect/InvocationHandler.html),发现了该异常抛出的条件,如下图:
上述原因翻译成关键一句就是:如果抛出的异常是检查型异常,而代理类在处理异常时没有发现该类型的异常在接口中声明
这种话是什么意思呢?下面结合代码给大家讲述一下,动态代理之后会生成$Proxy0.class文件,至于怎么生成并查看这个文件,请查看这个链接:JDK动态代理文件$Proxy0.class的生成和查看, $Proxy0.class 文件内容说明了如何抛出了UndeclaredThrowableException异常,如下图:
通过JDK动态代理代码调用我们发现,method.invoke(target, args) 将会抛出 InvocationTargetException ,InvocationTargetException 异常属于检查型异常,如下图:
而代码中接口声明的是非检查型异常RuntimeException,因此会抛出 UndeclaredThrowableException异常,示例demo如下所示:
// 自定义异常 public class CustomException extends RuntimeException { private static final long serialVersionUID = -5427543428947291283L; public CustomException(String message) { super(message); } } // 接口 public interface AccountService { void getAccount() throws RuntimeException; } // 实现类 public class AccountServiceImpl implements AccountService { @Override public void getAccount() throws RuntimeException { try { System.
平时我们在网上平台购物,每一订单各种单号都有,例如:物流单号,业务单号,等等,
如果在淘宝下单时使用了花呗支付,还要有个花呗单。
这些单号,生成都是有一定规则的,至于规则那是人家公司定的与我们无关,但是这些单号都是唯一的。
目前我在项目实训中,也有生成类似单号的情况;
我是通过获取当前时间的{yyyy}{MM}{DD}{HH}{mm}{ss}年月日时分秒拼接某格式实现的
至于获取的方法和属性就不说了,前面有,CSDN的博客上一搜也有大堆;
注意下面的方法是存在问题的。
//获取日期时间拼接成特定格式
function SetDateNumder() {
var date = new Date();
var strmonth = date.getMonth() + 1;//获取月份
var strDate = date.getDate();//获取日期
var strMinute = date.getMinutes();//获取分
var strSeconde = date.getSeconds();//获取秒
if (strmonth >= 1 && strmonth <= 9) {
strmonth = “0” + strmonth;
}
if (strDate >= 1 && strDate <= 9) {
strDate = “0” + strDate;
}
if (strMinute >= 1 && strMinute <= 9) {
这是一种可以创建多线程消息的函数
使用方法:
1,首先创建一个Handler对象
Handler handler=new Handler();
2,然后创建一个Runnable对象
Runnable runnable=new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
//要做的事情,这里再次调用此Runnable对象,以实现每两秒实现一次的定时器操作
handler.postDelayed(this, 2000);
} };
3,使用PostDelayed方法,两秒后调用此Runnable对象
handler.postDelayed(runnable, 2000);
实际上也就实现了一个2s的一个定时器
4,如果想要关闭此定时器,可以这样操作
handler.removeCallbacks(runnable);
当然,你也可以做一个闹钟提醒延时的函数试试,比如,先用MediaPlayer播放闹钟声音,
如果不想起,被停止播放之后,下次就5分钟后再播放,再被停止的话,下次就4分钟后播放,
………………
只要更改延时的时间就可以实现了,用一个static对象的话会比较容易操作。
是可以异步效果,但Runnable的执行是在Handler对象所在的线程
如果其所在的线程是UI线程的话,Runnable中还是不能执行耗时操作,不然会ANR
前几天我们自己的设备很卡,卡到跳转界面都需要不到1秒的时间,我就把跳转的动作放在Runnable里边,外边加上弹出进度提示框
注:举例说明
public class XXX extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.loading); // 显示第1屏
Handler handler = new Handler();
handler.postDelayed(new splashhandler(), 2000); // 延迟2秒,再运行splashhandler的run()
}
class splashhandler implements Runnable
#include<stdio.h> int main() { int i;//循环变量 int n;//循环的次数 int num;//输入的值 int max;//最大的数 scanf("%d",&n); for(i = 0;i < n;i ++) { scanf("%d",&num); if(i == 0) { max = num; } if(max < num) { max = num; } }; printf("%d",max); return 0; }
在解压后,安装MySQL时出现如下错误:
解决:加两个参数: nodeps ,force
若还出错,可能是版本冲突,见:https://blog.csdn.net/typa01_kk/article/details/49059729
【史上最全】国内外常用精品API汇总
API是获取网络服务最便捷的方式,合理地使用API开发项目可以大大提高开发效率,把精力都集中在程序的业务逻辑之上,避免重复造轮子。推荐给大家个人觉得很赞的第三方API(资源整合自网络)。文章分为天气查询、生活常用、文体娱乐、企业金融、通讯服务、交通出行、技术开发七大类,如果你觉得分类不直观,想直接获取免费可试用的api,也可以直接搜索用友APILink,或访问官网api.yonyoucloud.com
一、天气查询
天气查询应用的场景非常广,我猜很多人练手的第一个项目就是做天气查询类的demo。
全国天气预报 - 一个简单的HTTP接口,根据用户输入的adcode,查询目标区域当前/未来的天气情况。 使用API前需先申请Key。
AccuWeather - AccuWeather API 通过一个简单的 REST 风格的 Web 界面为订阅者提供基于位置的天气数据的访问. Aeris Weather - 驱动你的定制应用的先进 API, 为新鲜空气提供了从简到繁的解决方案. 彩云天气 - 中国天气信息. 和风天气 - 中国天气信息. Open Weather Map - Open Weather Map 服务提供免费的天气数据和预测 API, 适用于任何制图服务, 如网页和智能手机应用程序. Weather Underground - 可靠的数据, 准确的预测, 全球覆盖80种语言. Weather Unlocked - 电子广告商, 电子商务和开发人员的天气驱动方案.
心知天气 - 中国天气信息. Yandex.Weather - Yandex.Weather 使用专有的预测技术 Meteum 来评估俄罗斯地区特定地点的当前天气情况, 并为这些地理坐标创建预报. Yahoo! Weather - 获取任何位置的最新天气信息, 包括5天预报, 风, 大气, 天文条件等. 二、生活常用
目录
1.navigation导航对象相关参数
1.1在当前Component获取navigation导航对象
1.2navigate方法
1.2.2使用示例
1.2.3源码
1.3params
1.4navigation的state属性
2.动态修改标题-title或者左右显示组件-headerRight
2.1动态修改标题
2.2动态修改左右显示组件-headerRight
2.3动态监听右侧组件点击事件
2.4动态设置标题剧中
1.navigation导航对象相关参数 1.1在当前Component获取navigation导航对象 const {state,params,navigate}=this.props.navigation;
1.2navigate方法 navigate方法参数,navigateTo:具体进入页面,params:传递给下一个页面具体参数,action:动作
1.2.2使用示例 const {navigate} = this.props.navigation; //获取navigation的navigate方法
navigate(
'InspectionAndMaintenanceScene', //必填,具体进入的下一个页面
{user:'111'}, //下一个界面接收的参数
//(advanced) The sub-action to run in the child router, if the screen is a navigator. Any one of the //actions described in this doc can be set as a sub-action.
//(高级)如果屏幕是导航器,要在子路由器中运行的子操作。此文档中描述的任何操作都可以设置为子操作。
NavigationActions.navigate({ routeName: 'WriteConfigInfoScene' }) //通常不需要配置
);
1.2.3源码 navigate: (navigateTo, params, action) => { if (typeof navigateTo === 'string') { return navigation.
下图是tomcat与jdk的对应版本:
因tomcat与jdk版本都在不断变化,因此请前往tomcat官网进行查证,官网版本对应关系地址:http://tomcat.apache.org/whichversion.html
最近在搞前端的时候突然报了Cannot read property ‘length’ of null的错,一开始都是在前端调试错,发现解决不了问题,后来发现如果你所查找的数据条数为0的时候,后端返回给前端是null,此时必然报错Cannot read property ‘length’ of null.
解决办法:
如果后端的返回值为null,就需要我们在后端返回一个空的list数组
本人错误的后台代码:
如果返回data有数据,那么返回Data=data,如果没有数据,我们没有给前端返回一个data,所以在前端就接受到的是个null
var data = IScreenshot.GetAllStuScreenInfo(studentId); return data.Count != 0 ? new AjaxResult() { Status = "ok",Data=data } : new AjaxResult() { Status = "error",ErrorMsg= "暂时未能查询到任何信息"}; 改正后的后台代码:加上一个data,此时data的值为空的list.
var data = IScreenshot.GetAllStuScreenInfo(studentId); return data.Count != 0 ? new AjaxResult() { Status = "ok",Data=data } : new AjaxResult() { Status = "error",ErrorMsg= "暂时未能查询到任何信息",Data=data};
1.下载NCCL 官网下载地址
根据想要安装的nccl版本以及自己cuda版本选择对应下载项,以我自己安装的情况为例,选择下载:Download NCCL v2.3.7, for CUDA 10.0, Nov 8 & Dec 14, 2018
nccl下载安装分本地安装(Local installers (x86))和网络安装(Network installers (x86)), 这里我们选择网络安装,我的系统时Ubuntu16.04,所以选择:Network Installer for Ubuntu16.04 。下载完成后,得到一个文件:nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb
2.安装 安装网络版本依次执行以下命令即可:
sudo dpkg -i nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb sudo apt update sudo apt install libnccl2=2.3.7-1+cuda10.0 libnccl-dev=2.3.7-1+cuda10.0 成功安装大概会出现下面类似log信息
一、BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor 类。
postProcessBeanDefinitionRegistry();
在所有bean定义信息将要被加载,bean实例还未创建的;优先于BeanFactoryPostProcessor执行;利用BeanDefinitionRegistryPostProcessor给容器中再额外添加一些组件。
自定义 BeanDefinitionRegistryPostProcessor
@Component public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor{ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { // TODO Auto-generated method stub System.out.println("MyBeanDefinitionRegistryPostProcessor...bean的数量:"+beanFactory.getBeanDefinitionCount()); } // BeanDefinitionRegistry Bean定义信息的保存中心,以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例; @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { // TODO Auto-generated method stub System.out.println("postProcessBeanDefinitionRegistry...bean的数量:"+registry.getBeanDefinitionCount()); //RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class); AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition(); registry.registerBeanDefinition("hello", beanDefinition); } } 测试:
@Test public void test01(){ AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class); applicationContext.
1.封装性 面向对象的第一个原则是把数据和对该数据的操作都封装到一个类中,类的概念和现实世界的“事务种类”是一致的。
如电视机就是一个类,每台电视机都有尺寸、品牌,这些性能被封装成类的属性,每台电视机都可以开关电视、播放电视节目,这些行为动作被封装成类的方法。
对象是类的一个实例化结果,对象具有类所描述的所有属性及方法,是具体的。
每个对象都属于某个类,面向对象程序设计就是设计好相关的类,类中有属性和方法。
封装是为了继承
2.继承性 继承是在类、子类以及对象之间自动地共享属性和方法的机制。
类的上层可以有父类,下层可以有子类,形成一种层次结构。
一个类将直接继承其父类的属性和方法,而且继承还具有传递性,因此,它还将间接继承所有祖先类的属性和方法。
继承最重要的有点是复用性,在继承已有类的基础上加以改写,进而功能得到不断扩充,这样既可以得到程序共享的好处,又可以,提高软件开发的效率。
继承是为了多态
3.多态性 多态是指在表示特定功能时,有多种不同的形态或实现方法。
常见的多态形式有以下两种:
(1)方法重载。(overlord) 即在同一个类中,相同名称的方法有多种形态。
一、方法重载的具体规范:
1、必须具有不同的参数列表;
2、可以有不同的返回类型,只要参数列表不同就可以了;
3、可以有不同的访问修饰符;
4、可以抛出不同的异常。
好处:提供方法的多种使用形式,方便调用。
####(2)方法覆盖。(override)
对于父类的某个方法,在子类中重新定义一个相同形态()的方法,这样,在子类中将覆盖从父类继承来的那个方法。
遵循一同一大两小原则:
一同:方法签名必须相同。
方法签名 = 方法名称 + 参数列表,参数列表 = 参数个数 + 参数类型 + 参数顺序。
也就是说,方法名称,参数个数,参数类型,参数顺序必须都相同。
一大:子类方法的访问权限大于等于父类方法的访问权限。
两小:子类方法的返回值类型小于等于父类方法的返回值类型,子类方法声明抛出的异常小于等于父类方法声明抛出的异常。
好处:以相同的方式对待不同的对象,不同的对象可以用各自的方式响应同一消息。
运行时多态:通过父类定义的变量可引用子类的对象,执行对象方法时则表现出每个子类对象各自的行为。 4.抽象性 两层含义,(1)体现在类的层次设计中,高层类是底层类的抽象描述。
(2)体现在类与对象之间的关系上,类是一个抽象的概念,而对象是具体的。
总结:面向对象的核心:设计类
tomcat 启动报错:org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/springmvc-servlet.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/springmvc-servlet.xml]
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/springmvc-servlet.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/springmvc-servlet.xml] at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:344) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304) at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188) at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:224) at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:195) at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125) at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94) at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:133) at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:636) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:521) at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:701) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:667) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:715) at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:590) at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:529) at org.
题目描述 一队士兵在操场上排成一列,士兵总数为n,士兵按照队伍从前往后的顺序从1到n依次编号。每个士兵有各自的身高,第i个士兵的身高为ai。
士兵列队完毕后,将军走到队列的最前面。因为身高不一,有些士兵可能被前面身高更高的挡住了,这样将军就看不到他们。将军能看到某个士兵当且仅当他的身高严格大于他前面的所有士兵。
问将军一共能看到多少个士兵。
注意: 这道题目不是最长上升子序列问题,因为将军是从第一个士兵开始看到,比较简单。
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int N = 10000; int nums[N]; int dp[N]; int main() { int T; scanf("%d", &T); while (T--) { int n;; scanf("%d", &n); int res = 1, temp = 0; scanf("%d", &nums[0]); temp = nums[0]; for (int i = 1; i < n; i++){ scanf("%d", &nums[i]); if (nums[i] > temp) { temp = nums[i]; res++; } } printf("
通常情况下在项目中会有大量的测试case需要去执行操作,基于上一小节的方法(将测试用例添加到测试容器中),在大批量的case面前会变得非常的麻烦。
通常情况下测试用例的执行都是部署到Jenkins的集成测试环境中的,通常我们只需要一条命令执行就可以执行测试用例。
基于这样的思想,我们用可以将我们要执行的测试用例文件全部添加的测试容器中去,然后我们去执行测试容器中添加的批量的测试用例就达到执行批量测试用例的效果。
GitHub代码commits id:2a0769b
创建一份大量测试用例的unittest_case02.py文件
#!/bin/usr/env python3 # -*- coding: utf-8 -*- # -------------------------------------- # ProjectName: MySpace # Author: crisimple # CreateTime: 2019/6/15 18:49 # FileName: unittest_case02.py # Description: 大批量运行case # Question: # -------------------------------------- import unittest class UnittestCase(unittest.TestCase): @classmethod def setUpClass(cls) -> None: print("所有case执行之前的前提条件\n") @classmethod def tearDownClass(cls) -> None: print("所有case执行之后的后置条件\n") def setUp(self) -> None: print("...case 的前置条件...\n") def tearDown(self) -> None: print("...case 的后置条件...\n") def test_case001(self): print("first case001") # 跳过测试用例的执行,即使在容器中添加了测试用例也可以被跳过 @unittest.
下载springmvc Jar
最终下载地址:https://repo.spring.io/simple/libs-release-local/org/springframework/spring/
步骤:
https://repo.spring.io/simple/libs-release-local/
https://repo.spring.io/simple/libs-release-local/org/
https://repo.spring.io/simple/libs-release-local/org/springframework/
https://repo.spring.io/simple/libs-release-local/org/springframework/spring/
signal.h是C标准函数库中的信号处理部分,定义了程序执行时如何处理不同的信号。信号用作进程间通信,报告异常行为(如除零)、用户的一些按键组合(如同时按下Ctrl与C键,产生信号SIGINT)。C++中的对应头文件是csignal。
C语言标准定义了6个信号,都定义在signal.h头文件中:
(1). SIGABRT:程序异常中止,如调用abort函数。
(2). SIGFPE:算术运算出错,如除数为0或溢出。
(3). SIGILL:非法函数映像,如非法指令。
(4). SIGINT:交互的用户按键请求,如同时按下Ctrl+C键。
(5). SIGSEGV:无效内存访问,段错误。
(6). SIGTERM:程序的中止请求。
signal.h可能还定义了其它信号,这依赖于具体实现。例如,类Unix系统还定义了15个以上的信号。Visual C++的C标准库只支持C语言标准规定的6个信号,即对信号处理只提供最小的支持。
signal函数:该函数设置一个函数(回调函数)来处理捕获到异常信号时需要执行的操作,其函数声明方式如下:
// Type of a signal handler typedef void (*__sighandler_t)(int); __sighandler_t signal(int __sig, __sighandler_t __handler); 下面是测试代码:
#include "signal.hpp" #include <signal.h> #include <string> #include <thread> #include <chrono> namespace signal_ { namespace { bool flag = true; void process_exit(int sig) { switch (sig) { case SIGINT: fprintf(stderr, "process exit: SIGINT: value: %d\n", sig); break; case SIGFPE: fprintf(stderr, "
1.首先在python中取一个字符串的多少位,使用s[begin:end]。
2.c++中使用一个函数来截取字符串位
头文件:
#include <string> //注意没有.h string.h是C的标准字符串函数数,c++中一般起名为ctring. 而string头文件是C++的字符串头文件。
函数原型: string substr(int pos = 0,int n ) const; 参数说明: 参数1:pos是必填参数
参数2:n是可参数,表示取多少个字符,不填表示截取到末尾
该函数功能为:返回从pos开始的n个字符组成的字符串,原字符串不被改变
# include <iostream> # include <string> using namespace std; int main() { const string image_name = "0170.bmp"; print(image_name.substr(0, 4)); return 0; } 参考:https://blog.csdn.net/liuweiyuxiang/article/details/50838349
【题目描述】
彦彦作为琳琳最好的朋友,她当然知道琳琳很爱吃桃子啦,于是,她们去了果园摘桃子,一棵果树上有N个桃子,可是,琳琳是一个很挑剔的人,她只摘重量大于K的大桃子,彦彦刚刚学信息学,不知道如何是好,所以她希望你帮她编个程序,求出一共可以吃到多少个桃子,并求出可以吃到的桃子的总重量和。
【输入】
第一行输入N(1<=N <=10000),K(1<=K <=5000),第二行输入N个数,表示每个桃子的重量,桃子每个的重量不超过100。
【输出】
第一行为可以吃到的桃子的数量,第二行为总重量和。
【输入样例】
8 5
1 2 3 4 5 6 7 8
【输出样例】
3
21
代码
#include<cstdio> int a,n,m,k,t; using namespace std; int main() { scanf("%d%d",&m,&n); for (int i=1;i<=m;++i) { scanf("%d",&k); if(k>n) { t=t+1; a=a+k; } } printf("%d\n",t); printf("%d",a); return 0; } #include<iostream> int a,n,m,k,t; using namespace std; int main() { cin>>m>>n; for (int i=1;i<=m;++i) { cin>>k; if(k>n) { t=t+1; a=a+k; } } cout<<t<<endl<<a; return 0; }
0.下载准备 下载安装VS2017或VS2015
下载安装opencv
可以参考博客:VS2017配置opencv教程 ,该博客中写的很详细
安装cmake
记得把bin目录添加到环境变量path中,例如我的:E:\SoftEnv\CMake\bin
下载libtorch
下载地址:PyTorch libtorch ,这个根据自己情况选择下载,因为我自己的是cuda10,并且我选择使用release版本,所以我的选择如下:
1.PyTorch模型转换为Torch脚本 PyTorch模型从Python到C ++的旅程由Torch Script实现,Torch Script是PyTorch模型的一种表示,可以由Torch Script编译器理解,编译和序列化。
这里说下通过跟踪转换为Torch脚本方式(示例),创建一个名为TorchScrip.py的脚本,内容如下:
import torch import torchvision # An instance of your model. model = torchvision.models.resnet18() # An example input you would normally provide to your model's forward() method. example = torch.rand(1, 3, 224, 224) # Use torch.jit.trace to generate a torch.jit.ScriptModule via tracing. traced_script_module = torch.jit.trace(model, example) traced_script_module.save("model.pt") 然后运行该脚本,会生成一个 model.pt 文件,该文件就是C++需要调用的模型。
2.准备C++测试代码和CMakelists.txt文件 首先,我在E:/PyTorch/libtorch_test路径下创建一个名为Example的文件夹,然后在该文件夹下分别创建C++测试代码(例如:example-app.cpp)和CMakelists.txt文件以及名为build的文件夹。
索引的简介:
create index 索引名称 on 表名称(字段名称)
索引分为聚集索引和非聚集索引,数据库中的索引类似于一本书的目录,在一本书中通过目录可以快速找到你想要的信息,而不需要读完全书。
索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间 。
但是索引对于提高查询性能也不是万能的,也不是建立越多的索引就越好。索引建少了,用 WHERE 子句找数据效率低,不利于查找数据。索引建多了,不利于新增、修改和删除等操作,因为做这些操作时,SQL SERVER 除了要更新数据表本身,还要连带立即更新所有的相关索引,而且过多的索引也会浪费硬盘空间。
索引的分类:
索引就类似于中文字典前面的目录,按照拼音或部首都可以很快的定位到所要查找的字。
唯一索引(UNIQUE):每一行的索引值都是唯一的(创建了唯一约束,系统将自动创建唯一索引)
主键索引:当创建表时指定的主键列,会自动创建主键索引,并且拥有唯一的特性。
聚集索引(CLUSTERED):聚集索引就相当于使用字典的拼音查找,因为聚集索引存储记录是物理上连续存在的,即拼音 a 过了后面肯定是 b 一样。
非聚集索引(NONCLUSTERED):非聚集索引就相当于使用字典的部首查找,非聚集索引是逻辑上的连续,物理存储并不连续。
PS:聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个。
什么情况下使用索引:
语法:
CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name ON <object> ( column_name [ ASC | DESC ] [ ,...n ] ) [ WITH <backward_compatible_index_option> [ ,...n ] ] [ ON { filegroup_name | "default" } ] <object> ::= { [ database_name.
''' from sklearn import datasets, model_selection, svm, decomposition, pipeline, metrics import matplotlib.pyplot as plt lfw_people = datasets.fetch_lfw_people(min_faces_per_person=70, resize=.4) n_images, h, w = lfw_people.images.shape x = lfw_people.images.reshape((n_images, -1)) n_feature = x.shape[1] print(n_feature) target_names = lfw_people.target_names n_class = len(target_names) print(n_class) y = lfw_people.target x_train, x_test, y_train, y_test = model_selection.train_test_split(x, y, test_size=.25) svc = svm.SVC(class_weight='balanced') pca = decomposition.PCA(whiten=True, svd_solver='randomized') pipe = pipeline.Pipeline([('pca', pca), ('svc', svc)]) gs = model_selection.GridSearchCV(pipe, {'pca__n_components': [8, 16, 24, 32, 48, 56, 64], 'svc__C': [1e3, 5e3, 1e4, 5e4, 1e5], 'svc__gamma': [0.
在最近的vue项目中,有一个需求是实现自定义样式的video播放器和audio播放器。
在这里记录下实现的思路。
首先得熟悉video与audio原生标签中的API——传送门
这里需要用到API有:
play;//开始播放音频/视频pause; //暂停当前播放的音频/视频loadedmetadata; //当浏览器已加载音频/视频的元数据时timeupdate; //当目前的播放位置已更改时 进度条实现用的elementUI组件中的Slider 滑块——传送门
这里我拿video播放器举例,video与audio播放器的样式与调用的API基本一致,所以当你知道如何实现video播放器后,audio播放器就是一样的思路了。
HTML
<div class="video-box"> <div class="video_playIcon" v-if="!initVideo.play" @click="playVideo"></div> //video API相关获取与调用 <video class="video" ref="video" :src="initVideo.url" @pause="handPlay(2,2)" @play="handPlay(2,1)" @loadedmetadata="getAudioLength(2)" @timeupdate="videoTimeUpdate" @click="playVideo"> 该浏览器不支持video </video> <div class="video_control"> <div class="progress"> //进度条 <el-slider class="commonSlider" :show-tooltip="false" v-model="initVideo.currentTime" :max="initVideo.videoLength" @change="changeVideoTime"> </el-slider> <div class="time"> //videoLength 总时间,currentTime 当前时间,videoTime 自定义过滤器 <span>{{initVideo.currentTime | videoTime}}</span> <span>{{initVideo.videoLength | videoTime}}</span> </div> </div> </div> </div> JS
data() { return { //视频 initVideo: { play: false,//播放还是暂停 true播放中 videoLength: 0,//时长 url: "
大数处理,可以用golang的math/big包
package main import ( "fmt" "math/big" ) func main() { //设置一个大于int64的数 a := new(big.Int) a, ok := a.SetString("9122322238215458478512545454878168716584545412154785452142499999", 10) if !ok { panic("error") } //String方法可以转换成字符串输出 fmt.Println(a.String()) //大数相加 b:=big.NewInt(2) b=b.Add(a,b) // Mod 取模、Add 加、Sub 减、Mul 乘、Div 除 fmt.Println(b.String()) }
云计算存储之存储高级特性博客目录 云计算存储1. 存储高级特性1.1虚拟磁盘的分配方式(1)预分配(2)精简分配1. 什么是精简分配2. 精简分配详细说明(1) LUN虚拟化(2) LUN动态扩容 3. 精简分配功能的优势及问题优势问题 4. 精简分配存储池状态检测 1.2 快照1.2.1 快照介绍快照的定义快照的价值快照的分类 1.2.2 快照的技术(1) COW(2) ROW(3) COW 和 ROW 对比 1.3 副本1.3.1 副本分布卷1.3.2 副本复制卷1.3.3 副本分布卷和复制卷1.3.4 多副本磁盘管理(1)主机个数、磁盘个数可以被副本数整除情况(2)主机个数、磁盘个数不能被副本数整除情况 1.3.5 多副本主机读写数据 1.4 数据平衡1.4.1 数据平衡介绍1.4.2 数据平衡配置 云计算存储 1. 存储高级特性 1.1虚拟磁盘的分配方式 Sangfor虚拟化平台为虚拟机创建新磁盘时,有两种磁盘分配方式可选,一种为预分配,一种为精简分配
(1)预分配 设置预分配的磁盘,在磁盘初始化时就占用了配置的全部空间,这样可以大幅提升该虚拟机的 IOPS 和吞吐量,但是虚拟机未使用的磁盘空间无法被其他虚机使用
(2)精简分配 虚拟机写磁盘时按需分配,虚拟未使用的空间还能够给其他虚拟机使用,可以节省存储空间,但是虚拟机写磁盘时要先申请存储空间,这个过程 对写性能有一定影响,相比来说磁盘性能不如预分配
1. 什么是精简分配 精简分配是一种存储管理的特性,核心思想是“欺骗”操作系统,利用主机不会去逐字节检查所有空间,并且分配给主机的存储空间不会被瞬间写满这个特点,把传统的完全供给变为按需供给
精简卷能够随着主机数据的写入而动态扩展容量,但最终扩展后的容量不会高于创建卷时指定的卷容量
2. 精简分配详细说明 (1) LUN虚拟化 分配虚拟LUN给主机,实现存储按需扩容
例如:主机看到500GB的空间,存储端实际只占用200GB
(2) LUN动态扩容 LUN空间按策略自动增长
扩容过程主机无需停机
空间最大化利用,降低管理复杂度
(3) 客户价值
提高资源利用率,避免首次存储资源规划浪费
3. 精简分配功能的优势及问题 优势 当精简卷在存储内镜像、克隆和存储间复制时,只需同步实际使用的数据,节省CPU、磁盘和带宽开销
问题 当存储池内的容量被用尽,而又没有及时添加新的物理资源。导致精简卷无法正常扩展空间,数据无法写入底层数据块,对应用产生重大影响
一、鼠标键入消息 1.WM_LBUTTONDBLCLK 双击鼠标左键;
2.WM_LBUTTONDOWN 单击鼠标左键;
3.WM_LBUTTONUP 松开鼠标左键;
4.鼠标中键及右键分别将上述L替换为M、R;
5.WM_MOUSEMOVE 鼠标移动消息;
6.WM_MOLSEWHEEL 鼠标滚轮消息;
二、鼠标消息处理 1.lParam:其参数值分为高位字节与低位字节,低位字节存储鼠标光标的X坐标值,高位字节存储Y坐标值;
WORD LOWORD(lParam 参数);
WORD HIWORD(lParam 参数);
2.wParam:记录鼠标按键及Ctrl、Shift键,通过wParam与测试标志的与操作判断按键是否按下;
测试标志:MK_L/M/RBUTTON(左中右)、MK_SHIFT、MK_CONTROL
3.当处理滚轮消息时,1不变,wParam低位字节存储按键的状态信息,高位字节是120或-120,表示向前或向后滚动;
三、鼠标相关函数 1.HWND SetCapture(HWND hwnd);
功能:获取窗口外的鼠标消息;
2.BOOL SetCursorPos(int x轴坐标,int y轴坐标);
功能:设定鼠标光标位置,这里的位置是相对于屏幕左上角的坐标;
3.BOOL ClientToScreen(HWND hwnd,LPPOINT 窗口点坐标);
功能:窗口点坐标转换为屏幕坐标,然后再使用SetCursorPos函数;
4.BOOL ScreenToClient(HWND hwnd,LPPOINT 屏幕点坐标);
功能:把屏幕坐标转换为窗口坐标;
5. int ShowCursor(BOOL true或false);
功能:隐藏及显示鼠标光标;
6.BOOL ClipCursor(CONST RECT 移动区域矩形);
功能:限制鼠标光标的移动区域,解除限制则参数设为NULL;
7.BOOL GetWindowRect(HWND hwnd,LPRECT 矩形结构);
功能:取得窗口外部区域矩形;
8.BOOL GetClientRect(HWND hwnd,LPRECT 矩形结构);
功能:取得窗口内部区域矩形;
四、飞机射击子弹的基本思路 1.一开始未按鼠标左键,则进行背景图的贴图并实现背景循环;
2.移动鼠标触发消息处理函数,获取鼠标光标的位置后,在贴图函数中,根据鼠标光标位置,确定飞机的贴图坐标,为了产生移
动效果,让飞机的坐标缓缓接近鼠标光标;
2.单击鼠标左键,消息处理函数处理该消息,设置第一颗子弹的贴图坐标(因为声明的子弹结构体是全局变量,所以它的成员变量 exist默认被初始化为0),然后回到贴图函数,先贴背景,再贴飞机,最后贴第一颗子弹,现在若不进行任何操作,则在主函数
创建一个javaweb项目流程
为什么创建的javaweb项目没有web.xml? 如何在已经创建好的项目中增加 web.xml
创建一个javaweb项目流程 右键选择New->Dynamic Web Project
下一步
下一步
下一步
注意:上图红色框不勾选,创建的项目没有web.xml (创建时候一般需要勾选) 如下图所示
为什么创建的javaweb项目没有web.xml? 如何在已经创建好的项目中增加 web.xml 注意:一般在在创建项目的时候都是快速创建(即快速点Finish),故经常出现没有web.xml的事情。让人感觉特别烦恼。
如何在已经创建好的项目中增加 web.xml,以上面创建好的没有web.xml的项目为例子。现在把它找出来。
项目右键——>properties
project faceets——>把“Dynamic Web Module”前面的钩去掉——>apply——>OK
上述图片中的Dynamic Web Module 是被锁定的,需要先解锁。如下图:右键 Unlock
下一步
下一步:下图最后一个箭头处勾选 点击OK 点击apply
打完收工
两种方式生成的web.xml 不一样。
可以参考:创建javaweb项目时的web.xml和后来增加的web.xml 之间的区别
一、常用调优方法
1、将新对象预留在新生代
由于 Full GC 的成本要远远高于 Minor GC ,因此尽可能将对象分配在新生代,在JVM 调优中,可以为应用程序分配一个合理的新生代空间,以最大限度避免新对象直接进去老年代。
注意:由于新生代垃圾回收的速度高于老年代回收,因此,将年轻对象预留在新生代有利于提高整体的 GC 效率
2、大对象进入老年代
大对象占用空间多,直接放入新生代中会扰乱新生代GC,新生代空间不足将会把大量的较小的年轻代对象移入到老年代中,这对GC来说是相当不利的。如果有短命大对象,对GC来说将会是一场灾难,原本存放于老年代的永久对象,被短命大对象塞满,扰乱了分代内存回收的基本思路,因此,在开发过程中,尽可能避免使用短命的大对象。使用参数 -XX:PretenureSizeThreshold 设置大对象直接进入老年代的阀值,当对象超过这个阀值时,将直接在老年代中分配。其中, -XX:PretenureSizeThreshold 只对串行收集器和新生代并行收集器有效,并行回收收集器不识别这个参数。
注意:短命的大对象对垃圾回收是一场灾难,目前木有一种特别好的回收方法处理这个问题,因此尽可能避免使用短命的大对象。
3、设置对象进入老年代的年龄
在堆中每个对象都有自己的年龄,如果对象在 eden 区,经过一次 GC 后还存活,则被移动到 survivor 区中,对象年龄加 1,以后每经过一次 GC 依然存活的,对象年龄就加 1。当对象年龄达到阀值时,就移动到老年代,这个阀值用以下参数设置:
-XX:MaxTenuringThreshold:默认值是15,这个参数是指定进入老年代的最大年龄值,对象实际进入老年代的年龄是 JVM 在运行时根据内存使用情况动态计算的。
如果希望对象尽可能长地留在新生代中,可以设置一个较大的阀值。
4、稳定与震荡的堆大小
稳定的堆大小对垃圾回收是有利的,获得一个稳定堆大小的方法就是设置 -Xmx 和 -Xms 一样的值。不稳定的堆也不是木有用处,让堆大小在一个区间内震荡,在系统不需要使用大内存时压缩堆空间,使 GC 应对一个较小的堆,可以加快单次 GC 的速度。基于这种思想,JVM 提供了两个参数用于压缩和扩展堆空间,参数如下:
-XX:MinHeapFreeRatio:设置堆空间最小空闲比例,默认是 40 ,当堆空间的空闲比例小于这个值时,JVM 便会扩展堆空间
-XX:MaxHeapFreeRatio:设置堆空间的最大空闲比例,默认是 70,当堆空间的空闲比例大于这个值时,JVM 便会压缩堆空间,得到一个较小的堆
注意:当 -Xms 和 -Xmx 相等时,-XX:MinHeapFreeRatio 和 -XX:MaxHeapFreeRatio 这两个参数无效
5、吞吐量优先设置
机器配置是 4G 内存 和 32 核 CPU,配置参数如下:
OOM排查过程步骤 1、先查看应用进程号pid: ps -ef | grep 应用名 2、查看pid垃圾回收情况: jstat -gc pid 5000(时间间隔)
即会每5秒一次显示进程号为68842的java进成的GC情况,显示内容如下图:
结果说明:显示内容说明如下(部分结果是通过其他其他参数显示的,暂不说明):
S0C:年轻代中第一个survivor(幸存区)的容量 (字节) S1C:年轻代中第二个survivor(幸存区)的容量 (字节) S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节) S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节) EC:年轻代中Eden(伊甸园)的容量 (字节) EU:年轻代中Eden(伊甸园)目前已使用空间 (字节) OC:Old代的容量 (字节) OU:Old代目前已使用空间 (字节) PC:Perm(持久代)的容量 (字节) PU:Perm(持久代)目前已使用空间 (字节) YGC:从应用程序启动到采样时年轻代中gc次数 YGCT:从应用程序启动到采样时年轻代中gc所用时间(s) FGC:从应用程序启动到采样时old代(全gc)gc次数 FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s) GCT:从应用程序启动到采样时gc用的总时间(s) NGCMN:年轻代(young)中初始化(最小)的大小 (字节) NGCMX:年轻代(young)的最大容量 (字节) NGC:年轻代(young)中当前的容量 (字节) OGCMN:old代中初始化(最小)的大小 (字节) OGCMX:old代的最大容量 (字节) OGC:old代当前新生成的容量 (字节) PGCMN:perm代中初始化(最小)的大小 (字节) PGCMX:perm代的最大容量 (字节) PGC:perm代当前新生成的容量 (字节) S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比 S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比 E:年轻代中Eden(伊甸园)已使用的占当前容量百分比 O:old代已使用的占当前容量百分比 P:perm代已使用的占当前容量百分比 S0CMX:年轻代中第一个survivor(幸存区)的最大容量 (字节) S1CMX :年轻代中第二个survivor(幸存区)的最大容量 (字节) ECMX:年轻代中Eden(伊甸园)的最大容量 (字节) DSS:当前需要survivor(幸存区)的容量 (字节)(Eden区已满) TT: 持有次数限制 MTT : 最大持有次数限制 3、开启OOM快照: -XX:+HeapDumpOnOutOfMemoryError(开启堆快照)
tomcat启动的URL:
在自己的项目名称上,点右键,properties,web project settings,然后修改右边的context root,一般默认是项目名,但是,如果是复制别的项目工程,还是原来复制过来的项目名
maven工程:项目名称就是artifactId,即f2pdj,在哪里启动,就是哪里,不管是不是父子工程。还有,改的时候要小心,别把 标签里面的artifactId改错了,那就直接报错了
<groupId>com.thinkgem.jeesite</groupId> <!-- <artifactId>jeesite</artifactId> --> <artifactId>f2pdj</artifactId> <version>1.2.6</version> <packaging>war</packaging> 访问路径:
也就是指在浏览器中访问该web系统时的根路径,比如http://localhost:8080/xxxx/index.jsp 这里的xxxx,也就是request.getContextPath()得到的值。
我们在做系统开发的时候,在本地工作区可能会有同一个系统的多个版本存在,比如上面所说的xxxx系统,这里可能会有xxxx1、xxxx1_1、xxxx1_2代表该系统的1.0 、1.1、 1.2版本,对应的工程名字默认就是系统的访问路径,但是,我们可能会希望这些项目能够有一个统一的访问路径xxxx,这样向服务器部署的时候不管部署的是哪个项目,访问路径都是统一的。
在服务器部署的时候,比如tomcat,我们只需要修改对应的context.xml文件即可,属性对应的就是访问路径。
在Eclipse中,双击Server视图的Tomcat实例,如下:
我们可以看到在Server locations中有3个选项,在上图中选择的是第一个选项,这由Eclipse对tomcat的配置进行管理,对应的虚拟配置目录在图片中的Server Path一栏中。
我们可以去直接修改那个路径下的conf/server.xml文件,或者点击下面的Modules,在里面的web modules里进行修改各个项目的Path。其效果最终都是修改server.xml文件里Context的path内容
在Tensorflow中,使用Python,如何将张量(Tensor)转换为numpy数组呢?
最佳解决办法 由Session.run或eval返回的任何张量都是NumPy数组。
>>> print(type(tf.Session().run(tf.constant([1,2,3])))) <class 'numpy.ndarray'> 要么:
>>> sess = tf.InteractiveSession() >>> print(type(tf.constant([1,2,3]).eval())) <class 'numpy.ndarray'> 或者等同地:
>>> sess = tf.Session() >>> with sess.as_default(): >>> print(type(tf.constant([1,2,3]).eval())) <class 'numpy.ndarray'> 参考资料 How can I convert a tensor into a numpy array in TensorFlow? --------------------------------------------------------------------------------------------------------------------
https://vimsky.com/article/3725.html
原生小程序转Taro,Taro转多端 这里先讲一下需求,公司之前的小程序是用原生开发的,目前有客户需要同样的H5版本的项目,考虑短时间内开发出一个差不多100个页面左右的H5项目不太现实。所以这里就用到了Taro。
上链接:https://nervjs.github.io/taro/docs/taroize.html 原生小程序转Taro这一步的话还是比较简单的,按文档安装好Taro,npm或者cnpm都可以
npm i -g @tarojs/cli cnpm i -g @tarojs/cli 然后在小程序项目的根目录运行指令
$ taro convert 如果你小程序里面用到wxParse这个插件,会报错,文档也有写怎么解决报错。按文档中的解决就可以了。 这里讲一点转Taro的调试经验,有报错的文件先拎出来放在一边,因为es5,6语法差异,很多js文件转es6是不支持的,所以会报错,建议是先把所有报错的文件注释,或者改成es6写法再转。我这边是去掉了很多的文件才转成功了的。这里需要自己一步一步调试解决报错,转成功之后根目录多出来一个taroConvert的文件夹这说明已经转Taro成功了,接下来就是运行以及二次开发。 进入taroConvert文件夹(二次开发就在这个文件里面,小程序代码不用管了),执行命令 npm install 或者cnpm install 先拉取所有依赖。可以看一下package.json文件的运行命令以及安装的依赖,我这里是要运行H5的,输入命令 npm run dev:h5打开H5开发模式,这个步骤有可能会有个nerv.js不存在的报错,可以安装一下,然后在你文件src下面的的app.js import一下。
执行命令 import Nerv from 'nervjs',这个报错就会解决。其它的页面代码报错可以自己调试。开启成功的话浏览器中会打开127.0.0.1:8082的窗口运行项目。 先看下转taro之后的目录文件 这个是根目录,运行开发环境跟打包的命令都在这层执行。 这层就是跟小程序项目文件差不多的了,index.html是主入口文件,其它的跟小程序差不多,代码该在哪儿写就在哪儿写。 下篇再讲二次开发中的坑。
onchooseimage: function() {
var that = this;
wx.chooseImage({
count: 1, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function(res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
var tempFilePaths = res.tempFilePaths
wx.uploadFile({
url: app.globalData.url + '/api/home/uploads', //仅为示例,非真实的接口地址
filePath: tempFilePaths[0],
name: 'file',
formData: {
'user': 'test'
},
success: function(res) {
console.log("上传")
console.log(res);
//do something
var data = JSON.parse(res.data);
console.log(data);
imageUrl=data.data
}
})
that.setData({
tempFilePath: res.tempFilePaths
})
}
})
},
MySQL创建用户与授权 一. 创建用户 命令: CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 说明: username:你将创建的用户名host:指定该用户在哪个主机上可以登陆,如果是本地用户可用localhost,如果想让该用户可以从任意远程主机登陆,可以使用通配符%password:该用户的登陆密码,密码可以为空,如果为空则该用户可以不需要密码登陆服务器 例子: CREATE USER 'dog'@'localhost' IDENTIFIED BY '123456'; CREATE USER 'pig'@'192.168.1.101_' IDENDIFIED BY '123456'; CREATE USER 'pig'@'%' IDENTIFIED BY '123456'; CREATE USER 'pig'@'%' IDENTIFIED BY ''; CREATE USER 'pig'@'%'; 二. 授权: 命令: GRANT privileges ON databasename.tablename TO 'username'@'host' 说明: privileges:用户的操作权限,如SELECT,INSERT,UPDATE等,如果要授予所的权限则使用ALLdatabasename:数据库名tablename:表名,如果要授予该用户对所有数据库和表的相应操作权限则可用*表示,如*.* 例子: GRANT SELECT, INSERT ON test.user TO 'pig'@'%'; GRANT ALL ON *.* TO 'pig'@'%'; GRANT ALL ON maindataplus.* TO 'pig'@'%'; 注意: 用以上命令授权的用户不能给其它用户授权,如果想让该用户可以授权,用以下命令:
Yelp dataset原始数据集下载地址为:https://www.yelp.com/dataset/documentation/main
本人用到的两个数据集为yelp_photos.tar和yelp_dataset.tar,两个压缩包加一块大约10.3GB。
在GitHub上浏览基于yelp dataset数据集做的推荐系统项目时,发现人们用csv格式的数据集处理数据更加方便。而在GitHub上找到的json转csv的代码并不能达到理想转换效果,于是自己编写了jsontocsv_business.py和jsontocsv_review.py程序,此处贡献前者与大家交流学习。
import csv import json import sys import os import pandas as pd import numpy as np json_file_path='/home/yelp_dataset/business.json' csv_file_path='/home/yelp_dataset/business.csv' #打开business.json文件,取出第一行列名 with open(json_file_path,'r',encoding='utf-8') as fin: for line in fin: line_contents = json.loads(line) headers=line_contents.keys() break print(headers) #将json读成字典,其键值写入business.csv的列名,再将json文件中的values逐行写入business.csv文件 with open(csv_file_path, 'w', newline='',encoding='utf-8') as fout: writer=csv.DictWriter(fout, headers) writer.writeheader() with open(json_file_path, 'r', encoding='utf-8') as fin: for line in fin: line_contents = json.loads(line) if 'Phoenix' in line_contents.values(): writer.writerow(line_contents) # 删除state','postal_code','is_open','attributes'列,并保存 df_bus=pd.read_csv(csv_file_path) df_reduced=df_bus.
#include<stdio.h>
int main()
{
int shu;
scanf("%d",&shu);
if(shu < 30)
{
printf("%d",50 * shu);
}
else
{
printf("%d",48 * shu);
}
return 0;
}
mysql模块(项目地址为https://github.com/mysqljs/mysql)是一个开源的、JavaScript编写的MySQL驱动,可以在Node.js应用中来操作MySQL。但在使用过程中,出现了“ER_NOT_SUPPORTED_AUTH_MODE”问题。
本文介绍了出现该问题的原因及解决方案。
报错信息 当我试图使用mysql模块来连接MySQL 8时,出现了如下错误信息:
D:\workspaceGithub\nodejs-book-samples\samples\mysql-demo\index.js:17 throw error; ^ Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client at Handshake.Sequence._packetToError (D:\workspaceGithub\nodejs-book-samples\samples\mysql-demo\node_modules\mysql\lib\protocol\sequences\Sequence.js:47:14) at Handshake.ErrorPacket (D:\workspaceGithub\nodejs-book-samples\samples\mysql-demo\node_modules\mysql\lib\protocol\sequences\Handshake.js:123:18) at Protocol._parsePacket (D:\workspaceGithub\nodejs-book-samples\samples\mysql-demo\node_modules\mysql\lib\protocol\Protocol.js:291:23) at Parser._parsePacket (D:\workspaceGithub\nodejs-book-samples\samples\mysql-demo\node_modules\mysql\lib\protocol\Parser.js:433:10) at Parser.write (D:\workspaceGithub\nodejs-book-samples\samples\mysql-demo\node_modules\mysql\lib\protocol\Parser.js:43:10) at Protocol.write (D:\workspaceGithub\nodejs-book-samples\samples\mysql-demo\node_modules\mysql\lib\protocol\Protocol.js:38:16) at Socket.<anonymous> (D:\workspaceGithub\nodejs-book-samples\samples\mysql-demo\node_modules\mysql\lib\Connection.js:91:28) at Socket.<anonymous> (D:\workspaceGithub\nodejs-book-samples\samples\mysql-demo\node_modules\mysql\lib\Connection.js:525:10) at Socket.emit (events.js:196:13) at addChunk (_stream_readable.js:290:12) -------------------- at Protocol._enqueue (D:\workspaceGithub\nodejs-book-samples\samples\mysql-demo\node_modules\mysql\lib\protocol\Protocol.js:144:48) at Protocol.handshake (D:\workspaceGithub\nodejs-book-samples\samples\mysql-demo\node_modules\mysql\lib\protocol\Protocol.js:51:23) at Connection.connect (D:\workspaceGithub\nodejs-book-samples\samples\mysql-demo\node_modules\mysql\lib\Connection.js:119:18) at Object.<anonymous> (D:\workspaceGithub\nodejs-book-samples\samples\mysql-demo\index.js:12:12) at Module._compile (internal/modules/cjs/loader.
Ubuntu上打开docker的tcp访问 在使用systemd系统的linux操作系统中,默认docker daemon使用unix socket进行通信,如果需要使用tcp连接,让外部访问在不修改docker.service文件的前提下可以如下操作:
新建/etc/systemd/system/docker.service.d/startup_options.conf文件,并添加如下内容:
# /etc/systemd/system/docker.service.d/override.conf [Service] ExecStart= ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 重新载入服务信息 => sudo systemctl daemon-reload。
重启docker服务 => sudo systemctl restart docker.service。
转载于:https://my.oschina.net/taodf/blog/3061331
import numpy from sklearn import linear_model, decomposition, pipeline, model_selection, datasets pca = decomposition.PCA() logistic = linear_model.SGDClassifier('log') pipe = pipeline.Pipeline([('pca', pca), ('logistic', logistic)]) digit = datasets.load_digits() x = digit.data y = digit.target gs = model_selection.GridSearchCV(pipe, dict(pca__n_components=[5, 20, 30, 40, 50, 64], logistic__alpha=numpy.logspace(-4, 4, 5)), cv=5, n_jobs=-1, iid=False) gs.fit(x, y) print(gs.best_params_) print(gs.best_score_) pca.fit(x) import matplotlib.pyplot as plt plt.figure() plt.plot(pca.explained_variance_ratio_) plt.axvline(gs.best_estimator_.named_steps['pca'].n_components, linestyle=':') plt.show()
cross_val_score
import numpy from sklearn import svm, model_selection, datasets digit = datasets.load_digits() x = digit.data y = digit.target cs = numpy.logspace(-10, 0, 11) mean_scores = [] std_scores = [] for c in cs: scores = model_selection.cross_val_score(svm.SVC(kernel='linear', C=c), x, y, cv=10, n_jobs=-1) mean_scores.append(numpy.mean(scores)) std_scores.append(numpy.std(scores)) import matplotlib.pyplot as plt plt.figure() plt.semilogx(cs, mean_scores) plt.semilogx(cs, numpy.array(mean_scores)+numpy.array(std_scores), 'b--') plt.semilogx(cs, numpy.array(mean_scores)-numpy.array(std_scores), 'b--') plt.xlabel('C') plt.ylabel('score') plt.show() GridSearchCV import numpy from sklearn import svm, model_selection, datasets digit = datasets.
响应状态码 状态码类别 1xx Informational (信息性状态码) 接收的请求正在处理 2xx Success (成功状态码) 请求正常处理完毕 3xx Redirection (重定向状态码) 需要进行附加操作以完成请求 4xx Client Error(客户端错误状态码) 服务器无法处理请求 5xx Server Error(服务器错误状态码) 服务器处理请求出错 常见状态码 200:请求被正常处理 301:永久性重定向 302:临时重定向 401:请求需要认证 403:请求的对应资源禁止被访问 404:服务器无法找到对应资源 500:服务器内部错误 503:服务器正忙 转载于:https://www.cnblogs.com/wujinsheng/p/11010427.html
打开我的电脑
点击“更改文件夹和搜索选项”菜单
找到“隐藏文件夹合并冲突”一项,把其前面的勾选去掉,最后点击确定按钮
以后再复制文件的时候,替换或跳过文件询问窗口又显示出来了
java中smartbi的使用
1、修改知识库配置和替换授权文件
smartbi配置文件
smartbi授权文件 2、数据库建一张空表,启动项目后会生成170个表。
3、插件的配置
通过厂家提供的插件脚手架生成插件工程,目前只支持IE浏览器生成
需要修改的样式、图片都可以放在vision这个路径下。
Android 开发实践 Lambda表达式的使用 Java8 中着实引入了一些非常有特色的功能,如Lambda表达式、streamAPI、接口默认实现等等。Lambda表达式在 Android 中最低兼容到 Android2.3 系统,兼容性还是不错的,Lambda表达式本质上是一种匿名方法,它既没有方法名,也没有访问修饰符和返回值类型,使用它编写的代码将更加简洁易读。
1.Lambda表达式的基本写法 如果想要在 Android 项目中使用 Lambda表达式 或者 Java8 的其他新特性,首先我们需要安装Java8版本的JDK,然后在 app/build.gradle 中添加以下配置:
android { ... defaultConfig { jackOptions.enabled = true } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } 之后就可以开始使用Lambda表达式了:
比如使用Lambda表达式开启子线程的写法是:
// 传统方式 new Thread(new Runnable() { @Override public void run() { // 处理业务逻辑 } }).start(); // 使用Lambda表达式 new Thread(() -> { // 处理业务逻辑 }).start(); 不管是从代码行数上还是缩进结构上看,Lambda表达式的写法更加精简。为什么可以这么写呢?我们看一下 Runnable 接口的源码:
public interface Runnable { void run(); } 凡是这种只有一个待实现方法的接口,都可以使用 Lambda表达式的写法。
1、Zabbix服务端部署 1)关闭selinux(如果不关闭selinux的话,zabbix会找不到数据库的socket)
setenforcce 0 #临时关闭
vim /etc/selinux/config #永久关闭,需重启电脑
关闭防火墙 systemctl stop firewalld.service #临时关闭
systemctl disable firewalld.service #永久关闭
安装apache yum install -y httpd
systemctl enable httpd
systemctl start httpd
安装mysql(yum直接安装mariadb,方便快捷) yum install -y mariadb mariadb-server
systemctl enable mariadb #自启动
systemctl start mariadb #启动mysql,检查是否安装成功,命令行输入mysql
安装php环境 yum install -y php php-mysql php-fpm
vim /etc/php.ini
date.timezone = Asia/Shanghai
max_execution_time = 300
post_max_size = 32M
max_input_time = 300
memory_limit = 128M
systemctl start php-fpm #启动
1. 求开方
2. 大于给定元素的最小元素3. 有序数组的 Single Element4. 第一个错误的版本5. 旋转数组的最小数字6. 查找区间 正常实现
Input : [1,2,3,4,5] key : 3 return the index : 2 public int binarySearch(int[] nums, int key) { int l = 0, h = nums.length - 1; while (l <= h) { int m = l + (h - l) / 2; if (nums[m] == key) { return m; } else if (nums[m] > key) { h = m - 1; } else { l = m + 1; } } return -1; } 时间复杂度
/******************************************************************************************
* 版权声明
* 本文为本人原创,本人拥有此文的版权。鉴于本人持续受益于开源软件社区,
* 本人声明:任何个人及团体均可不受限制的转载和复制本文,无论是否用于盈利
* 之目的,但不得修改文章内容,并必须在转载及复制时同时保留本版权声明,否
* 则为侵权行为,本人保留追究相应主体法律责任之权利。
* speng2005@gmail.com
* 2019-6
******************************************************************************************/
Gflags是微软为windows平台调试应用程序堆内存错误(主要是内存溢出)的利器。
Gflags 官方参考:https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/gflags-commands
Gflags基本用法:
假设目标程序是testProject1.exe
cmd中执行命令:gflags.exe /p /enable testProject1.exe /full
可实现下次启动testProject1.exe时打开windows的堆内存跟踪器,只要应用程序内部出现堆缓冲区溢出操作,就会出现异常。但这个异常无法显示出来,程序员也不知道溢出操作发生时的调用栈。因此,需要在调试器中启动testProject1.exe才能捕获到错误的第1现场,找到调用栈从而定位代码错误源头。这有两种方法。
一种是待testProject1.exe启动后用调试器(例如vs2015)进行attach debug。
另一种是程序启动时自动打开调试器来运行testProject1.exe,可通过如下命令实现:
gflags.exe /p /enable testProject1.exe /full /debug vsjitdebugger.exe
Gflags运行原理
Gflags实际是继承了旧版windows的page heap功能,其实际作用是设置一些调试运行参数到系统注册表的如下路径(默认路径):
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\testproject1.exe
对于某些32位程序,则会设置到如下路径:
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\testproject1.exe
这其实是利用了windows的IFEO技术,也就是在启动exe执行前进行特殊的运行参数设置。当Gflags将用于heap跟踪的启动参数设置到注册表后,当用户要启动执行目标程序testproject1.exe时,操作系统自动设定相关运行参数,该参数将在ntdll.dll模块中被识别执行,如果ntdll.dll发现需要page heap功能,则会自动加载verifier.dll,该模块将正真执行page heap的实际处理逻辑。verifier.dll最重要的功能有两个:一是,在testproject1.exe调用free释放某块heap内存时,执行heap健康检查,如果testproject1.exe在之前使用该内存时发生了写溢出操作,哪怕是一个字节,则此时verifier.dll就可以检查出来,该模块会自动产生异常,由调试器捕获该异常供开发人员分析处理。但通常此时的调用栈只代表释放内存的代码,往往并不是产生错误溢出操作的根源代码。这时就需要verifier.dll的第二个重要功能,就是分配heap内存时进行特殊处理,让返回给用户的内存块的结尾处(也可以是开头处,参考Gflags的/backwards参数)对齐到一个os内存页的边界处,然后紧邻该内存的下一个(或前一个)内存页叫做full page。full page设置了特殊的页保护属性,其内存地址实际上并未commit给操作系统,当应用程序试图读或写该页上的内存地址时,哪怕是一个字节,将立刻触发os的内存访问异常,该异常会被调试器捕获,从而立刻显示试图对heap内存进行越界访问的第1现场的调用栈,供开发人员分析并修正代码问题。
Gflags使用中存在的问题
理论上Gflags用于排查heap内存越界访问问题非常有效,但在实际使用中存在很多问题。
一是,heap返回给用户的内存地址一般是按8字节对齐的,也就是说最少有8个字节的空闲内存区会返给用户。如果用户代码的内存溢出未超过8字节,则有可能无法触发full page的内存操作异常。虽然Gflags提供了/unaligned参数用于解决该问题,但实际使用发现在某些平台上无效。在win10上对testproject1.exe使用/unaligned参数时,会导致兼容性问题,进程直接就启动失败,根本无法跟踪调试。对于win7平台,/unaligned参数则是可用的。这应该是微软ntdll.dll和verifier.dll在win10上存在bug。如果不使用/unaligned参数,则可以启动程序。因为windows不开源,也没有资料描述该问题,故用户只能放弃该功能。
二是,对于某些稍复杂的第三方应用,在启用full page但不使用/unaligned参数时,仍然出现第三方应用启动失败的问题,原因未知,这导致full page实际上不可用。据猜测,这问题可能跟开启full page的条件下加载第三方应用的动态库,或者启动多线程有关。
三是,开启full page跟踪后会降低目标程序的运行性能,并会显著增加目标程序内存占用,因为即使只申请1个字节的内存,也要单独占用一个内存页,同时还要占用一个full page的地址空间,这可能会造成目标程序出现诡异现象。
Gflags高级用法
由于Gflags存在复杂应用无法正常启动问题,一个解决思路是:在应用启动阶段,暂时不要触发page heap的full page功能,这样应用就能按照普通方式正常启动起来,然后在需要的时候打开full page功能,用于跟踪可能存在的heap内存溢出问题。Gflags的官方资料中提供了/random,/size,/address,/dlls等参数,这些参数的作用都是条件启用full page功能,也就是在目标程序运行过程中,并不是所有的heap内存分配都启用full page功能,而是符合一定条件下才启用。观察这几个参数,都需要一定的线索,才知道用哪个合适。但实际上,第一次出现heap内存溢出问题时,往往没有线索。另外,这些参数也可能不好用,笔者试验了/dlls就发现有问题,目标程序启动失败。最要紧的是,这些参数都是在目标程序启动前设定,无法在目标程序启动后进行动态开关。对于前面应对复杂应用无法正常启动问题的解决思路,就是要让Gflags具有条件启用full page并且能动态开关的能力。仔细研究发现,在/random参数的基础上进行hacker,最符合目标方向,具体做法是(以testproject1.
插件默认的是将这些带有下划线的字段默认的组合在一起,比如 stu_name 变成 stuname 在配置文件中添加: <property name="useActualColumnNames" value="true" /> <table tableName="student" domainObjectName="Student" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" > <property name="useActualColumnNames" value="true" /> </table> 记住每个表对应一行,就搞定了!!!!
chmod -R 777 filename chown user filename chgrp user filename
创建一个cordova项目((项目名称:android-app app包名:com.test.app app名称:testapp) cordova create android-app com.test.app testapp 进入到新建的android-app文件夹中,添加安卓开发平台 cordova platform add android --save 创建一个react项目(报错请传送) creat-react-app app01 再进入到react工程目录 cd app01 在package.json中private下任意位置添加"homepage": "./"构建react项目 npm run build 构建后会在app01目录下生成build文件夹,将build文件夹中的所有文件全部复制到cordova项目android-app的www文件夹中进入到android-app文件夹中,构建cordova项目 cordova build android 如果命令行没错的话就会在cordova项目android-app\platforms\android\app\build\outputs目录下生成一个apk,把它安装到手机上就可以了(虚拟机一般会出现空白页面)
1.如果你点点点的话到了一个接口的话,就记住这个方法的名字。
2.找到接口的名字,前面加上 implements例如:implements ICharDevic。全局搜索。
3.看到可能会有很多的继承你可以大体的过滤一些,然后进去,在类中搜索你刚才记住的方法,这里应该是重写的。
4.打上断点,看看会不会有你想要的调用。就ok了。
前言 当以前后端分离的方式进行项目的开发时,我们可以简单地把前端开发看做页面展示的开发,把后端开发看做数据处理的开发。前端页面的展示,会根据需求去后端请求相应的数据。
后端是以URL的方式暴露接口来提供服务的,也就是说前端需要根据需求对应的URL组装http请求,去调用后端接口获取数据并将展示在页面上。前端项目的实际开发中,经常使用axios + promise来整合http请求。这篇博客就是对axios + promise整合http请求的相关知识点进行总结。
目录 Ajax相关知识点Promise相关知识点Axios相关知识点 Ajax相关知识点 AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。 AJAX 不是新的编程语言,而是一种使用现有标准的新方法。在不重新加载整个页面的情况下, AJAX 与服务器交换数据并更新部分网页的内容。
—参考自W3school的ajax教学
ajax的相关代码如下:
// 创建XMLHttpRequest对象 var request; if (window.XMLHttpRequest) { // IE7+和其他 request = new XMLHttpRequest(); } else { // IE6或IE5 request = new ActiveXObject("Microsoft.XMLHTTP"); } // 当http请求的状态发生变化时,会调用onreadystatechange()方法 request.onreadystatechange = function(){ // 当readyStatue = 4且status = 200时,表示http请求成功完成 if (request.readyState === 4 && request.status === 200) { // 获取http请求返回的字符串类型的响应文本 var response = request.
测试发现的问题及解决办法
1、当后端两台应用服务器都正常时,访问速度非常快,查看日志,原来一个请求,是后端两台服务器同时响应的;
2、为了模仿故障测试,停掉一台应用服务器,这时再访问,请求打开一页面时,发现有一半响应比较快,另一半响应很慢,最后页面是可以打开,但速度 不理想,很慢,查看error日志,发现nginx还是把请求的一半发往已停掉的那台服务器,难怪会这么慢;但当很快(10秒内)再打开一个请求页面时, 速度又非常快了,查看日志,发现nginx不会把请求的一半发往已停掉的那台服务器;过一会再发起一个请求时,又出现有一半响应比较快另一半响应很慢的现 象了,查看日志,nginx又把请求的一半发往已停掉的那台服务器;
3、到这里,我明白了nginx检查后端应用服务器的健康时是有一个时间间隔的,应该怎样处理这个问题呢,当后端有一台服务器down机时,用户访问感觉不出有慢的现象?原来在nginx负载均衡配置里加上下面两个参数时可以有效的解决这个问题:
upstream iisserver {
server 192.168.0.20:80 weight=5max_fails=2 fail_timeout=600s;
server 192.168.0.21:80 weight=5max_fails=2 fail_timeout=600s;
}
3.1)max_fails = NUMBER ---- 在一定时间内(这个时间在fail_timeout参数中设置)检查这个服务器是否可用时产生的最多失败请求数,默认为1,将其设置为0可以关闭检查,这 些错误在proxy_next_upstream或fastcgi_next_upstream(404错误不会使max_fails增加)中定义;
3.2)fail_timeout = TIME ---- 在这个时间内产生了max_fails所设置大小的失败尝试连接请求后这个服务器可能不可用,同样它指定了服务器不可用的时间(在下一次尝试连接请求发起 之前),默认为10秒,fail_timeout与前端响应时间没有直接关系,不过可以使用proxy_connect_timeout和 proxy_read_timeout来控制。
我设置当有2个请求失败,就表示后端的服务器不可用,在以后的600S时间内nginx不会再把请求发往已检查出标记为不可用的服务器,再次测试时,把 后端一台IIS应用服务务器停掉,只是有一个请求打开页面时出现上面的现象,以后10分钟内都不会出现了,请求页面打开速度正 常,fail_timeout的值可以根据你的实际情况而定。
转载于:https://www.cnblogs.com/stj123/p/11004041.html
Caused by: com.android.builder.internal.aapt.v2.Aapt2Exception: Android resource linking failed
E:\git_code\helloapp\app\src\main\res\layout\activity_main.xml:2: error: resource color/green (aka com.wm.helloapp:color/green) not found.
E:\git_code\helloapp\app\src\main\res\layout\activity_main.xml:9: error: resource color/white (aka com.wm.helloapp:color/white) not found.
在res/values/colors.xml里加
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#008577</color> <color name="colorPrimaryDark">#00574B</color> <color name="colorAccent">#D81B60</color> <color name="red">#FF0000</color> <color name="green">#4CAF50</color> <color name="white">#FFFFFF</color> </resources>
方法一:找到workspace文件夹,将旧工作空间中的“.metadata”文件夹拷贝到新空间中。
方法二:打开Eclipse,选择路径新建立的工作空间,左上角File→Switch Workspace→Other…
点开Copy Settings 只需在Workbench Layout前打钩(Working Sets前不需要),点击确认即可
。
方法三:一劳永逸的方法,就是在方法一或者方法二建好之后不建立新的项目,即是一个干净的工作空间,将其作为模板,若要新建工作空间,只需将其拷贝一份即可。
使用spring boot 整合 redis Redis 安装
liunx 下
拉取官方的镜像,下载
docker pull redis 查看一下是否成功:
docker images 启动rides镜像
docker run -p 6379:6379 -d redis:latest redis-server 然后使用spring boot 整合 redis
/** 架包依赖*/ <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> application.yml spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/test?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT username: root password: root redis: host: 192.168.139.129 #服务器地址 port: 6379 #服务器端口 database: 1 # Redis数据库索引(默认为0) 密码之类的 默认是没有的可以写 logging: level: com.jianglin.demo_redis.dao: debug # 打印SQL语句 这就不详细写实体类了 dao层 @Mapper public interface StudentMapper { @Select("
在虚拟机centos7开发vue,然后打包到win7,先安装nginx,在nginx for window可以下载最新版,解压nginx-1.17.0,文件夹名称改为nginx
1方法可以点击nginx.exe启动
2方法可以在cmd里
启动时会突然弹出个小黑屏,就消失了,表示启动成功了
可以conf看到默认的端口和localhost,我改成88
打开浏览器
nginx其他命令
start nginx 开启nginx
nginx -s stop 快速关闭Nginx,可能不保存相关信息,并迅速终止web服务。
nginx -s quit 平稳关闭Nginx,保存相关信息,有安排的结束web服务。
nginx -s reload 因改变了Nginx相关配置,需要重新加载配置而重载。
nginx -s reopen 重新打开日志文件。
nginx -c filename 为 Nginx 指定一个配置文件,来代替缺省的。
nginx -t 不运行,而仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件。
nginx -v 显示 nginx 的版本。
然后部署vue项目,在D下存放打包好的dist文件
在nginx.conf加入下面,可以跨域访问远程服务器的数据
在浏览器输入http://localhost:8888/就成功了
至于apache部署vue项目 参考网上的貌似不行,继续加油~
但是当按下F5或者刷新页面时就出现如下404错误 解决方法 try_files $uri $uri/ /index.html last;
1.运算放大器工作原理综述:
运算放大器组成的电路五花八门,令人眼花瞭乱,在分析运算放大器工作原理时倘没有抓住核心,往往令人头大。本文收集运放电路的应用电路,希望看完后有所收获。但是在分析各个电路之前,还是先回忆一下两个运放教材里必教的技能,就是“虚短”和“虚断”。
“虚短”是指在分析运算放大器处于线性状态时,可把两输入端视为等电位,这一特性称为虚假短路,简称虚短。显然不能将两输入端真正短路。
“虚断”是指在分析运放处于线性状态时,可以把两输入端视为等效开路,这一特性 称为虚假开路,简称虚断。显然不能将两输入端真正断路。
2.运算放大器工作原理经典电路图一
图一运算放大器的同向端接地=0V,反向端和同向端虚短,所以也是0V,反向输入端输入电阻很高,虚断,几乎没有电流注入和流出,那么R1和R2相当于是串联的,流过一个串联电路中的每一只组件的电流是相同的,即流过R1的电流和流过R2的电流是相同的。流过R1的电流I1 = (Vi - V-)/R1 ……a 流过R2的电流I2 = (V- - Vout)/R2 ……b V- = V+ = 0 ……c I1 = I2 ……d 求解上面的初中代数方程得Vout = (-R2/R1)*Vi 这就是传说中的反向放大器的输入输出关系式了。
3.运算放大器工作原理经典电路图二
图二中Vi与V-虚短,则 Vi = V- ……a 因为虚断,反向输入端没有电流输入输出,通过R1和R2 的电流相等,设此电流为I,由欧姆定律得: I = Vout/(R1+R2) ……b Vi等于R2上的分压, 即:Vi = IR2 ……c 由abc式得Vout=Vi(R1+R2)/R2 这就是传说中的同向放大器的公式了。
4.运算放大器工作原理经典电路图三
图三中,由虚短知: V- = V+ = 0 ……a 由虚断及基尔霍夫定律知,通过R2与R1的电流之和等于通过R3的电流,故 (V1 – V-)/R1 + (V2 – V-)/R2 = (Vout – V-)/R3 ……b 代入a式,b式变为V1/R1 + V2/R2 = Vout/R3 如果取R1=R2=R3,则上式变为Vout=V1+V2,这就是传说中的加法器了。
exists 的用法 select * from t where t.deptId in (select id from s) 等于
select * from t where exists (select 1 from s where s.id=t.deptId)
order by 慢日志查询( show global status like '%Slow_queries%';查询系统慢查询数量 ) 一般默认关闭,需要分析调优才开启
show VARIABLES like '%slow_query_log%';
set global slow_query_log=1;
设置记录阈值(默认10s,大于10s的查询会被记录到日志文件)
show VARIABLES like 'long_query_time%';
set global long_query_time=3;
当重启mysql,慢日志配置失效,永久生效参考:
mysqldumpslow分析慢日志(在linux命令运行)
mysqldumpslow -s r -t 10 /www/server/data/mysql-slow.log(得到返回记录集最多的10个SQL)
mysqldumpslow -s c -t 10 /www/server/data/mysql-slow.log(得到访问次数最多的10个SQL)
mysqldumpslow -s t -t 10 -g "
git看一个历史版本的某个文件.md
git show HEAD~4:index.html
冒号前后没有空格
下载(注:flink需要jdk版本在8.x之上):
https://flink.apache.org/downloads.html
下载Apache Flink 1.x.x for Scala 2.11 (asc, sha512),本地解压运行
进入解压目录的bin目录,运行start-cluster.bat,启动成功后本地访问http://localhost:8081执行一个程序 D:\software\flink-1.8.0-bin-scala_2.11\flink-1.8.0\bin>flink.bat run ../examples/batch/WordCount.jar 在页面的Running Jobs下面可以看到有一个任务在运行,这个任务执行的比较快,有可能看不到;
但是在Completed Jobs下面可以看到有一个已完成任务
如果想要这个任务执行的慢一点,可以修改input选项,自己做一个大一点的文件来运行
D:\software\flink-1.8.0-bin-scala_2.11\flink-1.8.0\bin>flink.bat run ../examples/batch/WordCount.jar -input ../examples/ batch/test.txt 此时可以看到Running Jobs下有任务运行
前言: 一般来说,移动开发者不会单独来配置Dart开发环境,因为Flutter的环境已经包括了它。这里我们是抛开Flutter单独学习一下Dart语言,而且大家要知道的是Flutter只是它的一个应用方向而已,还有其他很多方向,诸如后端等等,因为我是移动开发者,所以其他方向我就不多关注了,大家有兴趣可以去Dart官网看看。配置Dart比Flutter要简单很多,坑也很少。下面看看具体步骤吧。
一,下载SDK: 不管学习什么语言,或者框架。我们第一步总是先要下载它的SDK,不仅仅是使用它的API,而且你可以阅读它的源码。来学习它的编程思想。由于我使用的是Windows系统。所以我这里主要介绍在Windows环境下的安装,而其他环境大家可以参考官方文档:
1.通过使用Chocolatey工具执行指令安装 在安装前要给大家说的是Dart SDK分为稳定版和开发版,我们这里要使用开发版也就是Dev版本。
2,通过下载SDK压缩包来安装 笔者采用的就是这种方式,如果大家不想下载工具的话,我推荐使用这种方式,简单快捷。上面这种方式肯定会有些小伙伴多少遇到点问题的,在安装之前大家选择自己喜欢的一个文件夹来存放SDK,好了下面我给出下载地址,至于安装一直下一步就行了:
Windows环境压缩包下载地址:http://www.gekorm.com/dart-windows/Linux/Mac环境压缩包下载地址:http://www.dartdoc.cn/tools/sdk/archive/ 二,IDE选择配置: IDE(编译器)的选择有很多,包括AndroidStudio,Intellij,VSCode,Sublime Text等等,配置方面都大同小异,都是要装Dart插件。笔者采用的是VSCode,因为只是学习语法,就不需要动用AS了,后面学习Flutter我们再用它,这里我默认大家已经下载安装好了VSCode,这个可比AndroidStudio简单太多了,好了,下面上图:
首先有部分小伙伴可能使用的中文汉化版本的VSCode,如果是这样可能最左边红圈选项可能没有,这时候你需要把VSCode更新到最新版本,具体是在help菜单下倒数第二个选项执行更新,之后应该就和我一样,这里提醒大家作为一个开发者我们还是尽量使用原生版本吧,这样对你更有好处。图中过程很清楚了,由于我已经安装好了,所以没有出现绿色install按钮,大家只需要点击安装就行,除了Dart插件,VSCode中要想运行项目还需下载一个Code Runner插件,步骤和上面一样,可能有些小伙伴以前就用过,好了,全部安装好后重启VSCode即可。下面最后一步大家还得配置一下环境变量。
三,配置环境变量: 具体在哪配置,只有小白会问这种问题吧。好吧,给你说一下,在桌面找到我的电脑右击鼠标选中属性,注意这也是Windows环境下,其他环境自己百度吧,点击高级系统设置,再找到环境变量,只需给系统变量设置就行,用户变量只适用于当前你这个Windows账户,好了配置下面两个变量,如果没有则新建:
Path:D:\2019Learn\dart\sdk\Dart\dart-sdk\bin;(这是笔者的SDK路径,这里替换成你自己的,要选择到bin的目录)DART_SDK:D:\2019Learn\dart\sdk\Dart\dart-sdk(替换成你的路径) 这样配置完以后,注意一点,每一个路径前后要用分号隔开,好了快捷键Windows+R打开cmd控制台输入dart --version回车如果是下面这样就意味配置成功:
好了,通过上面三大步骤,你已经正式进入Dart的世界了,以后就可以使用VSCode来进行demo练习了。希望你能爱上这门语言
以上!
js代码
function initEchars(){ var myChart3 = echarts.init(document.getElementById('table2left')); var option3 = { tooltip: { trigger: 'item', formatter: '{a}<br/>{b}:{c}' }, dataRange: { show:false, min: 0.5, max: 17.1, x: 'left', y: 'bottom', text:['高','低'], // 文本,默认为数值文本 calculable : true, color: ['#EE4000','lightskyblue','#9F79EE','lightskyblue'], textStyle :{color: '#FFFFFF'} }, series : [ { name: '安徽', type: 'map', mapType: '安徽', hoverable: true, dataRangeHoverLink: true, zoom: 1.2, selectedMode : 'single', // 同时只能一块区域变色 label:{ //显示各地方名称 normal:{ show:true, textStyle:{ color:'#101010', fontSize:12, // fontWeight:'bold', }, // formatter:function(d){return d.
socket 编程 套接字概念
Socket本身有“插座”的意思,在Linux环境下,用于表示进程间网络通信的特殊文件类型。本质为内核借助缓冲区形成的伪文件。既然是文件,那么理所当然的,我们可以使用文件描述符引用套接字。与管道类似的,Linux系统将其封装成文件的目的是为了统一接口,使得读写套接字和读写文件的操作一致。区别是管道主要应用于本地进程间通信,而套接字多应用于网络进程间数据的传递。
在TCP/IP协议中,“IP地址+TCP或UDP端口号”唯一标识网络通讯中的一个进程。“IP地址+端口号”就对应一个socket。欲建立连接的两个进程各自有一个socket来标识,那么这两个socket组成的socket pair就唯一标识一个连接。因此可以用Socket来描述网络连接的一对一关系。
套接字通信原理如下图所示:
网络字节序
我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分。网络数据流同样有大端小端之分,那么如何定义网络数据流的地址呢?TCP/IP协议规定,网络数据流应采用大端字节序,即低地址存高字节,高地址存低字节。
为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。
#include <arpa/inet.h> uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort); //h表示host,n表示network,l表示32位长整数,s表示16位短整数。 //如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回,如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。 ip地址转换函数
只能处理IPv4的ip地址
不可重入函数
注意参数是struct in_addr
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int inet_aton(const char *cp, struct in_addr *inp); in_addr_t inet_addr(const char *cp); char *inet_ntoa(struct in_addr in); 支持IPv4和IPv6
可重入函数
其中inet_pton和inet_ntop不仅可以转换IPv4的in_addr,还可以转换IPv6的in6_addr。
#include <arpa/inet.h> int inet_pton(int af, const char *src, void *dst); const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); 网络套接字函数 socket模型流程图
一、键盘 1.虚拟键码:Windows系统下所有的按键被视为虚拟键(包含鼠标在内),每一个虚拟键都有其对应的虚拟键码;
2.键盘消息
(1)VM_KEWDOWN:按下按键消息;
(2)VM_KEYUP :松开按键消息;
(3)VM_CHAR :字符消息,当按下的按键为定义于ASCII码中的可打印字符时,便发出此字符消息;
3.系统键
(1)VM_SYSKEYDOWN:按下系统键消息;
(2)VM_SYSKEYUP :松开系统键消息;
二、键盘消息处理 1.LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
(1)wParam:表示按下按键的虚拟键码;
(2)lParam :存储按键的相关状态信息;
三、利用键盘上、下、左、右控制人物 1.首先设置人物的起始贴图坐标和起始方向,用0、1、2、3表示上、下、左、右,起始设为0;
2.初始化函数中,除贴背景图外,根据方向选择要贴的人物,还有根据方向判断人物图的宽和高,以便进行透明处理和贴图
操作,此时若没有按键操作,WinMain函数将每隔一段时间进行贴图操作,从而实现了人物的原地跑动;
3.若此时按下向下的按键,消息处理函数接收按键消息,接着要判断当前人物所处的方向,根据不同的方向,适当修正,只要有
明显下移就可以,然后判断y的值不能比地图的高还大,要设临界值;
4.更改了贴图坐标后,把方向设为1(下是1),然后就去指向绘图函数,然后又是重复2的操作;
四、效果 五、代码如下 #include "stdafx.h" #include <stdio.h> HINSTANCE hInst; HBITMAP girl[4],bg; HDC hdc,mdc,bufdc; HWND hWnd; DWORD tPre,tNow; int num,dir,x,y;//num:连续图中的小图编号;dir:人物移动的方向;x,y为人物贴图坐标 ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void MyPaint(HDC hdc); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; MyRegisterClass(hInstance); if (!
那些年我躺过的配置坑 在webpack的配置过程中,由于对新版本的憧憬,所以一开始就摒弃了老师所用的旧版本,毅然决然安装上了4.0版本。。。从我安装上他的那一刻,我注定要一路踩雷的走下去。
第一个兼容问题就是在4.0版本以上,webpack和webpack-cli是分开安装,但又是相互依赖的。所以,以往3.0版本的直装版在这里并不通用。所以,请在你的项目里为他们留出两个坑。
以上是当前时间,我所更新的最新版插件,对webpack@4.0版本支持良好。但是由于在实际的使用中,出现的难以查找的小bug让我头疼。
在今天果断将其退回3.8.1版本,之前堵塞的类型call问题烟消云散。
把我的package.json文件贴在这里,后续使用时自取。
{ "name": "wp-study", "version": "2.0.0", "description": "rollback 3", "main": "main.js", "scripts": { "test": "npm test", "dev": "webpack-dev-server" }, "author": "platonic", "license": "ISC", "devDependencies": { "ajv": "^6.9.1", "css-loader": "^0.28.7", "file-loader": "^1.1.5", "html-webpack-plugin": "^2.30.1", "less": "^2.7.3", "less-loader": "^4.0.5", "node-sass": "^4.5.3", "sass-loader": "^6.0.6", "style-loader": "^0.19.0", "url-loader": "^0.6.2", "webpack": "^3.8.1", "webpack-dev-server": "^2.9.3" } } 以下为webpack.config.js配置文件
const path = require("path") const webpack = require("webpack") const htmlWebpackPlugin = require("html-webpack-plugin") module.
一、基本思路 1.现在有三张背景图:天空和草地、山峦、房屋;
2.天空在最远处,其次是草地和山峦(因为山峦在草地上),最后是房屋;
3.背景的循环速度是天空最慢、然后是山峦、最后是草地和房屋;
4.恐龙让它原地跑动,以num记录图号,每次到末尾号,再从第0号开始;
二、背景循环贴图 1.以天空为例,设x0表示背景图从左向右滚动右边需要切割的宽度,初值为0;
2.设背景图宽度640,裁剪的右边区域的左上角坐标为:(640-x0,0),把该区域贴到mdc以(0,0)为起点的坐标区域上;
3.然后把天空图剩下的部分贴到mdc中以(x0,0)为起点的坐标上;
4.假设每次x0增加5,每次贴图就实现了背景图的移动,直到x=640时,再重新设为0;
5.需要注意,山峦和房屋除了实现循环外,还要进行透明处理;
三、代码如下 #include "stdafx.h" HINSTANCE hInst; HBITMAP dra,bg[3]; HDC hdc,mdc,bufdc; HWND hWnd; DWORD tPre,tNow; int x0=0,x1=0,x2=0,num=0;//x0、x1、x2三张背景图由左向右移动时所要切割的宽度;num表示图号 ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void MyPaint(HDC hdc); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; MyRegisterClass(hInstance); if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } while( msg.message!=WM_QUIT ) { if( PeekMessage( &msg, NULL, 0,0 ,PM_REMOVE) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else { tNow = GetTickCount(); if(tNow-tPre >= 100) MyPaint(hdc); } } return msg.
在 ios 开发中,类也是一个对象,我们称之为类对象, 所有对象中,包含实例对象和类对象,都含有一个isa 指针。实例对象的isa指针, 指向他的类对象,类对象的isa 指针, 指向他的元类。系统判断一个对象属于哪个类,也是通过这个对象的isa指针的指向来判断。对象中的成员变量,存储在对象本身,对象的实例方法,存储在他的isa 指针所指向的对象中,即:减号方法,存储在类对象中,类方法,存储在类对象isa所指向的元类中,成员变量的值,储存在对象中。
对象在调用减号方法的时候,系统会在对象的isa指针所指向的类对象中寻找方法,这一段在kvo的实现原理中就能看到,kvo的实现原理就是系统动态的生成一个类对象,这个类是监听对象的类的子类,在生成的类中重写了监听属性的set方法,实现对set方法的监听,之后将监听对象的isa指针指向系统动态生成的这个类,当监听对象调用set方法时,由于监听对象的isa指针指向的是刚刚动态生成的类,所以在其中找的的set方法也是重写过有监听功能的set方法,这就是kvo的实现原理。同理,我们也可以通过rutime中的方法设置某个对象isa指针指向的类对象,让对象调用一些原本不属于他的方法。可以,但没必要。
下面附上isa指针指向图
设二叉树以二叉链表形式存放,用类C语言设计非递归算法判断一棵根结点为T的二叉树是否为二叉排序树。
可以参考二叉树中序遍历的非递归算法
非递归算法如下:
int InOrderTraverse(BiTree T) { BiTree p; p=T; while(p||!StackEmpty(S)) { if(p) { Push(S,p); if(p->data>p->lchild->data) p=p->lchild; else return 0; } else { Pop(S,p); cout<<p->data<<" "; if(p->data<p->rchild->data) p=p->rchild; else return 0; } } return 1; } 递归算法附给大家一个链接:
判定二叉树为二叉排序树的递归算法
一 产品经理做APP从头到尾的所有工作流程详解! - eickandy的专栏 - CSDN博客
https://blog.csdn.net/eickandy/article/details/80294224
二 产品经理的六大工作职责一个人的成熟的标志之一,就是心中可以容纳互相矛盾的观点而无碍行事——当大家觉得我发的是狗屎的时候可以看看上面这句话_!
**
产品经理的六大工作职责 **
1、市场调研:
2、产品定义及设计:
3、项目管理:
4、产品宣介:
5、产品市场推广
6、产品生命周期管理
作者:Ranslong
链接:https://www.jianshu.com/p/f75038d30d87
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。