前言
经过前面几章,我们的网站已经最基本的功能,接下来就是继续拓展其他的功能,这期一起来实现一个该网站流量分析的工具,统计出这个网站每天用户相关数据,不仅要满足了我们对流量统计数字的基本要求,并且用更简单的图形显示方式,让我们一目了然地获取页面热度、点击率信息等等。有了这个想法以后,那怎么实现呢,跟着笔者一步步来吧。
首先,需要考虑怎么才能获得用户访问网站时的相关数据呢?我们没必要自己去记录这些信息,目前已经有很多成熟的解决方案,提供捕获这些信息的免费接口,我们只用去访问这些接口就可以了。
在众多的方案中,有2款目前是比较流行的,分别是google analytics和百度统计。怎么说呢,google的确实是行业的大牛,不仅很成熟,而且有详尽的技术文档,数据收集过程很顺利,但是数据呈现需要fanqiang(原因你们懂得),这块是硬伤,一个开放的网站没法要求用户都要fanqiang吧,也是由于这个原因,让我忍痛放弃了google analytics。那只有一个选择了:百度统计。想比较而言,百度统计的相关技术文档不忍多说,都是泪,笔者在坑中摸爬滚打很久,才弄明白怎么调用和访问。
方案定下来,因为我们要访问百度统计的开放API,以后会经常调用到外网的各种API,为了磨刀不费砍柴工,我们开发一个API的模拟工具,用来调试。
API模拟工具
单独给API模拟工具增加一个菜单项,菜单管理-->新增菜单,增加一个根节点菜单下的一个子菜单:“工具箱”。以后一些常用的开发工具菜单,就放置该目录,然后在“工具箱”菜单下,再新建一个子菜单:“API模拟”。
那C#中怎么调用远程API方法呢,一般用HttpClient可以访问,这里我们稍微再封装一下,分为Get请求(传递url参数)和Post请求(传递url和content参数):
1 public static class HttpClientExtensions
2 {
3 ///
4 /// Get请求API
5 ///
6 ///
7 ///
8 ///
9 ///
10 ///
11 public static async Task<string > HttpGetAsync(this HttpClient client, string url)
12 {
13 // 初始化内容
14 var responseMessage = await client.GetAsync(url);
15 if (responseMessage.IsSuccessStatusCode)
16 {
17 return await responseMessage.Content.ReadAsStringAsync();
18 }
19 else
20 {
21 return $" 访问API地址:{url}出错,错误代码:{responseMessage.StatusCode},错误原因:{responseMessage.ReasonPhrase} " ;
22 }
23 }
24
25
26 ///
27 /// Post请求API
28 ///
29 ///
30 ///
31 ///
32 ///
33 ///
34 public static async Task<string > HttpPostAsync(this HttpClient client, string url, string jsonValue)
35 {
36 // 初始化内容
37 var content = new StringContent(jsonValue, Encoding.UTF8, " application/json " );
38
39 var responseMessage = await client.PostAsync(url, content);
40 if (responseMessage.IsSuccessStatusCode)
41 {
42 return await responseMessage.Content.ReadAsStringAsync();
43 }
44 else
45 {
46 return $" 访问API地址:{url}出错,参数:{jsonValue},错误代码:{responseMessage.StatusCode} ,错误原因:{responseMessage.ReasonPhrase} " ;
47 }
48 }
参考上一章的内容中,我们将Api的相关配置,比如url地址,url请求类型,参数等等,都配置到json文件中,并定义相应的数据结构MyRequest。后续依赖注入IOptions myRequest即可访问。
Areas/Tools/Controllers创建对应的控制器ApiSimulatorController
InvokApi方法:根据读取的Api请求类型,想远程API服务商发送请求并传递参数,返回json格式给UI端;
Index方法:根据用户在下拉框中选择的Api,切换显示Api相关信息;
1 [Area(" Tools " )]
2 public class ApiSimulatorController : AppController
3 {
4 private readonly MyRequest _myRequest;
5
6 public ApiSimulatorController(IOptions myRequest)
7 {
8 _myRequest = myRequest.Value;
9 }
10
11 ///
12 /// API模拟主页
13 ///
14 ///
15 ///
16 public IActionResult Index(string selectedApiCode = null )
17 {
18 UpdateDropDownList(selectedApiCode);
19 if (selectedApiCode == null )
20 {
21 return View(" Index " , new ApiRequest());
22
23 }
24 var selectedApi = _myRequest.ApiRequests.FirstOrDefault(s => s.ApiCode == selectedApiCode);
25 if (selectedApi != null && selectedApi.Methord == " POST " )
26 selectedApi.ApiDatas = selectedApi.ApiDatas.ToJsonString();
27 return View(" Index " , selectedApi);
28 }
29
30 ///
31 /// 调用API
32 ///
33 ///
34 ///
35 public async Task InvokApi(ApiRequest request)
36 {
37 var hc = new HttpClient();
38
39 if (request.Methord == " GET " )
40 {
41 var getUrl = request.Url + " ? " ;
42 foreach (var para in request.ApiParas)
43 {
44 getUrl += " & " + para.ParaName + " = " + para.ParaValue;
45 }
46
47 ViewBag.SendContent = getUrl;
48 ViewBag.ReturnResult = (await hc.HttpGetAsync(getUrl)).ToJsonString();
49 }
50 else if (request.Methord == " POST " )
51 {
52 if (!string .IsNullOrEmpty(request.ApiDatas))
53 {
54 ViewBag.SendContent = request.Url;
55 ViewBag.ReturnResult = (await hc.HttpPostAsync(request.Url, request.ApiDatas)).ToJsonString();
56 }
57 else
58 {
59 ModelState.AddModelError(string .Empty, " 请输入Json格式请求参数 " );
60 }
61 }
62 else
63 {
64 ModelState.AddModelError(string .Empty, " 请求方式非法 " );
65 }
66
67 UpdateDropDownList(request.ApiCode);
68 return View(" Index " , request);
69 }
70
71 ///
72 /// 初始化下拉选择框
73 ///
74 private void UpdateDropDownList(string selectedApiCode = null )
75 {
76 List listApiName = new List();
77 foreach (var request in _myRequest.ApiRequests.Select(s => new { s.ApiName, s.ApiCode }))
78 {
79 listApiName.Add(new SelectListItem
80 {
81 Value = request.ApiCode,
82 Text = request.ApiName,
83 Selected = request.ApiCode == selectedApiCode
84 });
85 }
86 ViewBag.ApiCodes = listApiName;
87 }
88 }
Areas/Tools/Views创建对应的视图Index
1 < div class ="form-group" >
2 < label asp-for ="ApiCode" > API名称:label >
3 < select asp-for ="ApiCode" class ="form-control input-sm select2" asp-items ="ViewBag.ApiCodes" >
4 < option value ="" > -- 请选择 --option >
5 select >
6 div >
7 < div class ="form-group" >
8 < label asp-for ="Url" > API地址:label >
9 < input asp-for ="Url" class ="form-control input-sm" readonly >
10 div >
11 < div class ="form-group" >
12 < label asp-for ="Methord" > 请求方式:label >
13 < input asp-for ="Methord" class ="form-control input-sm" readonly >
14 div >
15 < div class ="form-group" >
16 < label for ="params" class ="" > 请求参数:label >
17 @if (Model.Methord == "GET")
18 {
19 < div style ="overflow-x:auto;" >
20 < table class ="table table-bordered table-striped table-condensed" id ="params" >
21 < thead >
22 < tr >
23 < td > 参数名td >
24 < td > 类型td >
25 < td > 是否必填td >
26 < td > 说明td >
27 < td > 值td >
28 tr >
29 thead >
30 < tbody >
31 @for (var i = 0; i < Model .ApiParas.Count(); i++)
32 {
33 >
34 < td >
35 < span > @Model.ApiParas[i].ParaNamespan >
36 @Html.TextBoxFor(a => a.ApiParas[i].ParaName,
37 new { @class = "form-control input-sm", type = "hidden" })
38 td >
39 < td >
40 < span > @Model.ApiParas[i].ParaTypespan >
41 @Html.TextBoxFor(a => a.ApiParas[i].ParaType,
42 new { @class = "form-control input-sm", type = "hidden" })
43 td >
44 < td >
45 < span > @(Model.ApiParas[i].Required ? "是" : "否")span >
46 @Html.TextBoxFor(a => a.ApiParas[i].Required,
47 new { @class = "form-control input-sm", type = "hidden" })
48 td >
49 < td >
50 < span > @Model.ApiParas[i].Descriptionspan >
51 @Html.TextBoxFor(a => a.ApiParas[i].Description,
52 new { @class = "form-control input-sm", type = "hidden" })
53 td >
54 < td >
55 @Html.TextBoxFor(a => a.ApiParas[i].ParaValue,
56 new { @class = "form-control input-sm" })
57 td >
58 tr >
59 }
60 tbody >
61 table >
62 div > }
63 else if ((Model.Methord == "POST"))
64 {
65 @Html.TextAreaFor(m => m.ApiDatas,
66 new { @class = "form-control", rows = "8", placeholder = "输入Json格式 ..." })
67 }
68 div >
69 < button type ="submit" class ="btn btn-success" >< i class ="fa fa-send-o margin-r-5" > i > 发送请求button >
json文件中增加“手机号码归属地”、“百度统计”相关API的配置,我们来测试一下:
流量分析工具
有了上面API模拟工具,现在可以很方便的调试我们百度统计接口了。百度统计是怎么获取这些网站用户访问的相关信息的呢?原理其实很简单,百度针对你的注册服务提供一段js代码,其中包含标识你在百度统计的id。你在网页中添加这段代码后,每当用户访问该网站时,会下载这段js脚本,加载完毕和离开页面的时候,都会发送一次请求和传递参数,百度统计服务中心从而捕获到这些信息,维护在服务器中。调用百度统计API传递你的id,会根据id返回你的网站对应分析数据。
关于流量统计原理,有兴趣详见揭秘百度统计和Google Analytics的工作原理
注册百度统计
知道了原理,那首先第一步我们注册百度统计用户。注册完成后,我们找到 代码管理-->代码获取,将百度统计帮你自动生成好的js脚本复制过来,粘贴到site.js文件中。由于_layout母版页引用了site.js文件,这样的话,网站域名下所有的用户访问,都会被统计。
安装完百度统计的代码,发布网站程序,可以用百度统计中代码检查,看看自己统计代码有没有被正确的安装,如果安装成功,估计20分钟后,就可以在百度统计中查看网站的访问情况了。当然,你也可以添加多个域名的网站。
申请Tongji API数据导出
现在我们很方便的在百度统计中查看各种统计数据了,比如流量分析、来源分析、访问分析、转化分析等等,接下来需要获取这些数据,来移植到我们自己的网站中来。百度提供了Tongji API,我们可以调用API来查询自己网站的分析数据,从而进一步组织增加的分析视图了。
要访问Tongji API,需要提供一个token值,这个需要开通申请,在 百度统计-->管理-->其他设置-->数据导出服务 中,请求开通,开通后百度统计会提供给你一个token字符串,以后用这个token就可以访问Tongji API。Tongji API具体的请求格式说明详见:百度统计开发平台
比如我们需要请求站点列表,使用API模拟工具,请求类型POST,url地址:https://api.baidu.com/json/tongji/v1/ReportService/getSiteList,这里注意请求的data参数格式应该如下:
1 {
2 " header " : {
3 " account_type " : 1 ,
4 " password " : " <密码> " ,
5 " token " : " " ,
6 " username " : " <用户名> "
7 },
8 " body " : {}
9 }
输入百度统计的用户名和密码及访问使用的token,即可正常访问我们的注册的所有站点,这里我们可以拿到站点的site_id(也可以通过百度统计页面查看),后面请求该站点的分析数据会用到。
地域分布数据获取
百度统计提供的数据类型很多,我们选取其中一个来试验下效果。比如我们需要获得访问网站用户的地域信息,不同省份的用户访问情况。
使用API模拟工具调试:请求类型POST,url地址:https://api.baidu.com/json/tongji/v1/ReportService/getData,请求的data参数格式如下:
1 {
2 " header " : {
3 " account_type " : 1 ,
4 " password " : "<密码> " ,
5 " token " : " " ,
6 " username " : "<用户名> "
7 },
8 " body " : {
9 " site_id " : <站点id> ,
10 " method " : " visit/district/a " ,
11 " start_date " : " 30daysago " ,
12 " end_date " : " today " ,
13 " metrics " : " pv_count,pv_ratio,visit_count,visitor_count,new_visitor_count,new_visitor_ratio, ip_count,bounce_ratio,avg_visit_time,avg_visit_pages,trans_count,trans_ratio " ,
14 " order " : " pv_count,desc " ,
15 " max_results " : 0
16 }
17 }
可以看到,正常返回按照不同省份区域的网站统计数据。
实现控制器逻辑:按照上面提供的json格式,配置到json文件中,并定义MyRequest对象,映射我们所有的API请求,MyRequest存放的是所有API请求的配置信息,通过API请求的id,加载不同的API配置信息。Areas/Tools/Controllers创建对应的控制器SiteAnalyticsController,主要实现GetVisitDistrictAnalytics方法,用来根据时间范围,获取相应的区域分析json数据:
1 [Area(" Tools " )]
2 public class SiteAnalyticsController : AppController
3 {
4 private readonly IList _requests;
5
6 public SiteAnalyticsController(IOptions myRequest)
7 {
8 _requests = myRequest.Value.ApiRequests;
9 }
10
11 public IActionResult Index()
12 {
13 return View();
14 }
15
16 ///
17 /// 获取百度访客区域统计数据
18 ///
19 ///
20 public async Task GetVisitDistrictAnalytics(string startDate, string endDate)
21 {
22 var hc = new HttpClient();
23 var request = _requests.FirstOrDefault(s => s.ApiCode == " BaiduGetVisitDistrict " );
24 var data = request.ApiDatas.Replace(" 30daysago " , startDate).Replace(" today " , endDate);
25 return Json(await hc.HttpPostAsync(request.Url, data));
26 }
27
28 ///
29 /// 获取百度趋势分析数据
30 ///
31 ///
32 public async Task GetTrendAnalytics(string startDate, string endDate)
33 {
34 var hc = new HttpClient();
35 var request = _requests.FirstOrDefault(s => s.ApiCode == " BaiduGetTrend " );
36 var data = request.ApiDatas.Replace(" 30daysago " , startDate).Replace(" today " , endDate);
37 return Json(await hc.HttpPostAsync(request.Url, data));
38 }
39 }
区域分析显示
有了区域分析的数据,接下来考虑要怎么显示。
我们设计各个省份的访问量,可以通过地图展现,根据实际访问量的多少,通过颜色的深浅表现;
表格的形式,具体显示不同省份的访问量和占比;
柱状图的形式,显示最近7天的访问量趋势;
地图展现,采用jvectormap插件,它是矢量地图,且有自己的API,还是非常好用的,具体使用方法,推荐访问官网:http://jvectormap.com/
Areas/Tools/Views创建视图Index:
1
2 < div class ="col-md-6 col-sm-6" >
3 < div class ="box-body" >
4 < div id ="map-markers" class ="text-center" style ="height: 420px;" >
5 < div > 浏览量地域分布div >
6 div >
7 div >
8 div >
9
10 < div class ="col-md-4 col-sm-4" style ="height: 440px; overflow: auto;" >
11 < table class ="table table-bordered" id ="districtTable" >
12 < tbody >
13 < tr >
14 < th style ="width: 10px" > #th >
15 < th > 省份th >
16 < th > 浏览量(PV)th >
17 < th > 占比th >
18 tr >
19 tbody >
20 table >
21 div >
22
23 < div class ="col-md-2 col-sm-2" >
24 < div class ="pad box-pane-right bg-green" style ="min-height: 280px" >
25 < div class ="description-block margin-bottom" id ="trend_pv_count" >
26 < div class ="sparkbar pad" data-color ="#fff" > div >
27 < h5 class ="description-header" > h5 >
28 < span class ="description-text" > 浏览量(PV)span >
29 div >
30 < div class ="description-block margin-bottom" id ="trend_visitor_count" >
31 < div class ="sparkbar pad" data-color ="#fff" > div >
32 < h5 class ="description-header" > h5 >
33 < span class ="description-text" > 访客数(UV)span >
34 div >
35 < div class ="description-block" id ="trend_ip_count" >
36 < div class ="sparkbar pad" data-color ="#fff" > div >
37 < h5 class ="description-header" > h5 >
38 < span class ="description-text" > IP数span >
39 div >
40 < div class ="description-block" id ="trend_avg_visit_time" >
41 < div class ="sparkbar pad" data-color ="#fff" > div >
42 < h5 class ="description-header" > h5 >
43 < span class ="description-text" > 平均访问时长span >
44 div >
45 div >
46 div >
SiteAnalytics.js中,定义jvectormap显示样式,动态获取区域分析数据后, 设置数据集mapObject.series.regions[0].setValues(visitorsData);
1 var options = {
2 map: 'cn_mill',
3 backgroundColor: 'transparent',
4 regionStyle: {
5 initial : {
6 fill : 'rgba(210, 214, 222, 1)',
7 'fill-opacity' : 1,
8 stroke : 'none',
9 'stroke-width' : 0,
10 'stroke-opacity': 1
11 },
12 hover : {
13 'fill-opacity': 0.7,
14 cursor : 'pointer'
15 },
16 selected : {
17 fill: 'yellow'
18 },
19 selectedHover: {}
20 },
21 series: {
22 markers: [{
23 attribute: 'fill',
24 scale: ['#C8EEFF', '#0071A4'],
25 normalizeFunction: 'polynomial',
26 values: [408, 512, 550, 781],
27 legend: {
28 vertical: true
29 }
30 }],
31 regions: [
32 {
33 scale: ['#ebf4f9', '#92c1dc'],
34 normalizeFunction: 'polynomial'
35 }
36 ]
37 },
38 onRegionLabelShow: function (e, el, code) {
39 var html = '';
40 html += ''
;
41 html += '
' + el.html() + '
'
;
42 html += '
浏览量(PV)';
43 if (typeof visitorsData[code] != 'undefined') {
44 html += visitorsData[code];
45 } else {
46 html += 0;
47 }
48 html += '
'
;
49 html += '
占比';
50 if (typeof pecentData[code] != 'undefined') {
51 html += pecentData[code];
52 } else {
53 html += 0;
54 }
55 html += ' %
'
;
56 el.html(html);
57 }
58 }
59
60 $('#map-markers').vectorMap(options);
小结
用地图显示区域分析功能至此就已经大体完成,我们加上图表数据的显示,这样内容更丰富些,最后,我们看下效果:
你可能感兴趣的:(ASP.NET Core 一步步搭建个人网站(5)_Api模拟和网站分析)
情绪觉察日记第37天
露露_e800
今天是家庭关系规划师的第二阶最后一天,慧萍老师帮我做了个案,帮我处理了埋在心底好多年的一份恐惧,并给了我深深的力量!这几天出来学习,爸妈过来婆家帮我带小孩,妈妈出于爱帮我收拾东西,并跟我先生和婆婆产生矛盾,妈妈觉得他们没有照顾好我…。今晚回家见到妈妈,我很欣赏她并赞扬她,妈妈说今晚要跟我睡我说好,当我们俩躺在床上准备睡觉的时候,我握着妈妈的手对她说:妈妈这几天辛苦你了,你看你多利害把我们的家收拾得
芦花鞋一四
许叶晗
又是在一个寒冷的夏日里,青铜和葵花决定今天一起去卖芦花鞋,奶奶亲手给他们做了一碗热乎乎的粥对他们说:“就靠你们两挣生活费了这碗粥赶紧趁热喝了吧!”于是青铜和葵花喝完了奶奶给她们做的粥,就准备去镇上卖卢花鞋,这回青铜和葵花穿着新的芦花鞋来到了镇上。青铜这回看到了很多人都在卖,用手势表达对葵花说:“这回有好多人在抢我们生意呢!我们必须得吆喝起来。”葵花点了点头。可是谁知他们也大声的叫,卖芦花喽!卖芦花
关于沟通这件事,项目经理不需要每次都面对面进行
流程大师兄
很多项目经理都会遇到这样的问题,项目中由于事情太多,根本没有足够的时间去召开会议,那在这种情况下如何去有效地管理项目中的利益相关者?当然,不建议电子邮件也不需要开会的话,建议可以采取下面几种方式来形成有效的沟通,这几种方式可以帮助你努力的通过各种办法来保持和各方面的联系。项目经理首先要问自己几个问题,项目中哪些利益相关者是必须要进行沟通的?可以列出项目中所有的利益相关者清单,同时也整理出项目中哪些
机器学习与深度学习间关系与区别
ℒℴѵℯ心·动ꦿ໊ོ꫞
人工智能 学习 深度学习 python
一、机器学习概述定义机器学习(MachineLearning,ML)是一种通过数据驱动的方法,利用统计学和计算算法来训练模型,使计算机能够从数据中学习并自动进行预测或决策。机器学习通过分析大量数据样本,识别其中的模式和规律,从而对新的数据进行判断。其核心在于通过训练过程,让模型不断优化和提升其预测准确性。主要类型1.监督学习(SupervisedLearning)监督学习是指在训练数据集中包含输入
2020-01-25
晴岚85
郑海燕坚持分享590天2020.1.24在生活中只存在两个问题。一个问题是:你知道想要达成的目标是什么,但却不知道如何才能达成;另一个问题是:你不知道你的目标是什么。前一个是行动的问题,后一个是结果的问题。通过制定具体的下一步行动,可以解决不知道如何开始行动的问题。而通过去想象结果,对结果做预估,可以解决找不着目标的问题。对于所有吸引我们注意力,想要完成的任务,你可以先想象一下,预期的结果究竟是什
想家
爆米花机
也许不同于大家对家乡的思念,我对家乡甚至是疯狂的不舍。还未踏出车站就感觉到幸福,我享受这里的夕阳、这里的浓烈柴火味、这里每一口家常菜。我是宅女,我贪恋家的安逸。刚刚踏出大学校门,初出茅庐,无法适应每年只能国庆和春节回家。我焦虑、失眠、无端发脾气,是无法适应工作的节奏,是无法接受我将一步步离开家乡的事实。我不想承认自己胸无大志,选择再次踏上征程。图片发自App
【iOS】MVC设计模式
Magnetic_h
ios mvc 设计模式 objective-c 学习 ui
MVC前言如何设计一个程序的结构,这是一门专门的学问,叫做"架构模式"(architecturalpattern),属于编程的方法论。MVC模式就是架构模式的一种。它是Apple官方推荐的App开发架构,也是一般开发者最先遇到、最经典的架构。MVC各层controller层Controller/ViewController/VC(控制器)负责协调Model和View,处理大部分逻辑它将数据从Mod
一百九十四章. 自相矛盾
巨木擎天
唉!就这么一夜,林子感觉就像过了很多天似的,先是回了阳间家里,遇到了那么多不可思议的事情儿。特别是小伙伴们,第二次与自己见面时,僵硬的表情和恐怖的气氛,让自己如坐针毡,打从心眼里难受!还有东子,他现在还好吗?有没有被人欺负?护城河里的小鱼小虾们,还都在吗?水不会真的干枯了吧?那对相亲相爱漂亮的太平鸟儿,还好吧!春天了,到了做窝、下蛋、喂养小鸟宝宝的时候了,希望它们都能够平安啊!虽然没有看见家人,也
UI学习——cell的复用和自定义cell
Magnetic_h
ui 学习
目录cell的复用手动(非注册)自动(注册)自定义cellcell的复用在iOS开发中,单元格复用是一种提高表格(UITableView)和集合视图(UICollectionView)滚动性能的技术。当一个UITableViewCell或UICollectionViewCell首次需要显示时,如果没有可复用的单元格,则视图会创建一个新的单元格。一旦这个单元格滚动出屏幕,它就不会被销毁。相反,它被添
element实现动态路由+面包屑
软件技术NINI
vue案例 vue.js 前端
el-breadcrumb是ElementUI组件库中的一个面包屑导航组件,它用于显示当前页面的路径,帮助用户快速理解和导航到应用的各个部分。在Vue.js项目中,如果你已经安装了ElementUI,就可以很方便地使用el-breadcrumb组件。以下是一个基本的使用示例:安装ElementUI(如果你还没有安装的话):你可以通过npm或yarn来安装ElementUI。bash复制代码npmi
地推话术,如何应对地推过程中家长的拒绝
校师学
相信校长们在做地推的时候经常遇到这种情况:市场专员反馈家长不接单,咨询师反馈难以邀约这些家长上门,校区地推疲软,招生难。为什么?仅从地推层面分析,一方面因为家长受到的信息轰炸越来越多,对信息越来越“免疫”;而另一方面地推人员的专业能力和营销话术没有提高,无法应对家长的拒绝,对有意向的家长也不知如何跟进,眼睁睁看着家长走远;对于家长的疑问,更不知道如何有技巧地回答,机会白白流失。由于回答没技巧和专业
谢谢你们,爱你们!
鹿游儿
昨天家人去泡温泉,二个孩子也带着去,出发前一晚,匆匆下班,赶回家和孩子一起收拾。饭后,我拿出笔和本子(上次去澳门时做手帐的本子)写下了1\2\3\4\5\6\7\8\9,让后让小壹去思考,带什么出发去旅游呢?她在对应的数字旁边画上了,泳衣、泳圈、肖恩、内衣内裤、tapuy、拖鞋……画完后,就让她自己对着这个本子,将要带的,一一带上,没想到这次带的书还是这本《便便工厂》(晚上姑婆发照片过来,妹妹累得
C语言如何定义宏函数?
小九格物
c语言
在C语言中,宏函数是通过预处理器定义的,它在编译之前替换代码中的宏调用。宏函数可以模拟函数的行为,但它们不是真正的函数,因为它们在编译时不会进行类型检查,也不会分配存储空间。宏函数的定义通常使用#define指令,后面跟着宏的名称和参数列表,以及宏展开后的代码。宏函数的定义方式:1.基本宏函数:这是最简单的宏函数形式,它直接定义一个表达式。#defineSQUARE(x)((x)*(x))2.带参
微服务下功能权限与数据权限的设计与实现
nbsaas-boot
微服务 java 架构
在微服务架构下,系统的功能权限和数据权限控制显得尤为重要。随着系统规模的扩大和微服务数量的增加,如何保证不同用户和服务之间的访问权限准确、细粒度地控制,成为设计安全策略的关键。本文将讨论如何在微服务体系中设计和实现功能权限与数据权限控制。1.功能权限与数据权限的定义功能权限:指用户或系统角色对特定功能的访问权限。通常是某个用户角色能否执行某个操作,比如查看订单、创建订单、修改用户资料等。数据权限:
理解Gunicorn:Python WSGI服务器的基石
范范0825
ipython linux 运维
理解Gunicorn:PythonWSGI服务器的基石介绍Gunicorn,全称GreenUnicorn,是一个为PythonWSGI(WebServerGatewayInterface)应用设计的高效、轻量级HTTP服务器。作为PythonWeb应用部署的常用工具,Gunicorn以其高性能和易用性著称。本文将介绍Gunicorn的基本概念、安装和配置,帮助初学者快速上手。1.什么是Gunico
2021年12月19日,春蕾教育集团团建活动感受——黄晓丹
黄错错加油
感受:1.从陌生到熟悉的过程。游戏环节让我们在轻松的氛围中得到了锻炼,也增长了不少知识。2.游戏过程中,我们贡献的是个人力量,展现的是团队的力量。它磨合的往往不止是工作的熟悉,更是观念上契合度的贴近。3.这和工作是一样的道理。在各自的岗位上,每个人摆正自己的位置、各司其职充分发挥才能,并团结一致劲往一处使,才能实现最大的成功。新知:1.团队精神需要不断地创新。过去,人们把创新看作是冒风险,现在人们
Cell Insight | 单细胞测序技术又一新发现,可用于HIV-1和Mtb共感染个体诊断
尐尐呅
结核病是艾滋病合并其他疾病中导致患者死亡的主要原因。其中结核病由结核分枝杆菌(Mycobacteriumtuberculosis,Mtb)感染引起,获得性免疫缺陷综合症(艾滋病)由人免疫缺陷病毒(Humanimmunodeficiencyvirustype1,HIV-1)感染引起。国家感染性疾病临床医学研究中心/深圳市第三人民医院张国良团队携手深圳华大生命科学研究院吴靓团队,共同研究得出单细胞测序
c++ 的iostream 和 c++的stdio的区别和联系
黄卷青灯77
c++ 算法 开发语言 iostream stdio
在C++中,iostream和C语言的stdio.h都是用于处理输入输出的库,但它们在设计、用法和功能上有许多不同。以下是两者的区别和联系:区别1.编程风格iostream(C++风格):C++标准库中的输入输出流类库,支持面向对象的输入输出操作。典型用法是cin(输入)和cout(输出),使用>操作符来处理数据。更加类型安全,支持用户自定义类型的输入输出。#includeintmain(){in
《投行人生》读书笔记
小蘑菇的树洞
《投行人生》----作者詹姆斯-A-朗德摩根斯坦利副主席40年的职业洞见-很短小精悍的篇幅,比较适合初入职场的新人。第一部分成功的职业生涯需要规划1.情商归为适应能力分享与协作同理心适应能力,更多的是自我意识,你有能力识别自己的情并分辨这些情绪如何影响你的思想和行为。2.对于初入职场的人的建议,细节,截止日期和数据很重要截止日期,一种有效的方法是请老板为你所有的任务进行优先级排序。和老板喝咖啡的好
《策划经理回忆录之二》
路基雅虎
话说三年变六年,飘了,飘了……眨眼,2013年5月,老吴回到了他的家乡——油城从新开启他的工作幻想症生涯。很庆幸,这是一家很有追求,同时敢于尝试的,且实力不容低调的新星房企——金源置业(前身泰源置业)更值得庆幸的是第一个盘就是油城十路的标杆之一:金源盛世。2013年5月,到2015年11月,两年的陪伴,迎来了一场大爆发。2000个筹,5万/筹,直接回笼1个亿!!!这……让我开始认真审视这座看似五线
Long类型前后端数据不一致
igotyback
前端
响应给前端的数据浏览器控制台中response中看到的Long类型的数据是正常的到前端数据不一致前后端数据类型不匹配是一个常见问题,尤其是当后端使用Java的Long类型(64位)与前端JavaScript的Number类型(最大安全整数为2^53-1,即16位)进行数据交互时,很容易出现精度丢失的问题。这是因为JavaScript中的Number类型无法安全地表示超过16位的整数。为了解决这个问
swagger访问路径
igotyback
swagger
Swagger2.x版本访问地址:http://{ip}:{port}/{context-path}/swagger-ui.html{ip}是你的服务器IP地址。{port}是你的应用服务端口,通常为8080。{context-path}是你的应用上下文路径,如果应用部署在根路径下,则为空。Swagger3.x版本对于Swagger3.x版本(也称为OpenAPI3)访问地址:http://{ip
Linux下QT开发的动态库界面弹出操作(SDL2)
13jjyao
QT类 qt 开发语言 sdl2 linux
需求:操作系统为linux,开发框架为qt,做成需带界面的qt动态库,调用方为java等非qt程序难点:调用方为java等非qt程序,也就是说调用方肯定不带QApplication::exec(),缺少了这个,QTimer等事件和QT创建的窗口将不能弹出(包括opencv也是不能弹出);这与qt调用本身qt库是有本质的区别的思路:1.调用方缺QApplication::exec(),那么我们在接口
绘本讲师训练营【24期】8/21阅读原创《独生小孩》
1784e22615e0
24016-孟娟《独生小孩》图片发自App今天我想分享一个蛮特别的绘本,讲的是一个特殊的群体,我也是属于这个群体,80后的独生小孩。这是一本中国绘本,作者郭婧,也是一个80厚。全书一百多页,均为铅笔绘制,虽然为黑白色调,但并不显得沉闷。全书没有文字,犹如“默片”,但并不影响读者对该作品的理解,反而显得神秘,梦幻,給读者留下想象的空间。作者在前蝴蝶页这样写到:“我更希望父母和孩子一起分享这本书,使他
店群合一模式下的社区团购新发展——结合链动 2+1 模式、AI 智能名片与 S2B2C 商城小程序源码
说私域
人工智能 小程序
摘要:本文探讨了店群合一的社区团购平台在当今商业环境中的重要性和优势。通过分析店群合一模式如何将互联网社群与线下终端紧密结合,阐述了链动2+1模式、AI智能名片和S2B2C商城小程序源码在这一模式中的应用价值。这些创新元素的结合为社区团购带来了新的机遇,提升了用户信任感、拓展了营销渠道,并实现了线上线下的完美融合。一、引言随着互联网技术的不断发展,社区团购作为一种新兴的商业模式,在满足消费者日常需
消息中间件有哪些常见类型
xmh-sxh-1314
java
消息中间件根据其设计理念和用途,可以大致分为以下几种常见类型:点对点消息队列(Point-to-PointMessagingQueues):在这种模型中,消息被发送到特定的队列中,消费者从队列中取出并处理消息。队列中的消息只能被一个消费者消费,消费后即被删除。常见的实现包括IBM的MQSeries、RabbitMQ的部分使用场景等。适用于任务分发、负载均衡等场景。发布/订阅消息模型(Pub/Sub
ArcGIS栅格计算器常见公式(赋值、0和空值的转换、补充栅格空值)
研学随笔
arcgis 经验分享
我们在使用ArcGIS时通常经常用到栅格计算器,今天主要给大家介绍我日常中经常用到的几个公式,供大家参考学习。将特定值(-9999)赋值为0,例如-9999.Con("raster"==-9999,0,"raster")2.给空值赋予特定的值(如0)Con(IsNull("raster"),0,"raster")3.将特定的栅格值(如1)赋值为空值,其他保留原值SetNull("raster"==
高级编程--XML+socket练习题
masa010
java 开发语言
1.北京华北2114.8万人上海华东2,500万人广州华南1292.68万人成都华西1417万人(1)使用dom4j将信息存入xml中(2)读取信息,并打印控制台(3)添加一个city节点与子节点(4)使用socketTCP协议编写服务端与客户端,客户端输入城市ID,服务器响应相应城市信息(5)使用socketTCP协议编写服务端与客户端,客户端要求用户输入city对象,服务端接收并使用dom4j
水平垂直居中的几种方法(总结)
LJ小番茄
CSS_玄学语言 html javascript 前端 css css3
1.使用flexbox的justify-content和align-items.parent{display:flex;justify-content:center;/*水平居中*/align-items:center;/*垂直居中*/height:100vh;/*需要指定高度*/}2.使用grid的place-items:center.parent{display:grid;place-item
本周第二次约练
2cfbdfe28a51
中原焦点团队中24初26刘霞2021.12.3约练161次,分享第368天当事人虽然是带着问题来的,但是咨询过程中发现,她是经过自己不断地调整和努力才走到现在的,看到当事人的不容易,找到例外,发现资源,力量感也就随之而来。增强画面感,或者说重温,会给当事人带来更深刻的感受。
TOMCAT在POST方法提交参数丢失问题
357029540
java tomcat jsp
摘自http://my.oschina.net/luckyi/blog/213209
昨天在解决一个BUG时发现一个奇怪的问题,一个AJAX提交数据在之前都是木有问题的,突然提交出错影响其他处理流程。
检查时发现页面处理数据较多,起初以为是提交顺序不正确修改后发现不是由此问题引起。于是删除掉一部分数据进行提交,较少数据能够提交成功。
恢复较多数据后跟踪提交FORM DATA ,发现数
在MyEclipse中增加JSP模板 删除-2008-08-18
ljy325
jsp xml MyEclipse
在D:\Program Files\MyEclipse 6.0\myeclipse\eclipse\plugins\com.genuitec.eclipse.wizards_6.0.1.zmyeclipse601200710\templates\jsp 目录下找到Jsp.vtl,复制一份,重命名为jsp2.vtl,然后把里面的内容修改为自己想要的格式,保存。
然后在 D:\Progr
JavaScript常用验证脚本总结
eksliang
JavaScript javaScript表单验证
转载请出自出处:http://eksliang.iteye.com/blog/2098985
下面这些验证脚本,是我在这几年开发中的总结,今天把他放出来,也算是一种分享吧,现在在我的项目中也在用!包括日期验证、比较,非空验证、身份证验证、数值验证、Email验证、电话验证等等...!
&nb
微软BI(4)
18289753290
微软BI SSIS
1)
Q:查看ssis里面某个控件输出的结果:
A MessageBox.Show(Dts.Variables["v_lastTimestamp"].Value.ToString());
这是我们在包里面定义的变量
2):在关联目的端表的时候如果是一对多的关系,一定要选择唯一的那个键作为关联字段。
3)
Q:ssis里面如果将多个数据源的数据插入目的端一
定时对大数据量的表进行分表对数据备份
酷的飞上天空
大数据量
工作中遇到数据库中一个表的数据量比较大,属于日志表。正常情况下是不会有查询操作的,但如果不进行分表数据太多,执行一条简单sql语句要等好几分钟。。
分表工具:linux的shell + mysql自身提供的管理命令
原理:使用一个和原表数据结构一样的表,替换原表。
linux shell内容如下:
=======================开始 
本质的描述与因材施教
永夜-极光
感想 随笔
不管碰到什么事,我都下意识的想去探索本质,找寻一个最形象的描述方式。
我坚信,世界上对一件事物的描述和解释,肯定有一种最形象,最贴近本质,最容易让人理解
&
很迷茫。。。
随便小屋
随笔
小弟我今年研一,也是从事的咱们现在最流行的专业(计算机)。本科三流学校,为了能有个更好的跳板,进入了考研大军,非常有幸能进入研究生的行业(具体学校就不说了,怕把学校的名誉给损了)。
先说一下自身的条件,本科专业软件工程。主要学习就是软件开发,几乎和计算机没有什么区别。因为学校本身三流,也就是让老师带着学生学点东西,然后让学生毕业就行了。对专业性的东西了解的非常浅。就那学的语言来说
23种设计模式的意图和适用范围
aijuans
设计模式
Factory Method 意图 定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。 适用性 当一个类不知道它所必须创建的对象的类的时候。 当一个类希望由它的子类来指定它所创建的对象的时候。 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
Abstr
Java中的synchronized和volatile
aoyouzi
java volatile synchronized
说到Java的线程同步问题肯定要说到两个关键字synchronized和volatile。说到这两个关键字,又要说道JVM的内存模型。JVM里内存分为main memory和working memory。 Main memory是所有线程共享的,working memory则是线程的工作内存,它保存有部分main memory变量的拷贝,对这些变量的更新直接发生在working memo
js数组的操作和this关键字
百合不是茶
js 数组操作 this关键字
js数组的操作;
一:数组的创建:
1、数组的创建
var array = new Array(); //创建一个数组
var array = new Array([size]); //创建一个数组并指定长度,注意不是上限,是长度
var arrayObj = new Array([element0[, element1[, ...[, elementN]]]
别人的阿里面试感悟
bijian1013
面试分享 工作感悟 阿里面试
原文如下:http://greemranqq.iteye.com/blog/2007170
一直做企业系统,虽然也自己一直学习技术,但是感觉还是有所欠缺,准备花几个月的时间,把互联网的东西,以及一些基础更加的深入透析,结果这次比较意外,有点突然,下面分享一下感受吧!
&nb
淘宝的测试框架Itest
Bill_chen
spring maven 框架 单元测试 JUnit
Itest测试框架是TaoBao测试部门开发的一套单元测试框架,以Junit4为核心,
集合DbUnit、Unitils等主流测试框架,应该算是比较好用的了。
近期项目中用了下,有关itest的具体使用如下:
1.在Maven中引入itest框架:
<dependency>
<groupId>com.taobao.test</groupId&g
【Java多线程二】多路条件解决生产者消费者问题
bit1129
java多线程
package com.tom;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.loc
汉字转拼音pinyin4j
白糖_
pinyin4j
以前在项目中遇到汉字转拼音的情况,于是在网上找到了pinyin4j这个工具包,非常有用,别的不说了,直接下代码:
import java.util.HashSet;
import java.util.Set;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin
org.hibernate.TransactionException: JDBC begin failed解决方案
bozch
ssh 数据库异常 DBCP
org.hibernate.TransactionException: JDBC begin failed: at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:68) at org.hibernate.impl.SessionImp
java-并查集(Disjoint-set)-将多个集合合并成没有交集的集合
bylijinnan
java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.ut
Java PrintWriter打印乱码
chenbowen00
java
一个小程序读写文件,发现PrintWriter输出后文件存在乱码,解决办法主要统一输入输出流编码格式。
读文件:
BufferedReader
从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。
可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
通常,Reader 所作的每个读取请求都会导致对基础字符或字节流进行相应的读取请求。因
[天气与气候]极端气候环境
comsci
环境
如果空间环境出现异变...外星文明并未出现,而只是用某种气象武器对地球的气候系统进行攻击,并挑唆地球国家间的战争,经过一段时间的准备...最大限度的削弱地球文明的整体力量,然后再进行入侵......
那么地球上的国家应该做什么样的防备工作呢?
&n
oracle order by与union一起使用的用法
daizj
UNION oracle order by
当使用union操作时,排序语句必须放在最后面才正确,如下:
只能在union的最后一个子查询中使用order by,而这个order by是针对整个unioning后的结果集的。So:
如果unoin的几个子查询列名不同,如
Sql代码
select supplier_id, supplier_name
from suppliers
UNI
zeus持久层读写分离单元测试
deng520159
单元测试
本文是zeus读写分离单元测试,距离分库分表,只有一步了.上代码:
1.ZeusMasterSlaveTest.java
package com.dengliang.zeus.webdemo.test;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.j
Yii 截取字符串(UTF-8) 使用组件
dcj3sjt126com
yii
1.将Helper.php放进protected\components文件夹下。
2.调用方法:
Helper::truncate_utf8_string($content,20,false); //不显示省略号 Helper::truncate_utf8_string($content,20); //显示省略号
&n
安装memcache及php扩展
dcj3sjt126com
PHP
安装memcache tar zxvf memcache-2.2.5.tgz cd memcache-2.2.5/ /usr/local/php/bin/phpize (?) ./configure --with-php-confi
JsonObject 处理日期
feifeilinlin521
java json JsonOjbect JsonArray JSONException
写这边文章的初衷就是遇到了json在转换日期格式出现了异常 net.sf.json.JSONException: java.lang.reflect.InvocationTargetException 原因是当你用Map接收数据库返回了java.sql.Date 日期的数据进行json转换出的问题话不多说 直接上代码
&n
Ehcache(06)——监听器
234390216
监听器 listener ehcache
监听器
Ehcache中监听器有两种,监听CacheManager的CacheManagerEventListener和监听Cache的CacheEventListener。在Ehcache中,Listener是通过对应的监听器工厂来生产和发生作用的。下面我们将来介绍一下这两种类型的监听器。
activiti 自带设计器中chrome 34版本不能打开bug的解决
jackyrong
Activiti
在acitivti modeler中,如果是chrome 34,则不能打开该设计器,其他浏览器可以,
经证实为bug,参考
http://forums.activiti.org/content/activiti-modeler-doesnt-work-chrome-v34
修改为,找到
oryx.debug.js
在最头部增加
if (!Document.
微信收货地址共享接口-终极解决
laotu5i0
微信开发
最近要接入微信的收货地址共享接口,总是不成功,折腾了好几天,实在没办法网上搜到的帖子也是骂声一片。我把我碰到并解决问题的过程分享出来,希望能给微信的接口文档起到一个辅助作用,让后面进来的开发者能快速的接入,而不需要像我们一样苦逼的浪费好几天,甚至一周的青春。各种羞辱、谩骂的话就不说了,本人还算文明。
如果你能搜到本贴,说明你已经碰到了各种 ed
关于人才
netkiller.github.com
工作 面试 招聘 netkiller 人才
关于人才
每个月我都会接到许多猎头的电话,有些猎头比较专业,但绝大多数在我看来与猎头二字还是有很大差距的。 与猎头接触多了,自然也了解了他们的工作,包括操作手法,总体上国内的猎头行业还处在初级阶段。
总结就是“盲目推荐,以量取胜”。
目前现状
许多从事人力资源工作的人,根本不懂得怎么找人才。处在人才找不到企业,企业找不到人才的尴尬处境。
企业招聘,通常是需要用人的部门提出招聘条件,由人
搭建 CentOS 6 服务器 - 目录
rensanning
centos
(1) 安装CentOS
ISO(desktop/minimal)、Cloud(AWS/阿里云)、Virtualization(VMWare、VirtualBox)
详细内容
(2) Linux常用命令
cd、ls、rm、chmod......
详细内容
(3) 初始环境设置
用户管理、网络设置、安全设置......
详细内容
(4) 常驻服务Daemon
【求助】mongoDB无法更新主键
toknowme
mongodb
Query query = new Query(); query.addCriteria(new Criteria("_id").is(o.getId())); &n
jquery 页面滚动到底部自动加载插件集合
xp9802
jquery
很多社交网站都使用无限滚动的翻页技术来提高用户体验,当你页面滑到列表底部时候无需点击就自动加载更多的内容。下面为你推荐 10 个 jQuery 的无限滚动的插件:
1. jQuery ScrollPagination
jQuery ScrollPagination plugin 是一个 jQuery 实现的支持无限滚动加载数据的插件。
2. jQuery Screw
S