java 固定长度队列_如何彻底搞懂 Java 数据结构?|CSDN 博文精选

d646d35573ef75c7c880397b119179fa.png

作者 | 张振华.Jack

责编 | 郭芮

出品 | CSDN 博客

本文和大家一起来重温《Java数据结构》经典之作。

80bed2afb2d6592e8c4759a65253215d.png

Java数据结构

要理解Java数据结构,必须能清楚何为数据结构?

数据结构:

  1. Data_Structure,它是储存数据的一种结构体,在此结构中储存一些数据,而这些数据之间有一定的关系。

  2. 而各数据元素之间的相互关系,又包括三个组成成分,数据的逻辑结构,数据的存储结构和数据运算结构。

  3. 而一个数据结构的设计过程分成抽象层、数据结构层和实现层。

数据结构在Java的语言体系中按逻辑结构可以分为两大类:线性数据结构和非线性数据结构。

一、Java数据结构之:线性数据结构

线性数据结构:常见的有一维数组,线性表,栈,队列,双队列,串。

1、一维数组

在Java里面常用的util有:String ,int ,ArrayList,Vector,CopyOnWriteArrayList等,及可以通过一维数组自己实现不同逻辑结构的Util类,而ArrayList封装了一些的基本操作方法。

ArrayList和Vector的区别是:Vector是线程安全的,方法同步。CopyOnWriteArrayList也是线程安全的但效率要比Vector高很多。

数组这种数据结构典型的操作方法,是根据下标进行操作的,所以insert的的时候可以根据下标插入到具体的某个位置,但是这个时候它后面的元素都得往后面移动一位。所以插入效率比较低,更新,删除效率也比较低,而查询效率非常高,查询效率时间复杂度是1。

2、线性表

线性表是有序的储存结构、链式的储存结构。链表的物理储存空间是不连续的,链表的每一个节点都知道上一个节点、或者下一个节点是谁,通常用Node表示。常见的有顺序链表(LinkedList、Linked***),单项链表(里面只有Node类),双向链表(两个Node类),循环链表(多个Node类)等。

操作方法:插入效率比较高,插入的时候只需要改变节点的前后节点的连接即可。而查询效率就比较低了,如果实现的不好,需要整个链路找下去才能找到应该找的元素。所以常见的方法有:add(index,element),addFirst(element),addLast(element),getFirst,getLast,get(element)等。

常见的Uitil有:LinkedList,LinkedMap等,而这两个JDK底层也做了N多优化,可以有效避免查询效率低的问题,当自己实现的时候需要注意。其实树形结构可以说是非线性的链式储存结构。

3、栈Stack

栈,最主要的是要实现先进后出,后进先出的逻辑结构。来实现一些场景对逻辑顺序的要求。所以常用的方法有push(element)压栈,pop出栈。

java.util.Stack就实现了这用逻辑,而Java的Jvm里面也用的到了此种数据结构,就是线程栈,来保证当前线程的执行顺序。

4、队列

队列,队列是一种特殊的线性数据结构,队列只能允许在队头,队尾进行添加和查询等相关操作。队列又有单项有序队列、双向队列、阻塞队列等。

Queue这种数据结构注定了基本操作方法有:add(E e)加入队列,remove,poll等方法。

队列在Java语言环境中是使用频率相当高的数据结构,所有其实现的类也很多来满足不同场景。

de7a68f28fa331d73d7638ccf0882a01.png

queue

使用场景也非常多,如线程池、MQ、连接池等。

5、

串:也称字符串,是由N个字符组成的优先序列。在Java里面就是指String,而String里面是由chat来进行储存。

KMP算法: 这个算法一定要牢记,Java数据结构这本书里面针对字符串的查找匹配算法也只介绍了一种。关键点就是:在字符串比对的时候,主串的比较位置不需要回退的问题。

二、Java数据结构之:非线性数据结构

非线性数据结构:常见的有:多维数组,集合,树,图,散列表(hash)。

1、多维数组

一维数组前面咱也提到了,多维数组无非就是String ,int等。Java里面很少提供这样的工具类,而Java里面tree和图底层的native方法用了多维数组来储存。

2、集合

由一个或多个确定的元素所构成的整体叫做集合,在Java里面可以去广义的去理解为实现了Collection接口的类都叫集合。

2a7d3838f3cb3a22005ef11af977089c.png

Collection

3、

树形结构,作者觉得它是一种特殊的链形数据结构。最少有一个根节点组成,可以有多个子节点。树,显然是由递归算法组成。

树的特点:

  1. 在一个树结构中,有且仅有一个结点没有直接父节点,它就是根节点;

  2. 除了根节点,其他结点有且只有一个直接父节点;

  3. 每个结点可以有任意多个直接子节点。

树的数据结构又分如下几种:

1) 自由树/普通树:对子节点没有任何约束。

614b827b1cfa1be5dc3fc74c0c7e1a53.png

自由树

2) 二叉树:每个节点最多含有两个子节点的树称为二叉树。

2.1) 一般二叉树:每个子节点的父亲节点不一定有两个子节点的二叉树成为一般二叉树。

2.2) 完全二叉树:对于一颗二叉树,假设其深度为d(d>1)。除了第d层外,其它各层的节点数目均已达最大值,且第d层所有节点从左向右连续地紧密排列,这样的二叉树被称为完全二叉树;

2.3) 满二叉树:所有的节点都是二叉的二叉树成为满二叉树。

daea119d182f57aa51a9f8f067cf8ea2.png

二叉树

3) 二叉搜索树/BST:binary search tree,又称二叉排序树、二叉查找树。是有序的。要点:如果不为空,那么其左子树节点的值都小于根节点的值;右子树节点的值都大于根节点的值。

32117efee99535ea96f98a752602434c.png

二叉搜索

3.1) 二叉平衡树:二叉搜索树,是有序的排序树,但左右两边包括子节点不一定平衡,而二叉平衡树是排序树的一种,并且加点条件,就是任意一个节点的两个叉的深度差不多(比如差值的绝对值小于某个常数,或者一个不能比另一个深出去一倍之类的)。这样的树可以保证二分搜索任意元素都是O(log n)的,一般还附带带有插入或者删除某个元素也是O(log n)的的性质。

为了实现,二叉平衡树又延伸出来了一些算法,业界常见的有AVL、和红黑算法,所以又有以下两种树:

3.1.1) AVL树:最早的平衡二叉树之一。应用相对其他数据结构比较少。windows对进程地址空间的管理用到了AVL树。

3.1.2) 红黑树:通过制定了一些红黑标记和左右旋转规则来保证二叉树平衡。

9fe139621cc191348171b7ef1643e803.png

红黑树

红黑树的5条性质:

  1. 每个结点要么是红的,要么是黑的。

  2. 根结点是黑的。

  3. 每个叶结点(叶结点即指树尾端NIL指针或结点)是黑的。

  4. 如果一个结点是红的,那么它的俩个儿子都是黑的。

  5. 对于任一结点而言,其到叶结点树尾端NIL指针的每一条路径都包含相同数目的黑结点。

4) B-tree:又称B树、B-树。又叫平衡(balance)多路查找树。树中每个结点最多含有m个孩子(m>=2)。它类似普通的平衡二叉树,不同的一点是B-树允许每个节点有更多的子节点。

3ab13befafa5a7074d6f8be45b47e85a.png

B-tree

4) B+tree:又称B+。是B-树的变体,也是一种多路搜索树。

983a6f7d68a96c6c6477e92bad2afa36.png

B+tree

树总结: 树在Java里面应用的也比较多。非排序树,主要用来做数据储存和展示。而排序树,主要用来做算法和运算,HashMap里面的TreeNode就用到了红黑树算法。而B+树在数据库的索引原理里面有典型的应用。

4、Hash

Hash概念:

  • Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),变换成固定长度的输出,该输出就是散列值。一般通过Hash算法实现。

  • 所谓的Hash算法都是散列算法,把任意长度的输入,变换成固定长度的输出,该输出就是散列值(如:MD5,SHA1,加解密算法等)。

  • 简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

Java中的hashCode:

  • 我们都知道所有的class都是Object的子类,既所有的class都会有默认Object.java里面的hashCode的方法,如果自己没有重写,默认情况就是native方法通过对象的内存的+对象的值然后通过hash散列算法计算出来个int的数字。

  • 最大的特性是:不同的对象,不同的值有可能计算出来的hashCode可能是一样的。

Hash表:

Java中数据存储方式最底层的两种结构,一种是数组,另一种就是链表。而Hash表就是综合了这两种数据结构。

如:HashTable,HashMap。这个时候就得提一下HashMap的原理了,默认16个数组储存,通过Hash值取模放到不同的桶里面去。(注意:JDK1.8此处算法又做了改进,数组里面的值会演变成树形结构。)

哈希表具有较快(常量级)的查询速度,及相对较快的增删速度,所以很适合在海量数据的环境中使用。一般实现哈希表的方法采用“拉链法”,我们可以理解为“链表的数组”。

5f11fb253e4f17b8d280770904157b44.png

哈希表

一致性Hash:

我们查看一下HashMap的原理,其实发现Hash很好的解决了单体应用情况下的数据查找和插入的速度问题。但是毕竟单体应用的储存空间是有限的,所有在分布式环境下,应运而生了一致性Hash算法。

用意和hashCode的用意一样,只不过它是取模放在不同的IP机器上而已。具体算法可以找一下相关资料。

而一致性Hash需要注意的就是默认分配的桶比较多些,而当其中一台机器挂了,影响的面比较小一些。

需要注意的是,相同的内容算出来的hash一定是一样的。既:幂等性。

7166b031414688f5a9c1f05a32cf0830.png

一致性Hash

a84b0a057a4e7718ce8eea4c9577864d.png

Java基本算法

理解了Java数据结构,还必须要掌握一些常见的基本算法。理解算法之前必须要先理解的几个算法的概念:

空间复杂度:一句来理解就是,此算法在规模为n的情况下额外消耗的储存空间。

时间复杂度:一句来理解就是,此算法在规模为n的情况下,一个算法中的语句执行次数称为语句频度或时间频度。

稳定性:主要是来描述算法,每次执行完,得到的结果都是一样的,但是可以不同的顺序输入,可能消耗的时间复杂度和空间复杂度不一样。

一、二分查找算法

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好,占用系统内存较少;其缺点是要求待查表为有序表,且插入删除困难。这个是基础,最简单的查找算法了。

public static void main(String[] args) {

int srcArray = {3,5,11,17,21,23,28,30,32,50,64,78,81,95,101};

System.out.println(binSearch(srcArray, 28));

}

/**

* 二分查找普通循环实现

*

* @param srcArray 有序数组

* @param key 查找元素

* @return

*/

public static int binSearch(int srcArray[], int key) {

int mid = srcArray.length / 2;

// System.out.println("=:"+mid);

if (key == srcArray[mid]) {

return mid;

}

//二分核心逻辑

int start = 0;

int end = srcArray.length - 1;

while (start <= end) {

// System.out.println(start+"="+end);

mid = (end - start) / 2 + start;

if (key < srcArray[mid]) {

end = mid - 1;

} else if (key > srcArray[mid]) {

start = mid + 1;

} else {

return mid;

}

}

return -1;

}

二分查找算法如果没有用到递归方法的话,只会影响CPU。对内存模型来说影响不大。时间复杂度log2n,2的开方。空间复杂度是2。一定要牢记这个算法。应用的地方也是非常广泛,平衡树里面大量采用。

二、递归算法

递归简单理解就是方法自身调用自身。

public static void main(String[] args) {

int srcArray = {3,5,11,17,21,23,28,30,32,50,64,78,81,95,101};

System.out.println(binSearch(srcArray, 0,15,28));

}

/**

* 二分查找递归实现

*

* @param srcArray 有序数组

* @param start 数组低地址下标

* @param end 数组高地址下标

* @param key 查找元素

* @return 查找元素不存在返回-1

*/

public static int binSearch(int srcArray[], int start, int end, int key) {

int mid = (end - start) / 2 + start;

if (srcArray[mid] == key) {

return mid;

}

if (start >= end) {

return -1;

} else if (key > srcArray[mid]) {

return binSearch(srcArray, mid + 1, end, key);

} else if (key < srcArray[mid]) {

return binSearch(srcArray, start, mid - 1, key);

}

return -1;

}

递归几乎会经常用到,需要注意的一点是:递归不光影响的CPU。JVM里面的线程栈空间也会变大。所以当递归的调用链长的时候需要-Xss设置线程栈的大小。

三、八大排序算法

  • 直接插入排序(Insertion Sort)

  • 希尔排序(Shell Sort)

  • 选择排序(Selection Sort)

  • 堆排序(Heap Sort)

  • 冒泡排序(Bubble Sort)

  • 快速排序(Quick Sort)

  • 归并排序(Merging Sort)

  • 基数排序(Radix Sort)

八大算法,网上的资料就比较多了。吐血推荐参考资料:git hub 八大排序算法详解(https://itimetraveler.github.io/index.html)。此大神比作者讲解的还详细,作者就不在这里,描述重复的东西了,作者带领大家把重点的两个强调一下,此两个是必须要掌握的。

1、冒泡排序

基本思想:

冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

以下是冒泡排序算法复杂度:

平均时间复杂度最好情况最坏情况空间复杂度
O(n²)O(n)O(n²)O(1)

冒泡排序是最容易实现的排序, 最坏的情况是每次都需要交换, 共需遍历并交换将近n²/2次, 时间复杂度为O(n²). 最佳的情况是内循环遍历一次后发现排序是对的, 因此退出循环, 时间复杂度为O(n). 平均来讲, 时间复杂度为O(n²). 由于冒泡排序中只有缓存的temp变量需要内存空间, 因此空间复杂度为常量O(1).

Tips:由于冒泡排序只在相邻元素大小不符合要求时才调换他们的位置, 它并不改变相同元素之间的相对顺序, 因此它是稳定的排序算法。

/**

* 冒泡排序

*

* ①. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。

* ②. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

* ③. 针对所有的元素重复以上的步骤,除了最后一个。

* ④. 持续每次对越来越少的元素重复上面的步骤①~③,直到没有任何一对数字需要比较。

* @param arr 待排序数组

*/

public static void bubbleSort(int[] arr){

for (int i = arr.length; i > 0; i--) { //外层循环移动游标

for(int j = 0; j < i && (j+1) < i; j++){ //内层循环遍历游标及之后(或之前)的元素

if(arr[j] > arr[j+1]){

int temp = arr[j];

arr[j] = arr[j+1];

arr[j+1] = temp;

System.out.println("Sorting: " + Arrays.toString(arr));

}

}

}

}

2、快速排序

3b043e0820ad2b649b390a95b387a9cc.gif

快速排序

快速排序使用分治策略来把一个序列(list)分为两个子序列(sub-lists)。步骤为:

①从数列中挑出一个元素,称为”基准”(pivot)。

②重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。

③递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。

递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

代码实现:

用伪代码描述如下:

①i = L; j = R; 将基准数挖出形成第一个坑a[i]。

②j--,由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。

③i++,由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。

④再重复执行②,③二步,直到i==j,将基准数填入a[i]中。

快速排序采用“分而治之、各个击破”的观念,此为原地(In-place)分区版本。

04a54b6c12926bf19469a62033700c6a.png

快速排序 In-place

/**

* 快速排序(递归)

*

* ①. 从数列中挑出一个元素,称为"基准"(pivot)。

* ②. 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。

* ③. 递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。

* @param arr 待排序数组

* @param low 左边界

* @param high 右边界

*/

public static void quickSort(int[] arr, int low, int high){

if(arr.length <= 0) return;

if(low >= high) return;

int left = low;

int right = high;

int temp = arr[left]; //挖坑1:保存基准的值

while (left < right){

while(left < right && arr[right] >= temp){ //坑2:从后向前找到比基准小的元素,插入到基准位置坑1中

right--;

}

arr[left] = arr[right];

while(left < right && arr[left] <= temp){ //坑3:从前往后找到比基准大的元素,放到刚才挖的坑2中

left++;

}

arr[right] = arr[left];

}

arr[left] = temp; //基准值填补到坑3中,准备分治递归快排

System.out.println("Sorting: " + Arrays.toString(arr));

quickSort(arr, low, left-1);

quickSort(arr, left+1, high);

}

以下是快速排序算法复杂度:

平均时间复杂度最好情况最坏情况空间复杂度
O(nlog₂n)O(nlog₂n)O(n²)O(1)(原地分区递归版)

快速排序排序效率非常高。虽然它运行最糟糕时将达到O(n²)的时间复杂度, 但通常平均来看, 它的时间复杂为O(nlogn), 比同样为O(nlogn)时间复杂度的归并排序还要快. 快速排序似乎更偏爱乱序的数列, 越是乱序的数列, 它相比其他排序而言, 相对效率更高。

最后,作者希望让大家对《Java数据结构》整体有个全面的了解,知道什么是数据结构,离我们工作中有多远,而不是一个深不可测的神秘物件。里面的细节,篇幅有限可能不能描述完,但是只要同学们的方向没有搞错,那只要针对每个点再详细的看看即可。

面试和工作,这些都是离不开的,当同学们有个完整的认识之后,一定要在工作中留心,留意每个用到的地方。

【End】

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

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

相关文章

IdentityServer4 之 Resource Owner Password Credentials 其实有点尴尬

前言接着IdentityServer4的授权模式继续聊&#xff0c;这篇来说说 Resource Owner Password Credentials授权模式&#xff0c;这种模式在实际应用场景中使用的并不多&#xff0c;只怪其太开放啦&#xff0c;直接在客户端上拿着用户名和密码就去授权服务器获取AccessToken&#…

Xamarin使XRPC实现接口/委托远程调用

在之前的文章中已经介绍如何使用Beetlex.XRCP组件进行接口/委托远程调用&#xff1b;由于组件BeetleX.XRPC.Clients支持.NETStandard2&#xff0c;因此Xamarin同样可以使用它来实现基于接口/委托的数据交互通讯。接下来通过Xamarin实现一个简单的移动程序&#xff0c;并通过XRP…

mysql 拷贝安装_Mysql的安装和主从复制

安装mysql服务步骤一&#xff1a;首先下载mysql的yum源配置 &#xff0c;下载mysql的yum源wget http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm步骤二&#xff1a;安装mysql的yum源yum -y install mysql57-community-release-el7-11.noarch.rpm步骤三&…

浅谈CLR基础知识

中午的时候&#xff0c;有一个小伙伴问我&#xff0c;CLR到底是进程还是线程&#xff0c;它和自己写的程序是怎么关联的。这一问&#xff0c;直接把我问懞了。下面我尝试用简单的语言来描述这个问题&#xff0c;有的地方无法讲的太细&#xff08;不然内容会太多&#xff09;&am…

Asp.Net Core使用Skywalking实现分布式链路追踪

介绍Skywalking 是 Apache 基金会下面的一个开源 APM 项目&#xff0c;是一套(APM)分布式追踪系统&#xff0c;提供了很多数据存储列如&#xff1a;Mysql&#xff0c;H2&#xff0c;Elasticsearch7 等。其中APM 全称是应用性能监测软件&#xff0c;主要是用来处理以及追踪分布式…

python 里什么时候缩进_python什么时候缩进

Python中的缩进(Indentation)决定了代码的作用域范围。这一点和传统的c/c有很大的不同(传统的c/c使用花括号花括号{}符决定作用域的范围&#xff1b;python使用缩进空格来表示作用域的范围&#xff0c;相同缩进行的代码是处于同一范围)。每行代码中开头的空格数(whitespace)用于…

C# 9 新特性 —— 补充篇

C# 9 新特性 —— 补充篇Intro前面我们分别介绍了一些 C# 9 中的新特性&#xff0c;还有一些我觉得需要了解一下的新特性&#xff0c;写一篇作为补充。Top-Level Statements在以往的代码里&#xff0c;一个应用程序必须要有 Main 方法才能运行&#xff0c;从 C# 9 开始&#xf…

使用Popup窗口创建无限级Web页菜单(5)

代码框架在(4)里面已经全部列出来了&#xff0c;现在工作就是按流程把他们完成。本来实现一个prototype的Menu菜单类只需要最多300行代码&#xff0c;可是后来做了一些操作习惯支持和UI显示上的优化后&#xff0c;代码猛增到了1000多行。不过final版本看起来确实比土不拉叽的pr…

【gRPC】ProtoBuf 语言快速学习指南

继上篇【gRPC】 在.Net core中使用gRPC了解了gRPC的使用&#xff0c;gRPC基于HTTP/2和ProtoBuf&#xff0c;ProtoBuf就非常有必要好好了解一下了&#xff0c;那么ProtoBuf究竟是什么&#xff1f;ProtoBuf Google Protocol Buffer是一种语言无关、平台无关、可扩展的序列化结构数…

vspythonqt混合_PYQT5 vscode联合操作qtdesigner的方法

除了使用pycharm外&#xff0c;还可使用vscode来操作pyqt&#xff0c;方法如下&#xff1a;1. 在vscode中配置相关的pyqt的相关根据自己实际情况修改第一项pyqt的路径2. 创建一个文件夹&#xff0c;右键&#xff0c;最后一项可以创建一个新窗口创建的新窗口后缀为 .ui右键中有以…

TIOBE 1 月榜单:Python年度语言四连冠,C 语言再次第一

喜欢就关注我们吧&#xff01;TIOBE 公布了 2021 年 1 月的编程语言排行榜。TIOBE 本月公布了 2020 年度编程语言&#xff0c;Python 获得四连冠&#xff0c;是过去一年中最受欢迎的编程语言。Python 在 2020 年实现了 2.01&#xff05; 的正增长&#xff1b;C 紧随其后&#x…

A piecture of J2EE Core Patterns

这张图是J2EE Core Patterns里面的一幅图片,在Enterprise Solution Patterns Using Microsoft.Net里面虽然模式的概念与应用大同小异&#xff0c;但是那张表现架构模式整体的图感觉有点不直观,相比之下这幅图显得更清晰一点。 发到这里供大家参考学习&#xff1a;&#xff09…

孙丕恕离开浪潮 仪器厂历时60年成为服务器龙头企业

2020年12月31日浪潮集团有限公司董事会选举邹庆忠为公司董事长&#xff08;法定代表人&#xff09;&#xff1b;孙丕恕不再担任公司董事长&#xff1b;公司不再聘任孙丕恕为首席执行官。另外&#xff0c;经省委研究决定&#xff0c;拟任省直部门&#xff08;单位&#xff09;副…

java 数组 树_java使用顺序数组实现二叉树

顺序数组实现二叉树实现原理对于下标为index的节点其满足1.左孩子节点的下标为2index12.右孩子节点的下标为2index2代码实现package tree;public class ArrayBinaryTree {private int[] arr;public ArrayBinaryTree(int[] arr){this.arrarr;}public void preOrder(int index){i…

【Docker】Asp.net core在docker容器中的端口问题

还记得【One by one系列】一步步学习docker&#xff08;三&#xff09;——实战部署dotnetcore中遇到的问题么&#xff1f;容器内部启动始终是80端口&#xff0c;并不由命令左右。docker run --name container-name -p 81:5000 mywebapi所谓知其然就要知其所以然&#xff0c;浅…

.net 5.0 中的 JsonConsole

asp.net core 5.0 中的 JsonConsoleIntroasp.net core 5.0 中日志新增了 JsonConsole&#xff0c;还是输出日志到 Console&#xff0c;但是会应用 Json 格式的一个 Formatter 把日志格式化成 json 再输出到控制台Sample一起来看一个示例&#xff0c;以我的一个小项目为例子来演…

采用开源软件搭建WebGIS系统(6)数据格式

[本文版权由xiaotievip.sina.com所有&#xff0c;转载需得到作者同意。] 在国家基础地理信息中心下载到的数据格式是Shape file数据。Shape file数据由3个文件构成&#xff0c;*.shp&#xff0c;*.dbf和*.shx&#xff0c;分别存储空间数据、属性数据和两者间的关系。*.shp得专门…

.NET Core 使用Topshelf方式创建Windows服务

Topshelf是一个.NET Standard库&#xff0c;它消除了在.NET Framework和.NET Core中创建Windows服务的那些麻烦。安装Install-Package Topshelf代码using System; using System.Collections.Generic; using System.Text; using Topshelf;namespace ConsoleApp2222 {public clas…

Roslyn 使用 Directory.Build.props 管理多个项目配置

在一些大项目需要很多独立的仓库来做&#xff0c;每个仓库之间都会有很多相同的配置&#xff0c;本文告诉大家如何通过 Directory.Build.props 管理多个项目配置在我的 MVVM 框架需要三个不同的库&#xff0c;一个是 Framework 另外两个是 WPF 和 UWP 这三个库有很多重复的配置…

java 中符号_谁能告诉我java中符号的用法,见代码

展开全部大家都知道Vector以及其他的容器可以不加任何修饰地e68a8462616964757a686964616f31333236373765存储任何类型的对象,这给我们带来了极大的方便&#xff0c;也使得容器很容易被复用&#xff0c;但是大多数时候我们可能需要只能存储某一类型对象的Vector&#xff0c;这是…