最近文章:高可用数据采集平台(如何玩转3门语言php+.net+aauto)高并发数据采集的架构应用(Redis的应用)

项目文档:关键词匹配项目深入研究(二)- 分表思想的引入

吐槽:本人也是非常讨厌拿来主义的,有些培训每个细节都提到过,主管还找我要实际案例,而不是去安排合适的人去做这件事情,有点过于拿来主义了,有点担心。

好消息的是:高并发数据采集的架构应用(Redis的应用)团队已经实现了,不过有部分代码还是我写的,值得喝彩下,说明团队的能力还是不错的。

最近有时间,我也是用.net完成高可用数据采集平台(如何玩转3门语言php+.net+aauto)服务的编码工作。

正文开始

要想快速学习某一件事情,我们就得必须做好规划。

首先我们先来分析下要实现该项目需要哪些方面的技术,我们从哪里开始分析呢,当然有系统分析师帮你做啦!

所需的技术

1. Microsoft Studio 2010 IDE以及.Net Framework基础知识的了解

2. 如何利用C#创建服务,服务安装以及卸载

3. SQLite的基础应用以及C#如何使用SQLite

4. C#定时器的应用

5. C#的多线程应用以及线程池的应用

6. 操作系统信号量,互斥同步锁概念以及C#如何使用信号量、互斥同步锁

7. C#文件操作,ini配置文件读取技术

8. C# WEB API的调用,以及异步处理知识和C# TASK的了解应用

9. 数据传输解析技术,以及C#如何解析JSON

10. 其它常用应用,比如DataSet、DataTable、DataRow、Dictionary、List、KeyValuePair、String等

这些点看起来好恐怖,要想做好应用这些只是小小的一部分,但相对于菜鸟或者学生们就等于天书了,但是我只有一个星期的事情。

只要我们有目的去做事,任何事都不会有阻碍,废话少说,等下闲我啰嗦了。

1. Microsoft Studio 2010 IDE以及.Net Framework基础知识的了解

     这点我竟然列为了重点,有些人有可能对这点不重视,但是我相信很多有经验的人都会同我一样非常重视这点。

Microsoft Studio 2010 IDE都不用说了,这个大家都是专家,我为什么会选择博客园写文章,是因为我在上学的时候看了一本博客园出版的书,讲的是设计模式的应用,觉得非常的不错,当时博客园是.Net技术平台的佼佼者。

Microsoft Studio 2010 IDE最主要的一点,就是选择框架,选择项目适合的框架。

.Net Framework 主要也是注意下为什么有那么多版本,了解下他们互相是否有关系,比如从2.0升到4.0是否能够平稳的过渡。

   2. 如何利用C#创建服务,服务安装以及卸载

    我也是看了一篇博客而学来的,非常不错,我也把地址贴出来:http://www.cnblogs.com/aierong/archive/2012/05/28/2521409.html

我也是主要用了(a) 利用.net框架类ServiceBase,步骤参考上面博客的地址:安装的时候注意下选择好对应版本的installutil。

    代码贴出来

public partial class MainService : ServiceBase
{
readonly System.Timers.Timer _timer_request; readonly System.Timers.Timer _timer_upload; WorkProcess work = new WorkProcess(); public MainService()
{
InitializeComponent(); //install db table
TaskModel.install(); _timer_upload = _timer_request = new System.Timers.Timer()
{
AutoReset = true,
Enabled = true
}; _timer_request.Elapsed += delegate(object sender, ElapsedEventArgs e)
{
Logger.log("Start Request Data From Api"); try
{
TaskResponse response = TaskFactory.createFromApi();
TaskModel.save(response);
}
catch (Exception ex)
{
Logger.error(ex.Message);
} Logger.log("End Request Data From Api");
}; _timer_upload.Elapsed += delegate(object sender, ElapsedEventArgs e)
{
Logger.log("Start Upload Data To Api");
try
{
if (!work.wait())
{
work.doing();
}
}
catch (Exception ex)
{
Logger.error(ex.Message);
}
Logger.log("End Upload Data To Api"); }; } protected override void OnStart(string[] args)
{
_timer_request.Enabled = true;
_timer_upload.Enabled = true;
} protected override void OnStop()
{
_timer_request.Enabled = false;
_timer_upload.Enabled = false;
}
}

  

3. SQLite的基础应用以及C#如何使用SQLite

   也是一样,有博客就是好,推荐代码直接拷贝一份过来。http://www.cnblogs.com/OnlyVersion/p/3746086.html

我也贴个相对精简的吧。

class DB
{
/// <summary>
/// 获得连接对象
/// </summary>
/// <returns>SQLiteConnection</returns>
public static SQLiteConnection GetSQLiteConnection(){ string str = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var con = new SQLiteConnection("Data Source=" + str + @"\" + "DataBase" + @"\" + "InfoServiceDb.db");
return con;
} /// <summary>
/// 准备操作命令参数
/// </summary>
/// <param name="cmd">SQLiteCommand</param>
/// <param name="conn">SQLiteConnection</param>
/// <param name="cmdText">Sql命令文本</param>
/// <param name="data">参数数组</param>
private static void PrepareCommand(SQLiteCommand cmd, SQLiteConnection conn, string cmdText, Dictionary<String, String> data)
{
if (conn.State != ConnectionState.Open)
conn.Open();
cmd.Parameters.Clear();
cmd.Connection = conn;
cmd.CommandText = cmdText;
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = ;
if (data != null && data.Count >= )
{
foreach (KeyValuePair<String, String> val in data)
{
cmd.Parameters.AddWithValue(val.Key, val.Value);
}
}
} /// <summary>
/// 查询,返回DataSet
/// </summary>
/// <param name="cmdText">Sql命令文本</param>
/// <param name="data">参数数组</param>
/// <returns>DataSet</returns>
public static DataSet ExecuteDataset(string cmdText, Dictionary<string, string> data)
{
var ds = new DataSet();
using (SQLiteConnection connection = GetSQLiteConnection())
{
var command = new SQLiteCommand();
PrepareCommand(command, connection, cmdText, data);
var da = new SQLiteDataAdapter(command);
da.Fill(ds);
}
return ds;
} /// <summary>
/// 查询,返回DataTable
/// </summary>
/// <param name="cmdText">Sql命令文本</param>
/// <param name="data">参数数组</param>
/// <returns>DataTable</returns>
public static DataTable ExecuteDataTable(string cmdText, Dictionary<string, string> data)
{
var dt = new DataTable();
using (SQLiteConnection connection = GetSQLiteConnection())
{
var command = new SQLiteCommand();
PrepareCommand(command, connection, cmdText, data);
SQLiteDataReader reader = command.ExecuteReader();
dt.Load(reader);
}
return dt;
} /// <summary>
/// 返回一行数据
/// </summary>
/// <param name="cmdText">Sql命令文本</param>
/// <param name="data">参数数组</param>
/// <returns>DataRow</returns>
public static DataRow ExecuteDataRow(string cmdText, Dictionary<string, string> data)
{
DataSet ds = ExecuteDataset(cmdText, data);
if (ds != null && ds.Tables.Count > && ds.Tables[].Rows.Count > )
return ds.Tables[].Rows[];
return null;
} /// <summary>
/// 执行数据库操作
/// </summary>
/// <param name="cmdText">Sql命令文本</param>
/// <param name="data">传入的参数</param>
/// <returns>返回受影响的行数</returns>
public static int ExecuteNonQuery(string cmdText, Dictionary<string, string> data)
{
using (SQLiteConnection connection = GetSQLiteConnection())
{
var command = new SQLiteCommand();
PrepareCommand(command, connection, cmdText, data);
return command.ExecuteNonQuery();
}
} /// <summary>
/// 返回SqlDataReader对象
/// </summary>
/// <param name="cmdText">Sql命令文本</param>
/// <param name="data">传入的参数</param>
/// <returns>SQLiteDataReader</returns>
public static SQLiteDataReader ExecuteReader(string cmdText, Dictionary<string, string> data)
{
var command = new SQLiteCommand();
SQLiteConnection connection = GetSQLiteConnection();
try
{
PrepareCommand(command, connection, cmdText, data);
SQLiteDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
return reader;
}
catch
{
connection.Close();
command.Dispose();
throw;
}
} /// <summary>
/// 返回结果集中的第一行第一列,忽略其他行或列
/// </summary>
/// <param name="cmdText">Sql命令文本</param>
/// <param name="data">传入的参数</param>
/// <returns>object</returns>
public static object ExecuteScalar(string cmdText, Dictionary<string, string> data)
{
using (SQLiteConnection connection = GetSQLiteConnection())
{
var cmd = new SQLiteCommand();
PrepareCommand(cmd, connection, cmdText, data);
return cmd.ExecuteScalar();
}
}
}

4. C#定时器的应用

  参考1.创建服务的代码

主要两个定时器:

1. 用于请求服务端要待处理事项

2. 用于上传已处理事项的数据到服务器。

5. C#的多线程应用以及线程池的应用

     多线程和线程池的概念这儿略过,本次应用只使用了.Net Framework中提供ThreadPool

ThreadPool:http://www.cnblogs.com/xugang/archive/2010/04/20/1716042.html ,这篇博客很好的介绍了基础知识。

我也贴一下,本次应用的代码:

public class WorkProcess
{
public static int iCount = ;
public static int iMaxCount = ; public WorkProcess(int MaxCount)
{
iMaxCount = MaxCount;
} //线程池里的线程将调用Beta()方法
public void execute(Object state)
{
Interlocked.Increment(ref iCount);
try
{
TaskState taskState = (TaskState)state;
string lockedStr = string.Format("task.locked.{0}.{1}", taskState.taskId, taskState.uploadId); lock (lockedStr)
{
TaskUpload.work(taskState);
}
int iX = ;
Thread.Sleep(iX);
}
catch (Exception e)
{
Logger.error(e.Message);
}
finally
{
Interlocked.Decrement(ref iCount);
} } public bool wait()
{
int threadNumber = ;
//获取当前线程数
threadNumber = Interlocked.Exchange(ref iCount, iCount); Logger.log(string.Format("Thread Num:{0}",threadNumber)); if (threadNumber <= iMaxCount)
{
return false;
}
return true; } public void doing()
{
string sql = "SELECT task.id as id,task_upload.id as uploadId FROM task LEFT JOIN task_upload ON task.id=task_upload.task_id WHERE status=:status AND upload_status=:upload_status LIMIT 10";
Dictionary<string, string> data = new Dictionary<string, string>();
data.Add(":status", "DONE");
data.Add(":upload_status", "WAIT");
DataTable dt = DB.ExecuteDataTable(sql, data); foreach (DataRow row in dt.Rows)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(this.execute), new TaskState((int)row["id"], (int)row["uploadId"]));
}
}
}

6. 操作系统信号量,互斥同步锁概念以及C#如何使用信号量、互斥同步锁

   本次应用使用了信号量,主要作用是防止无限制的往线程池里面PUSH任务,适当的等待下任务的处理进度。

7. C#文件操作,ini配置文件读取技术

    本次应用主要使用文件存储一些必要的调试信息以及错误信息。

public class Logger
{
private static readonly string ErrorFileName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\" +"logs"+@"\"+ "error.txt";
private static readonly string LogFileName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\" + "logs" + @"\" + "log.txt"; public static void log(string msg)
{
StreamWriter sw = File.AppendText(LogFileName);
sw.WriteLine(string.Format("{0}:{1}",DateTime.Now,msg));
sw.Flush();
sw.Close();
} public static void error(string msg)
{
StreamWriter sw = File.AppendText(ErrorFileName);
sw.WriteLine(string.Format("{0}:{1}", DateTime.Now, msg));
sw.Flush();
sw.Close();
}
}

Ini配置读取是为了更好的成为一个独立的构件,源码来源博客园的其他作者。

/// <summary>
/// IniFiles的类
/// </summary>
public class IniFiles
{
public string FileName; //INI文件名
//声明读写INI文件的API函数
[DllImport("kernel32")]
private static extern bool WritePrivateProfileString(string section, string key, string val, string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, byte[] retVal, int size, string filePath); public static IniFiles config(){ string configFileName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)+@"\config.ini"; return new IniFiles(configFileName);
} //类的构造函数,传递INI文件名
public IniFiles(string AFileName)
{
// 判断文件是否存在
FileInfo fileInfo = new FileInfo(AFileName);
//Todo:搞清枚举的用法
if ((!fileInfo.Exists))
{ //|| (FileAttributes.Directory in fileInfo.Attributes))
//文件不存在,建立文件
System.IO.StreamWriter sw = new System.IO.StreamWriter(AFileName, false, System.Text.Encoding.Default);
try
{
sw.Write("#表格配置档案");
sw.Close();
}
catch
{
throw (new ApplicationException("Ini文件不存在"));
}
}
//必须是完全路径,不能是相对路径
FileName = fileInfo.FullName;
}
//写INI文件
public void WriteString(string Section, string Ident, string Value)
{
if (!WritePrivateProfileString(Section, Ident, Value, FileName))
{
throw (new ApplicationException("写Ini文件出错"));
}
}
//读取INI文件指定
public string ReadString(string Section, string Ident, string Default)
{
Byte[] Buffer = new Byte[];
int bufLen = GetPrivateProfileString(Section, Ident, Default, Buffer, Buffer.GetUpperBound(), FileName);
//必须设定0(系统默认的代码页)的编码方式,否则无法支持中文
string s = Encoding.GetEncoding().GetString(Buffer);
s = s.Substring(, bufLen);
return s.Trim();
} //读整数
public int ReadInteger(string Section, string Ident, int Default)
{
string intStr = ReadString(Section, Ident, Convert.ToString(Default));
try
{
return Convert.ToInt32(intStr);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return Default;
}
} //写整数
public void WriteInteger(string Section, string Ident, int Value)
{
WriteString(Section, Ident, Value.ToString());
} //读布尔
public bool ReadBool(string Section, string Ident, bool Default)
{
try
{
return Convert.ToBoolean(ReadString(Section, Ident, Convert.ToString(Default)));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return Default;
}
} //写Bool
public void WriteBool(string Section, string Ident, bool Value)
{
WriteString(Section, Ident, Convert.ToString(Value));
} //从Ini文件中,将指定的Section名称中的所有Ident添加到列表中
public void ReadSection(string Section, StringCollection Idents)
{
Byte[] Buffer = new Byte[];
//Idents.Clear(); int bufLen = GetPrivateProfileString(Section, null, null, Buffer, Buffer.GetUpperBound(),
FileName);
//对Section进行解析
GetStringsFromBuffer(Buffer, bufLen, Idents);
} private void GetStringsFromBuffer(Byte[] Buffer, int bufLen, StringCollection Strings)
{
Strings.Clear();
if (bufLen != )
{
int start = ;
for (int i = ; i < bufLen; i++)
{
if ((Buffer[i] == ) && ((i - start) > ))
{
String s = Encoding.GetEncoding().GetString(Buffer, start, i - start);
Strings.Add(s);
start = i + ;
}
}
}
}
//从Ini文件中,读取所有的Sections的名称
public void ReadSections(StringCollection SectionList)
{
//Note:必须得用Bytes来实现,StringBuilder只能取到第一个Section
byte[] Buffer = new byte[];
int bufLen = ;
bufLen = GetPrivateProfileString(null, null, null, Buffer,
Buffer.GetUpperBound(), FileName);
GetStringsFromBuffer(Buffer, bufLen, SectionList);
}
//读取指定的Section的所有Value到列表中
public void ReadSectionValues(string Section, NameValueCollection Values)
{
StringCollection KeyList = new StringCollection();
ReadSection(Section, KeyList);
Values.Clear();
foreach (string key in KeyList)
{
Values.Add(key, ReadString(Section, key, ""));
}
}
////读取指定的Section的所有Value到列表中,
//public void ReadSectionValues(string Section, NameValueCollection Values,char splitString)
//{  string sectionValue;
//  string[] sectionValueSplit;
//  StringCollection KeyList = new StringCollection();
//  ReadSection(Section, KeyList);
//  Values.Clear();
//  foreach (string key in KeyList)
//  {
//    sectionValue=ReadString(Section, key, "");
//    sectionValueSplit=sectionValue.Split(splitString);
//    Values.Add(key, sectionValueSplit[0].ToString(),sectionValueSplit[1].ToString()); //  }
//}
//清除某个Section
public void EraseSection(string Section)
{
if (!WritePrivateProfileString(Section, null, null, FileName))
{
throw (new ApplicationException("无法清除Ini文件中的Section"));
}
}
//删除某个Section下的键
public void DeleteKey(string Section, string Ident)
{
WritePrivateProfileString(Section, Ident, null, FileName);
}
//Note:对于Win9X,来说需要实现UpdateFile方法将缓冲中的数据写入文件
//在Win NT, 2000和XP上,都是直接写文件,没有缓冲,所以,无须实现UpdateFile
//执行完对Ini文件的修改之后,应该调用本方法更新缓冲区。
public void UpdateFile()
{
WritePrivateProfileString(null, null, null, FileName);
} //检查某个Section下的某个键值是否存在
public bool ValueExists(string Section, string Ident)
{
StringCollection Idents = new StringCollection();
ReadSection(Section, Idents);
return Idents.IndexOf(Ident) > -;
} //确保资源的释放
~IniFiles()
{
UpdateFile();
}
}

我们也是主要学习下使用方式就好了。

8. C# WEB API的调用,以及异步处理知识和C# TASK的了解应用

C# WEB API的调用也是参考了博客园的知识:http://www.cnblogs.com/r01cn/archive/2012/11/20/2779011.html

主要也是使用了HttpClient。

代码如下:

public static TaskResponse createFromApi()
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json")
);
string readUri = IniFiles.config().ReadString("uri","read","");
HttpResponseMessage response = client.GetAsync(readUri).Result; if (response.IsSuccessStatusCode)
{
// Parse the response body. Blocking!
var taskString = response.Content.ReadAsStringAsync().Result; StringReader sr = new StringReader(taskString.ToString());
JsonSerializer serializer = new JsonSerializer();
TaskResponse taskResponse = (TaskResponse)serializer.Deserialize(new JsonTextReader(sr),typeof(TaskResponse)); Logger.log(string.Format("nick:{0},Type:{1}", taskResponse.nick, taskResponse.type));
return taskResponse;
}
else
{
Logger.error(string.Format("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase));
throw new Exception(string.Format("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase));
}
} public static bool upload(string jsonData)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json")
); string uploadUri = IniFiles.config().ReadString("uri", "upload", "");
List<KeyValuePair<String, String>> paramList = new List<KeyValuePair<String, String>>();
paramList.Add(new KeyValuePair<string, string>("data",jsonData)); var response = client.PostAsync(uploadUri, new FormUrlEncodedContent(paramList)).Result;
if (response.IsSuccessStatusCode)
{
var responseString = response.Content.ReadAsStringAsync().Result;
Logger.log(responseString.ToString());
return true;
}
else
{
Logger.error(string.Format("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase));
return false;
} }

9. 数据传输解析技术,以及C#如何解析JSON

   数据传输技术已经经历过很多时代,不过现在的时代用json还是相当比较普及的,比如现在的手机行业的普及,JSON的传输方式再一次被推向浪的高潮。

C# json解析,我使用了第三方包Newtonsoft.Json,原因很简单,我觉得易用,哪个好用我就选哪个。

使用方法参考 8.C# WEB API的调用,以及异步处理知识和C# TASK的了解应用

10. 其它常用应用,比如DataSet、DataTable、DataRow、Dictionary、List、KeyValuePair、String等

     因为这些是基础,多使用,摸清他们的关系,基本讲求到会用就行了,当然性能优化的另说了,你要纠结的话那就去纠结吧。

总结:

     要想成功做好一件事情,是要有目的的去做去学,像我这样能把所有的都列清楚,一步一步的走吧,相信你离成功将会不远了。

看我如何快速学习.Net(高可用数据采集平台)的更多相关文章

  1. 高可用数据采集平台(如何玩转3门语言php+.net+aauto)

    同类文章:高并发数据采集的架构应用(Redis的应用) 吐槽下:本人主程是PHP,团队里面也没有精通.net的人才,为了解决这个平台方案,还是费了一部分劲. 新年了,希望有个新的开始.技术+团队管理都 ...

  2. 高可用Hadoop平台-集成Hive HAProxy

    1.概述 这篇博客是接着<高可用Hadoop平台>系列讲,本篇博客是为后面用 Hive 来做数据统计做准备的,介绍如何在 Hadoop HA 平台下集成高可用的 Hive 工具,下面我打算 ...

  3. 高可用Hadoop平台-启航

    1.概述 在上篇博客中,我们搭建了<配置高可用Hadoop平台>,接下来我们就可以驾着Hadoop这艘巨轮在大数据的海洋中遨游了.工欲善其事,必先利其器.是的,没错:我们开发需要有开发工具 ...

  4. 高可用Hadoop平台-Oozie工作流之Hadoop调度

    1.概述 在<高可用Hadoop平台-Oozie工作流>一篇中,给大家分享了如何去单一的集成Oozie这样一个插件.今天为大家介绍如何去使用Oozie创建相关工作流运行与Hadoop上,已 ...

  5. 高可用Hadoop平台-Hue In Hadoop

    1.概述 前面一篇博客<高可用Hadoop平台-Ganglia安装部署>,为大家介绍了Ganglia在Hadoop中的集成,今天为大家介绍另一款工具——Hue,该工具功能比较丰富,下面是今 ...

  6. 高可用Hadoop平台-探索

    1.概述 上篇<高可用Hadoop平台-启航>博客已经让我们初步了解了Hadoop平台:接下来,我们对Hadoop做进一步的探索,一步一步的揭开Hadoop的神秘面纱.下面,我们开始赘述今 ...

  7. 高可用Hadoop平台-实战尾声篇

    1.概述 今天这篇博客就是<高可用Hadoop平台>的尾声篇了,从搭建安装到入门运行 Hadoop 版的 HelloWorld(WordCount 可以称的上是 Hadoop 版的 Hel ...

  8. 高可用Hadoop平台-实战

    1.概述 今天继续<高可用的Hadoop平台>系列,今天开始进行小规模的实战下,前面的准备工作完成后,基本用于统计数据的平台都拥有了,关于导出统计结果的文章留到后面赘述.今天要和大家分享的 ...

  9. 三分钟快速搭建分布式高可用的Redis集群

    这里的Redis集群指的是Redis Cluster,它是Redis在3.0版本正式推出的专用集群方案,有效地解决了Redis分布式方面的需求.当单机内存.并发.流量等遇到瓶颈的时候,可以采用这种Re ...

随机推荐

  1. 转!idea启动后发现tomcat前面出现红色或是灰色的问号

    原博文地址:https://blog.csdn.net/z_zhy/article/details/83068168 直接在idea里 点击File------settings,在搜索框直接搜tomc ...

  2. Python开发【Django】:分页、Cookie和Session

    分页 1.简单分页 涉及xss攻击,需要用到mark_safe方法,使用此方法字符串传输到后端后,已html形式显示,而非字符串 HTML文件: <!DOCTYPE html> <h ...

  3. 以太坊geth主网全节点部署

    以太坊geth主网全节点部署 #环境 ubuntu 16.4 #硬盘500GB(目前占用200G) #客户端安装 # 查看下载页面最新版 # https://ethereum.github.io/go ...

  4. MySQL插入性能优化(转)

    原文:http://tech.uc.cn/?p=634 对于一些数据量较大的系统,数据库面临的问题除了查询效率低下,还有就是数据入库时间长.特别像报表系统,每天花费在数据导入上的时间可能会长达几个小时 ...

  5. oracle高水位问题

    转自:https://blog.csdn.net/cnham/article/details/5987999 说到HWM,我们首先要简要的谈谈ORACLE的逻辑存储管理.我们知道,ORACLE在逻辑存 ...

  6. ELK日志分析工具

    一.ELK介绍 1.1 elasticsearch 1.1.1 elasticsearch介绍 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎 ...

  7. vim多行注释和取消注释 Ubuntu

    多行注释: 1. 进入命令行模式,按ctrl + v进入 visual block模式,然后按d 是选择到最后一行,也可以直接光标上下左右,把需要注释的行标记起来 2. 按大写字母I,再插入注释符,例 ...

  8. 【android】开发笔记系列:行为篇

    1:键盘遮挡了输入框 在androidManifest.xml里,对应的activity里设置键盘模式 <activity android:name="活动名称" andro ...

  9. ng-深度学习-课程笔记-2: 神经网络中的逻辑回归(Week2)

    1 二分类( Binary Classification ) 逻辑回归是一个二分类算法.下面是一个二分类的例子,输入一张图片,判断是不是猫. 输入x是64*64*3的像素矩阵,n或者nx代表特征x的数 ...

  10. P1291 [SHOI2002]百事世界杯之旅(概率)

    P1291 [SHOI2002]百事世界杯之旅 设$f(n,k)$表示共n个名字,剩下k个名字未收集到,还需购买饮料的平均次数 则有: $f(n,k)=\frac{n-k}{n}*f(n,k) + \ ...