Hadoop入门(十一)Mapreduce的InputFomrat各种子类

一、TextInputFormat

extends FileInputFomrat<LongWritable,Text>  是默认读取文件的切分器,其内的LineRecordReader:用来读取每一行的内容,

  LineRecordReader:内的 nextKeyValue(){}中,key的赋值在:

  initialize()方法内, key=start=split.getStart();   split假如对应文件 hello.txt 期内为hello you  hello me

  那么起始位置就是0

  end = start + split.getLength(),

  而行文本在方法 读取到的行字节长度=readLine(...)中读取,对应到LineReader.readLine(...) 170行

  string key = getCurrentKey()   string value = getCurrentValue() 中得到

  然后在Mapper类中:

 while(LineRecordReader.nextKeyValue()){key = linerecordreader.getCurrentKey()'value = linerecordreader.getCurrentValue()map.(key,value,context); //不停的将键值对写出去
}

 

二、DBInputFormat

  DBInputFormat 在读取数据时,产生的键值对是 <LongWritable,DBWritable的实例>

    LongWritable仍旧是偏移量,

  可以参看 org.apache.hadoop.mapreduce.lib.db.DBRecordReader.nextKeyValue()/232行,如下

 key.set(pos + split.getStart());   来确认 表示的仍旧是偏移量

package inputformat;import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.net.URI;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;import mapreduce.MyWordCount;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.db.DBConfiguration;
import org.apache.hadoop.mapreduce.lib.db.DBInputFormat;
import org.apache.hadoop.mapreduce.lib.db.DBWritable;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;/*** 目的:    将mysql/test库/myuser表中将字段id,name对应的属性通过  mapreduce(下面例子仅是通过map  没有reduce操作)将记录写出到hdfs中* mysql--->map--->hdfs* 要运行本示例* 1.把mysql的jdbc驱动放到各TaskTracker节点的hadoop/mapreduce/lib目录下* 2.重启集群*/
public class MyDBInputFormatApp {private static final String OUT_PATH = "hdfs://hadoop0:9000/out";public static void main(String[] args) throws Exception {Configuration conf = new Configuration();//  连接数据库    代码尽量考前写  写在后面执行会报错    DBConfiguration.configureDB(conf, "com.mysql.jdbc.Driver", "jdbc:mysql://hadoop0:3306/test", "root", "admin");final FileSystem filesystem = FileSystem.get(new URI(OUT_PATH), conf);if (filesystem.exists(new Path(OUT_PATH))) {filesystem.delete(new Path(OUT_PATH), true);}final Job job = new Job(conf, MyDBInputFormatApp.class.getSimpleName());  //  创建job    job.setJarByClass(MyDBInputFormatApp.class);job.setInputFormatClass(DBInputFormat.class);//  指定inputsplit具体实现类    //  下面方法参数属性为:  操作javabean,  对应表名,  查询条件,排序要求,需要查询的表字段    DBInputFormat.setInput(job, MyUser.class, "myuser", null, null, "id", "name");//    //  设置map类和map处理的  key    value  对应的数据类型    job.setMapperClass(MyMapper.class);job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(NullWritable.class);job.setNumReduceTasks(0);              //指定不需要使用reduce,直接把map输出写入到HDFS中    job.setOutputKeyClass(Text.class);  //  设置job  output  key  输出类型    job.setOutputValueClass(NullWritable.class);//  设置job  output  value  输出类型    FileOutputFormat.setOutputPath(job, new Path(OUT_PATH));job.waitForCompletion(true);}//<k1,v1>对应的是数据库对应表下记录位置,和这行对应的JavaBean,      <k2,v2>表示经过map处理好输出结果    public static class MyMapper extends Mapper<LongWritable, MyUser, Text, NullWritable> {protected void map(LongWritable key, MyUser value, Context context) throws java.io.IOException, InterruptedException {context.write(new Text(value.toString()), NullWritable.get());};}/*** Writable是为了在Hadoop各节点之间传输使用的,因此需要实例化* DBWritable表示和数据库传输时使用的** @author zm*/public static class MyUser implements Writable, DBWritable {int id;String name;//  针对Writable  需要重写的方法    @Overridepublic void write(DataOutput out) throws IOException {out.writeInt(id);Text.writeString(out, name);}@Overridepublic void readFields(DataInput in) throws IOException {this.id = in.readInt();this.name = Text.readString(in);}//  针对DBWritable需要重写的方法    @Overridepublic void write(PreparedStatement statement) throws SQLException {statement.setInt(1, id);statement.setString(2, name);}@Overridepublic void readFields(ResultSet resultSet) throws SQLException {this.id = resultSet.getInt(1);this.name = resultSet.getString(2);}@Overridepublic String toString() {return id + "\t" + name;}}
}  

 

三、NLineInputFormat

 这种格式下,split的数量就不是由文件对应block块个数决定的, 而是由设置处理多少行决定,

  比如一个文件 100行, 设置NlineInputFormat 处理2行,那么会产生50个map任务, 每个map任务

  仍旧一行行的处理 会调用2次map函数、

package inputformat;import java.net.URI;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.NLineInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;/*** TextInputFormat处理的数据来自于一个InputSplit。InputSplit是根据大小划分的。* NLineInputFormat决定每个Mapper处理的记录数是相同的。* 设置map处理行数多,则需要产生的map个数就会减少*/
public class MyNLineInputFormatApp {private static final String INPUT_PATH = "hdfs://hadoop0:9000/hello";private static final String OUT_PATH = "hdfs://hadoop0:9000/out";public static void main(String[] args) throws Exception {//  定义conf    Configuration conf = new Configuration();//设置每个map可以处理多少条记录,默认是1行,这里设置为每个map处理的记录数都是2个    conf.setInt("mapreduce.input.lineinputformat.linespermap", 2);final FileSystem filesystem = FileSystem.get(new URI(OUT_PATH), conf);if (filesystem.exists(new Path(OUT_PATH))) {filesystem.delete(new Path(OUT_PATH), true);}//  定义job    final Job job = new Job(conf, MyNLineInputFormatApp.class.getSimpleName());job.setJarByClass(MyNLineInputFormatApp.class);//  定义  inputformat要处理的文件位置和具体处理实现类    FileInputFormat.setInputPaths(job, INPUT_PATH);job.setInputFormatClass(NLineInputFormat.class);//  设置map    job.setMapperClass(MyMapper.class);job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(LongWritable.class);//  设置reduce    job.setReducerClass(MyReducer.class);job.setOutputKeyClass(Text.class);job.setOutputValueClass(LongWritable.class);//  设置处理最终结果输出路径    FileOutputFormat.setOutputPath(job, new Path(OUT_PATH));job.waitForCompletion(true);}public static class MyMapper extends Mapper<LongWritable, Text, Text, LongWritable> {//解析源文件会产生2个键值对,分别是<0,hello  you><10,hello  me>;所以map函数会被调用2次    protected void map(LongWritable key, Text value, org.apache.hadoop.mapreduce.Mapper<LongWritable, Text, Text, LongWritable>.Context context) throws java.io.IOException, InterruptedException {//为什么要把hadoop类型转换为java类型?    final String line = value.toString();final String[] splited = line.split("\t");//产生的<k,v>对少了    for (String word : splited) {//在for循环体内,临时变量word的出现次数是常量1    context.write(new Text(word), new LongWritable(1));}};}//map函数执行结束后,map输出的<k,v>一共有4个,分别是<hello,1><you,1><hello,1><me,1>    //分区,默认只有一个区    //排序后的结果:<hello,1><hello,1><me,1><you,1>    //分组后的结果:<hello,{1,1}>    <me,{1}>    <you,{1}>    //归约(可选)    //map产生的<k,v>分发到reduce的过程称作shuffle    public static class MyReducer extends Reducer<Text, LongWritable, Text, LongWritable> {//每一组调用一次reduce函数,一共调用了3次    //分组的数量与reduce函数的调用次数有什么关系?    //reduce函数的调用次数与输出的<k,v>的数量有什么关系?    protected void reduce(Text key, java.lang.Iterable<LongWritable> values, org.apache.hadoop.mapreduce.Reducer<Text, LongWritable, Text, LongWritable>.Context context) throws java.io.IOException, InterruptedException {//count表示单词key在整个文件中的出现次数    long count = 0L;for (LongWritable times : values) {count += times.get();}context.write(key, new LongWritable(count));};}
}

 

四、KeyValueInputFormat

 如果行中有分隔符,那么分隔符前面的作为key,后面的作为value

 如果行中没有分隔符,那么整行作为key,value为空

 默认分隔符为 \t

package inputformat;import java.net.URI;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.KeyValueLineRecordReader;
import org.apache.hadoop.mapreduce.lib.input.KeyValueTextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;/*** 以hello文件内容为如下为例:* hello        you* hello        me* <p>* 特点是:* Each  line  is  divided  into  key  and  value  parts  by  a  separator  byte.  If  no* such  a  byte  exists,  the  key  will  be  the  entire  line  and  value  will  be  empty* 通过分隔符将每一行切分  切分后结果分别作为key  value* 如果没有分隔符,那么正一行就作为key    值为null* 如果一行中有多个制表符的话,会取第一个作为key  剩余作为value,后面的也不会再分割了* <p>* KeyValueInputForamt他用特定分隔符分割来形成自己的key  value,看源码(KeyValueLineRecordReader下为\t)默制默认分隔符为制表符* <p>* 输出结果为:* hello  1* you  1* helllo  1* me  1*/
public class MyKeyValueTextInputFormatApp {private static final String INPUT_PATH = "hdfs://hadoop0:9000/hello";private static final String OUT_PATH = "hdfs://hadoop0:9000/out";public static void main(String[] args) throws Exception {Configuration conf = new Configuration();conf.set(KeyValueLineRecordReader.KEY_VALUE_SEPERATOR, "\t");final FileSystem filesystem = FileSystem.get(new URI(OUT_PATH), conf);if (filesystem.exists(new Path(OUT_PATH))) {filesystem.delete(new Path(OUT_PATH), true);}//  创建job    final Job job = new Job(conf, MyKeyValueTextInputFormatApp.class.getSimpleName());job.setJarByClass(MyKeyValueTextInputFormatApp.class);//  设置InputFormat处理文件路径和具体操作实体类    FileInputFormat.setInputPaths(job, INPUT_PATH);job.setInputFormatClass(KeyValueTextInputFormat.class);//  设置map    job.setMapperClass(MyMapper.class);job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(LongWritable.class);//  设置reduce  这里reduce设置为0    job.setNumReduceTasks(0);job.setOutputKeyClass(Text.class);job.setOutputValueClass(LongWritable.class);//  设置最终结果输出路径    FileOutputFormat.setOutputPath(job, new Path(OUT_PATH));job.waitForCompletion(true);}public static class MyMapper extends Mapper<Text, Text, Text, LongWritable> {protected void map(Text key, Text value, org.apache.hadoop.mapreduce.Mapper<Text, Text, Text, LongWritable>.Context context) throws java.io.IOException, InterruptedException {context.write(key, new LongWritable(1));context.write(value, new LongWritable(1));}}
}  

GenericWritable

适用于 不同输入源下,多map输出类型不同

package inputformat;import java.net.URI;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.GenericWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.KeyValueTextInputFormat;
import org.apache.hadoop.mapreduce.lib.input.MultipleInputs;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;/*** MyMapper,  MyMapper2的  v2输出类型一个是longWritable,一个是String,  两者需要统一成一个输出类型,* 以方便job在设置v2类型---->  job.setMapOutputValueClass(MyGenericWritable.class)* <p>* 文件hello  内容为:* hello        you* hello        me* <p>* 文件hello2  内容为:* hello,you* hello,me** @author zm* <p>* <p>* 结果:* [root@master  hadoop]#  hadoop  fs  -text  /out/part-r-00000* Warning:  $HADOOP_HOME  is  deprecated.* <p>* hello      4* me            2* you          2*/
public class MyGenericWritableApp {private static final String OUT_PATH = "hdfs://master:9000/out";public static void main(String[] args) throws Exception {Configuration conf = new Configuration();final FileSystem filesystem = FileSystem.get(new URI(OUT_PATH), conf);if (filesystem.exists(new Path(OUT_PATH))) {filesystem.delete(new Path(OUT_PATH), true);}final Job job = new Job(conf, MyGenericWritableApp.class.getSimpleName());job.setJarByClass(MyGenericWritableApp.class);//  设置每种输入文件的位置      具体切分文件类    和对应的处理map类        MultipleInputs.addInputPath(job, new Path("hdfs://master:9000/hello"), KeyValueTextInputFormat.class, MyMapper.class);MultipleInputs.addInputPath(job, new Path("hdfs://master:9000/hello2"), TextInputFormat.class, MyMapper2.class);//  设置map    //job.setMapperClass(MyMapper.class);      //不应该有这一行    上面已经设置好了map类    job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(MyGenericWritable.class);//  设置reduce    job.setReducerClass(MyReducer.class);job.setOutputKeyClass(Text.class);job.setOutputValueClass(LongWritable.class);//  设置输出结果存放路径    FileOutputFormat.setOutputPath(job, new Path(OUT_PATH));job.waitForCompletion(true);}public static class MyMapper extends Mapper<Text, Text, Text, MyGenericWritable> {//解析源文件会产生2个键值对,分别是<hello,you>    <hello,me>;所以map函数会被调用2次    //  处理后结果为:  <hello,(MyGenericWritable(1),MyGenericWritable(1))>    <you,(MyGenericWritable(1))>    <me,(MyGenericWritable(1))>    protected void map(Text key, Text value, org.apache.hadoop.mapreduce.Mapper<Text, Text, Text, MyGenericWritable>.Context context) throws java.io.IOException, InterruptedException {context.write(key, new MyGenericWritable(new LongWritable(1)));context.write(value, new MyGenericWritable(new LongWritable(1)));};}public static class MyMapper2 extends Mapper<LongWritable, Text, Text, MyGenericWritable> {//解析源文件会产生2个键值对,分别是<0,(hello,you)><10,(hello,me)>;键值对内的()是我自己加上去的为了便于和前面偏移量的,区分开来  所以map函数会被调用2次    //  处理后结果为:  <hello,(MyGenericWritable("1"),MyGenericWritable("1"))>    <you,(MyGenericWritable("1"))>    <me,(MyGenericWritable("1"))>      protected void map(LongWritable key, Text value, org.apache.hadoop.mapreduce.Mapper<LongWritable, Text, Text, MyGenericWritable>.Context context) throws java.io.IOException, InterruptedException {//为什么要把hadoop类型转换为java类型?    final String line = value.toString();final String[] splited = line.split(",");//产生的<k,v>对少了    for (String word : splited) {System.out.println("MyMapper2  word  is:" + word);//在for循环体内,临时变量word的出现次数是常量1    final Text text = new Text("1");context.write(new Text(word), new MyGenericWritable(text));}};}//map产生的<k,v>分发到reduce的过程称作shuffle    public static class MyReducer extends Reducer<Text, MyGenericWritable, Text, LongWritable> {//每一组调用一次reduce函数,一共调用了3次    //分组的数量与reduce函数的调用次数有什么关系?    //reduce函数的调用次数与输出的<k,v>的数量有什么关系?    protected void reduce(Text key, java.lang.Iterable<MyGenericWritable> values, org.apache.hadoop.mapreduce.Reducer<Text, MyGenericWritable, Text, LongWritable>.Context context) throws java.io.IOException, InterruptedException {//count表示单词key在整个文件中的出现次数    long count = 0L;for (MyGenericWritable times : values) {final Writable writable = times.get();if (writable instanceof LongWritable) {count += ((LongWritable) writable).get();}if (writable instanceof Text) {count += Long.parseLong(((Text) writable).toString());}}context.write(key, new LongWritable(count));};}/*** @author zm*/public static class MyGenericWritable extends GenericWritable {public MyGenericWritable() {}public MyGenericWritable(Text text) {super.set(text);}public MyGenericWritable(LongWritable longWritable) {super.set(longWritable);}//  数组里面存放要处理的类型    @Overrideprotected Class<? extends Writable>[] getTypes() {return new Class[]{LongWritable.class, Text.class};}}
}

 

五、CombineTextInputFormat

将输入源目录下多个小文件 合并成一个文件(split)来交给mapreduce处理 这样只会生成一个map任务
比如用户给的文件全都是10K那种的文件, 其内部也是用的TextInputFormat 当合并大小大于(64M)128M的时候,
也会产生对应个数的split

SequenceFile

 也是合并还没明白和CombineTextInputFormat的区别在哪里:

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;import org.apache.commons.io.FileUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.SequenceFile.Writer;
import org.apache.hadoop.io.Text;public class SequenceFileMore {public static void main(String[] args) throws IOException, URISyntaxException {final Configuration conf = new Configuration();final FileSystem fs = FileSystem.get(new URI("hdfs://h2single:9000/"), conf);Path path = new Path("/sf_logs");//写操作    final Writer writer = new SequenceFile.Writer(fs, conf, path, Text.class, BytesWritable.class);//  false表示不迭代子目录    Collection<File> listFiles = FileUtils.listFiles(new File("/usr/local/logs"), new String[]{"log"}, false);for (File file : listFiles) {  //  将/usr/local/logs下的所有.log文件  以对应文件文件名为key    对应文件内容字节数组为value  共同写入到/sf_logs内    String fileName = file.getName();Text key = new Text(fileName);byte[] bytes = FileUtils.readFileToByteArray(file);BytesWritable value = new BytesWritable(bytes);writer.append(key, value);}IOUtils.closeStream(writer);//读操作    final SequenceFile.Reader reader = new SequenceFile.Reader(fs, path, conf);final Text key = new Text();final BytesWritable val = new BytesWritable();while (reader.next(key, val)) {String fileName = "/usr/local/logs_bak/" + key.toString();File file = new File(fileName);FileUtils.writeByteArrayToFile(file, val.getBytes());}IOUtils.closeStream(reader);}}    

 

MultipleInputs

对应于 多个文件处理类型下 比如又要处理数据库的文件 同时又要处理小文件

这里仅将main函数拼接展示下,各自对应的mapper类自己去写:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322975.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

欢乐纪中某B组赛【2019.1.21】

前言 成功翻车 成绩 RankRankRank是有算别人的 RankRankRankPersonPersonPersonScoreScoreScoreAAABBBCCC1414142017hzb2017hzb2017hzb8080803030300005050501414142017wyc2017wyc2017wyc8080800003030305050501414142017xxy2017xxy2017xxy8080803030300005050504444442017lw2…

极简版ASP.NET Core学习路径

拒绝承认这是一个七天速成教程&#xff0c;即使有这个效果&#xff0c;我也不愿意接受这个名字。嗯。 这个路径分为两块&#xff1a; 实践入门 理论延伸 有了ASP.NET以及C#的知识以及项目经验&#xff0c;我们几乎可以不再需要了解任何新的知识就开始操练&#xff0c;实践才是…

spring boot连接数据库

applicat.yml spring:datasource:username: rootpassword:url: jdbc:mysql://localhost:3306/test?useUnicodetrue&useJDBCCompliantTimezoneShifttrue&useLegacyDatetimeCodefalse&serverTimezoneUTCdriver-class-name: com.mysql.cj.jdbc.Drivertest文件夹下测…

依存句法分析的任务以及形式化定义

转载自 依存句法分析的任务以及形式化定义 依存句法分析的任务以及形式化定义 1、依存句法分析的形式化定义 在依存句法中&#xff0c;共同的基本假设是&#xff1a;句法结构本质上包含词和词对之间的关系。这种关系就是依存关系&#xff08;dependency relations&#xff…

jzoj3084-超级变变变【数学】

正题 题目大意 定义函数 f(x){x−1(x%21)x/2(x%20)f(x)\left\{\begin{matrix} &amp;x-1(x\%21)\\ &amp; x/2(x\%20) \end{matrix}\right.f(x){​x−1(x%21)x/2(x%20)​ 一次变化是将xf(x)xf(x)xf(x) 求A∼BA\sim BA∼B之间有多少个数可以变化到kkk 解题思路 其实就是…

使用Identity Server 4建立Authorization Server (5)

预备知识: 学习Identity Server 4的预备知识 第一部分: 使用Identity Server 4建立Authorization Server (1) 第二部分: 使用Identity Server 4建立Authorization Server (2) 第三部分: 使用Identity Server 4建立Authorization Server (3) 第四部分: 使用Identity Server 4建立…

idea如何安装lombok

https://github.com/mplushnikov/lombok-intellij-plugin/releases &#xff0c;Plugins -> Install plugin from disk… 选择下载的zip包安装&#xff0c;重启idea即可。 依赖包 <dependency><groupId>org.projectlombok</groupId><artifactId>lom…

好好说说Java中的常量池之Class常量池

转载自 好好说说Java中的常量池之Class常量池 在Java中&#xff0c;常量池的概念想必很多人都听说过。这也是面试中比较常考的题目之一。在Java有关的面试题中&#xff0c;一般习惯通过String的有关问题来考察面试者对于常量池的知识的理解&#xff0c;几道简单的String面试…

jzoj3085-图的计数【组合数,数论】

正题 题目大意 求有多少个m条边的有向图使得1到n的最短路长度为n-1 解题思路 首先长度为n−1n-1n−1那么就是1到n得先是一条链。在链上加m−n1m-n1m−n1条边且不能加如捷径边。 捷径边的条数为Cn−12C_{n-1}^2Cn−12​&#xff0c;然后可以加的边数就是n∗n−Cn−12n*n-C_{n-…

spring cloud+.net core搭建微服务架构:Api授权认证(六)

前言 这篇文章拖太久了&#xff0c;因为最近实在太忙了&#xff0c;加上这篇文章也非常长&#xff0c;所以花了不少时间&#xff0c;给大家说句抱歉。好&#xff0c;进入正题。目前的项目基本都是前后端分离了&#xff0c;前端分Web&#xff0c;Ios,Android。。。,后端也基本是…

如何用spring boot写一个注册页面

环境准备&#xff1a; java集成开发环境&#xff1a;IDEA 数据库&#xff1a;Mysql Maven 最好在安装有个navicat&#xff08;数据库可视化界面&#xff09; 安装好上述几个软件后 总结下&#xff1a;五步 1、创建新的工程 2、创建建applicatiom.yml 3、创建entity层 4、创建r…

Oracle入门(一)之入门级知识详解

转载自 Oracle入门级知识详解 一. Oracle基本介绍 1. 什么时候用Oracle数据库&#xff1f; SQL SERVER 号称百万级数据&#xff08;一个表的数据&#xff09;&#xff0c;但是其实做多20万条数据 超过20万条数据就用Oracle 2. Oracle的版本 Oracle8i/9i(internet)基于网络…

jzoj3086,luogu3831-[SHOI2012]回家的路【最短路,拆点】

正题 luogu评测记录:https://www.luogu.org/recordnew/lists?uid52918&pidP3831 题目大意 有n∗nn*nn∗n的铁路网走一格代价为2&#xff0c;mmm个中转站可以改变方向代价为1。求两个点之间的最短路。 解题思路 我们发现n∗nn*nn∗n很大&#xff0c;所以我们考虑根据mmm…

活动:北京Xamarin分享会第8期(2017年11月11日)

本期活动内容预告&#xff1a; 分享主题1: Tech Summit 2017大会课程 - 21世纪不动产使用Xamarin和Azure案例。 分享者&#xff1a;周岳, 微软MVP (Xamarin) , 北京视高盛景软件首席架构师 分享主题2: Tech Summit 2017大会课程 - AI: 清清爽爽几步&#xff0c;打造专属视觉分…

IDEA创建包不是树形

创建包的时候和别人的不一样&#xff0c;不是树形结构 可以点击图中的齿轮改变选项 把两个对勾取消掉就可以了 现在就是树形结构了

.NET Core跨平台的奥秘[下篇]:全新的布局

从本质上讲&#xff0c;按照CLI规范设计的.NET从其出生的那一刻就具有跨平台的基因&#xff0c;这与Java别无二致。由于采用了统一的中间语言&#xff0c;微软只需要针对不同的平台设计不同的虚拟机&#xff08;运行时&#xff09;就能弥合不同操作系统与处理器架构之间的差异&…

漫画:什么是拜占庭将军问题

转载自 漫画&#xff1a;什么是拜占庭将军问题 什么是拜占庭将军问题&#xff1f; 在很久很久以前&#xff0c;拜占庭是东罗马帝国的首都。那个时候罗马帝国国土辽阔&#xff0c;为了防御目的&#xff0c;因此每个军队都分隔很远&#xff0c;将军与将军之间只能靠信使传递消息…

欢乐纪中某A and B组赛【2019.1.23】

前言 翻车的更惨 成绩 RankRankRank是有算别人的 RankRankRankPersonPersonPersonScoreScoreScoreAAABBBCCC2929292017myself2017myself2017myself1601601607070700009090903636362017zyc2017zyc2017zyc1401401407070701010106060605454542017lw2017lw2017lw10010010050505000…

2019年度总结

还有两天就是2020年了&#xff0c;因此写一篇年度总结吧&#xff0c;以后争取每年都会写一篇的。 2019年回顾&#xff1a; 收获 2019年真是神奇的一年&#xff0c;对我而言&#xff0c;这一年收获的东西非常多&#xff0c;是我真正的入门编程的一年。 从二月份入门java到现在…

SQL Server 审计

审计&#xff08;Audit&#xff09;用于追踪和记录SQL Server实例或数据库中发生的事件&#xff0c;审计主要包括审计对象&#xff08;Audit&#xff09;和审计规范&#xff08;Audit Specification&#xff09;&#xff0c;创建审计首先需要创建一个SQL Server 实例级的审计对…