c#进阶(5)—— WCF 实现简单预订功能

1、WCF概述

WCF全称为Windows Communication Foundation,在.Net 3.0 中引入,用于客户端与服务端通信,替换了之前的一些技术,如.Net Remoting 及 WSE。

WCF 相比ASP.NET Web API 复杂,但提供了更多的功能,如

(1)、可靠性

(2)、事务

(3)、Web服务安全

如果不需要这些先进的通信功能,ASP.NET Web API是更好的选择。

2、WCF 主要功能

(1)、存储组件和服务,可以将WCF服务存放在ASP.NET 运行库、Windows服务、COM+进程或WPF应用程序中,进行对等计算

(2)、声明行为,不需要继承基类,可以使用属性定义服务。

(3)、通信信道,WCF提供了用HTTP、TCP、IPC信道进行通信的多条信道,支持自定义信道。

(4)、安全结构,为实现独立于平台的WEB服务,必须使用标准化的安全环境,标准用WSE3.0实现。

(5)、可扩展性,支持将功能注入客户端和服务端的消息流。

(6)总结

!最终目标:通过进程或不同系统,通过本地网络或Internet收发客户端和服务之间的消息,如果需要以独立于平台的方式尽快收发消息,就应该使用WCF。

!远距离视图

服务提供了一个端点,由协定、绑定、地址描述。

a:协定,定义了服务提供的操作

b:绑定,给出了协议和编码信息

c:地址,是服务的位置,客户端需要一个兼容的端点来进行访问。

3、WCF 组件及步骤解读

 

步骤解读:

(1)、客户端,客户端调用代理的一个方法

(2)、代理,代理将方法调用转化为一条消息,并把该消息传输到信道上。

(3)、信道,包含客户端部分及服务端部分,他们通过网络协议进行通信,在信道上,把消息传递给调度程序。

(4)、调度程序,将消息转换为服务调用的方法调用。

4、WCF 其他重要技术

(1)、SOAP协议

服务从客户端接收SOAP消息,并返回一条SOAP响应消息,SOAP消息包含信封,信封包含标题和正文。

(2)、WSDL

WSDL文档描述了服务的操作和消息,WSDL定义了服务的元数据,这些元数据用于为客户端应用程序创建代理。

WSDL包含如下信息:

a:消息的类型——用XML架构描述

b:从服务中收发的信息——消息的各部分用XML架构定义的类型

c:端口类型——映射服务协定,列出用服务协定定义的操作,操作包含信息,如与请求和响应序列一起使用的输入和输出消息

d:绑定信息——包含用端口类型列出的操作,并定义使用的SOAP变体

e:服务信息——把端口类型映射到端点地址

5、WCF实战——预定会议室

5.1 前言

业务场景,存储会议室预订信息,应用mysql数据库中的roomreservations表存储预订信息,

a:主要实施步骤包括

(1)创建服务和数据协定

(2)使用 自定义类库 访问数据库

(3)实现服务

(4)使用WCF服务宿主(Service Host)和WCF测试客户端(Test Client)

(5)创建定制的服务宿主

(6)使用元数据创建客户应用程序

(7)使用共享的协定创建客户应用程序

(8)配置诊断设置

b:主要包括:数据访问类、协定(服务协定、数据协定)、自定义宿主程序、客户端、服务实现。

类说明:

(1)Net.BCloudSoft.Core.DataAccess 数据访问底层代码。

RoomReservationData 调用数据访问提供的ExecuteNonQuery方法,实现数据的写入。

(2)RoomReservationContracts ,定义数据协定及服务协定,其中数据协定是数据实体映射,采用DataContract 及 DataMemeber 分别标记类及属性。服务协定,是一个接口类,包括服务协定及操作协定,接口类中声明方法,如ReserveRoom等,在类上添加ServiceContract,在方法上标记OperationContract。

(3)RoomReservationHost,自定义服务宿主,控制台程序,由StartService、StopService组成,Open方法会启动服务的监听器信道,Close方法会停止信道,主要用到的核心类是ServiceHost,ServiceHost类实例化时,可以将服务及服务地址进行处理。

(4)RoomReservationService 服务实现,实现服务协定中定义的接口方法。

(5)RoomReservationClient ,WPF作为客户端,右键添加服务引用,选取Service服务,此时会为RoomReservationService服务生成代理,代理类中会自动生成异步方法,使用async及await关键字调用ReserveRoomAsync() 异步方法,使订阅功能支持异步。

5.2 具体实现

(1)创建数据协定和服务协定

  整体结构:

1.1 创建数据协定

创建RoomReservationContracts类库,新建RoomReservation类,该类主要包含数据协定,具体属性字段与数据库中表对应。

复制代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
namespace RoomReservationContracts
{/// <summary>/// 数据协定/// </summary>[DataContract]public class RoomReservation : INotifyPropertyChanged{private int _id;private string _roomName;private DateTime _startTime;private DateTime _endTime;private string _contact;private string _text;/// <summary>///要通过WCF服务发送数据, 引入DataContract 和 DataMember 特性对该类进行注解/// </summary>[DataMember]public int Id{get { return _id; }set { SetProperty(ref _id, value); }}[DataMember][StringLength(45)]public string RoomName{get { return _roomName; }set { SetProperty(ref _roomName, value); }}[DataMember]public DateTime StartTime{get { return _startTime; }set { SetProperty(ref _startTime, value); }}[DataMember]public DateTime EndTime{get { return _endTime; }set { SetProperty(ref _endTime, value); }}[DataMember][StringLength(45)]public string Contact{get { return _contact; }set { SetProperty(ref _contact, value); }}[DataMember][StringLength(45)]public string Text{get { return _text; }set { SetProperty(ref _text, value); }}/// <summary>///  接口需实现的事件方法/// </summary>public event PropertyChangedEventHandler PropertyChanged;/// <summary>/// 得知属性发生变更时(定义为protected virtual 允许子类覆写本方法)/// </summary>/// <param name="propertyName">属性字段</param>protected virtual void OnNotifyPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}/// <summary>/// 设置属性/// </summary>/// <typeparam name="T">传入的类型参数</typeparam>/// <param name="item">字段名</param>/// <param name="value">字段值</param>/// <param name="propertyName"></param>protected virtual void SetProperty<T>(ref T item,T value,[CallerMemberName] string propertyName = null){//如果两个类型的对象T 是否不等if (!EqualityComparer<T>.Default.Equals(item, value)){item = value;OnNotifyPropertyChanged(propertyName);}}}
}

复制代码

1.2 创建服务协定

服务提供的操作可由接口定义,服务协定用ServiceContract特性定义,操作由OperationContract特性定义

复制代码

using System;
using System.ServiceModel;
namespace RoomReservationContracts
{/// <summary>/// 服务协定/// </summary>[ServiceContract(Namespace ="http://www.myfirstwcfservice.com/RoomReservation/2017")]public interface IRoomService{[OperationContract]bool ReserveRoom(RoomReservation roomReservation);[OperationContract]RoomReservation[] GetRoomReservations(DateTime fromTime, DateTime dateTime);}
}

复制代码

(2)、创建数据访问接口及实现类

本实例中使用自定义的数据访问类,基于反射实现的数据访问接口。采用该类添加RoomReservationData 类库,实现具体操作协定。

复制代码

using System;
using RoomReservationContracts;
using Net.BCloudSoft.Core.DataAccess;
using System.Data;
using System.Collections.Generic;namespace RoomReservationData
{/// <summary>/// 实现服务类/// </summary>public class RoomReservationRepository{/// <summary>/// 预订房间/// </summary>/// <param name="roomReservation"></param>public bool ReserveRoom(RoomReservation roomReservation){try{IDataAccess dataAccess = DataAccessFactory.Instance().GetDataAccess("server=127.0.0.1;database=wcfstudy_db;uid=root;pwd=admin;");string insertSql = string.Format("INSERT INTO wcfstudy_db.roomreservations VALUES" +"({0},'{1}','{2}','{3}','{4}','{5}')",roomReservation.Id,roomReservation.RoomName,roomReservation.StartTime,roomReservation.EndTime,roomReservation.Contact,roomReservation.Text);dataAccess.ExecuteNonQuery(insertSql);return true;}catch (Exception ex){throw ex;}}/// <summary>/// 获取所有预订信息/// </summary>/// <param name="fromTime"></param>/// <param name="toTime"></param>/// <returns></returns>public RoomReservation[] GetReservations(DateTime fromTime,DateTime toTime){try{IDataAccess dataAccess = DataAccessFactory.Instance().GetDataAccess("MySqlDataAccess");DataTable dt = dataAccess.ExecuteDataTable(string.Format("SELECT * FROM [wcfstudy_db].[roomreservations] WHERE [StartTime] > '{0}' AND [EndTime] <'{1}'", fromTime, toTime));List<RoomReservation> list = new List<RoomReservation>();foreach (DataRow row in dt.Rows){RoomReservation roomReservation = new RoomReservation();roomReservation.Id = int.Parse(row["Id"].ToString());roomReservation.RoomName = row["RoomName"].ToString();roomReservation.StartTime = Convert.ToDateTime(row["StartTime"]);roomReservation.EndTime = Convert.ToDateTime(row["EndTime"]);roomReservation.Contact = row["Contact"].ToString();roomReservation.Text = row["Text"].ToString();list.Add(roomReservation);}return list.ToArray();}catch (Exception ex){throw ex;}}}
}

复制代码

(3)、服务的实现

  3.1 基于 WCF 服务库直接生成的模型,默认包含服务协定和服务实现。

  a:根据模板创建的服务实现

 

  b:根据模板创建的服务协定

  3.2 如果客户应用程序只使用 元数据 信息来创建访问服务的代理,则使用visio studio 创建基于 WCF 服务库的模板是可行的。

但是,如果客户端直接使用协定类型,则最好把协定放在一个独立的程序集中如本例所示

 

  3.3 本案例中服务的实现

复制代码

using System;
using RoomReservationContracts;
using RoomReservationData;
using System.ServiceModel;namespace RoomReservationService
{[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]public class RoomReservationService : IRoomService{/// <summary>/// 获取所有预订信息/// </summary>/// <param name="fromTime">开始时间</param>/// <param name="dateTime">结束时间</param>/// <returns></returns>public RoomReservation[] GetRoomReservations(DateTime fromTime, DateTime dateTime){RoomReservationRepository repository = new RoomReservationRepository();return repository.GetReservations(fromTime, dateTime);}/// <summary>/// 预订房间/// </summary>/// <param name="roomReservation"></param>/// <returns></returns>public bool ReserveRoom(RoomReservation roomReservation){RoomReservationRepository repository = new RoomReservationRepository();return repository.ReserveRoom(roomReservation);}}
}

复制代码

    3.4 配置AppConfig

  在创建WCF 服务库时会创建AppConfig 文件,主要用于配置服务实现及服务协定,具体配置方法如下所示

复制代码

<?xml version="1.0" encoding="utf-8" ?>
<configuration><appSettings><add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /></appSettings><system.web><compilation debug="true" /></system.web><!-- 部署服务库项目时,必须将配置文件的内容添加到主机的 app.config 文件中。System.Configuration 不支持库的配置文件。 --><system.serviceModel><services><!--service 节点中 配置 实现类--><service name="RoomReservationService.RoomReservationService"><!--contract 节点中配置接口类--><endpoint address="" binding="basicHttpBinding" contract="RoomReservationContracts.IRoomService"><identity><dns value="localhost" /></identity></endpoint><endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /><host><baseAddresses><add baseAddress="http://localhost:8733/Design_Time_Addresses/RoomReservationService/Service1/" /></baseAddresses></host></service></services><behaviors><serviceBehaviors><behavior><!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false --><serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/><!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 --><serviceDebug includeExceptionDetailInFaults="False" /></behavior></serviceBehaviors></behaviors></system.serviceModel></configuration>

复制代码

 (4)使用WCF服务宿主和WCF测试客户端

  将RoomReservationService 类设置为启动项目,启动项目,WCF服务主机会启动WCF测试客户端,该测试客户端可用于测试应用程序,在输入参数后,点击‘调用’,会执行操作,输入测试数据可查看到响应结果。如下图:

   查看数据库,可知数据已经完成写入操作

 

(5)创建定制的服务宿主

使用WCF可以在任何宿主上运行服务,可以为对等服务创建一个WPF应用程序,可以创建一个Windows 服务,使用WAS 或 IIS 存放该服务,控制台程序也可以演示简单的自定义宿主。创建自定义宿主必须引入 System.ServiceModel和RoomReservationService。具体实现思路是,调用Open方法启动服务的监听器信道,该服务准备用于监听请求。Close方法会停止信道。代码如下:

复制代码

using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using RoomReservationService;
using static System.Console;/// <summary>
/// 自定义服务宿主
/// </summary>
namespace RoomReservationHost
{public class Program{internal static ServiceHost _serviceHost = null;/// <summary>/// 开启服务监听/// </summary>internal static void StartService(){try{//ServiceHost的构造函数第二个参数定义了服务的基地址,可以设置默认绑定,HTTP//的默认值是basicHttpBinding_serviceHost = new ServiceHost(typeof(RoomReservationService.RoomReservationService),new Uri("http://localhost:9000/RoomReservation"));_serviceHost.Description.Behaviors.Add(new ServiceMetadataBehavior{//获取设置一个值,指示是否发布服务元数据以使用Http/Get请求进行检索。HttpGetEnabled = true});}catch (AddressAccessDeniedException){WriteLine("地址禁止访问,使用netsh.exe 注册监听端口");throw;}}/// <summary>/// 停止服务监听/// </summary>internal static void StopService(){if(_serviceHost != null && _serviceHost.State== CommunicationState.Opened){_serviceHost.Close();}}static void Main(){StartService();WriteLine("服务正在运行,请退出");ReadLine();StopService();}}
}

复制代码

除以上使用编码方式实现WCF配置外,还可以通过,右键RoomReservationServcie 的App.config文件,点击 编辑 WCF 配置,如下图所示

 

(6)使用元数据创建客户应用程序

  此业务场景下,创建一个包含控件的WPF应用程序,命名为RoomReservationClient。如下图所示

添加服务引用,右键选取RoomReservationClient类库,添加 服务引用,点击发现,查找当前解决方案下的服务,将名称空间设置为RoomReservationService,这将为生成的代理类定义名称。如下图所示:

  根据数据协定把RoomReservation 引入到RoomReservationClient 中,RoomServiceClient 是RoomReservationService的客户端代理类(RoomServiceClient 是由上图执行后生成的),该客户端包含由操作协定定义的方法,使用这个客户端,可以将会议室预定信息发送给正在运行的服务。

在代码MainWindow.xaml.cs中,通过click 事件调用的OnReserveRoom方法,通过代理类调用ReserveRoomAsync。_roomReservation 为操作的数据源。代码如下

复制代码

using System;
using System.Windows;
using RoomReservationClient.RoomReservationService;namespace RoomReservationClient
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{private RoomReservationService.RoomReservation _roomReservation;public MainWindow(){InitializeComponent();_roomReservation.StartTime = DateTime.Now;_roomReservation.EndTime = DateTime.Now.AddHours(1);this.DataContext = _roomReservation;}private async void onReserveRoom(object sender, RoutedEventArgs e){//RoomServiceClient 是客户端的代理,该客户端包含由操作协定定义的方法,使用这个客户端,//可以将会议室预定信息发送给正在运行的服务。var client = new RoomServiceClient();bool reserved = await client.ReserveRoomAsync(_roomReservation);client.Close();if (reserved){MessageBox.Show("实体保存成功!");}}}
}

复制代码

6、最后

  参考的案例还有诊断及与客户端共享协定程序集两部分内容,两部分内容的具体实现并没有跟着书本完成,有兴趣的同学可以自行查看,参考的源代码路径为http://www.wrox.com/go/professionalcsharp6

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

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

相关文章

云原生架构重要组成部分之微服务

前言 近几年来&#xff0c;云计算与微服务架构非常火&#xff0c;运用广泛。各大厂商公司都运用了该技术架构&#xff0c;随着技术与理念的升级迭代&#xff0c;云原生概念应世而起&#xff0c;现在火的一塌糊涂。做为新时代的程序员&#xff0c;我们要抓住云原生的浪潮。 这篇…

第十届蓝桥杯——JAVA真题集锦

蓝桥杯百度百科&#xff1a; 蓝桥杯全国软件和信息技术专业人才大赛是由工业和信息化部人才交流中心举办的全国性IT学科赛事。共有北京大学、清华大学、上海交通大学等全国1200余所高校参赛&#xff0c;累计参赛人数超过40万人。2020年&#xff0c;蓝桥杯大赛被列入中国高等教育…

IIS与asp.net管道

阅读目录 asp.net是什么HTTP协议IIS与asp.netasp.net管道参考资料我们在基于asp.net开发web程序&#xff0c;基本上都是发布部署到安装了IIS的windows服务器上&#xff0c;然后只要用户能够访问就算任务完成了&#xff0c;但是很少静下心来想想这背后到底发生了什么&#xff0…

2022最新Spring相关大厂常问技术面试题大全 —— 金三银四好时机

Spring相关大厂常问面试题1. 什么是 Spring 框架?2. 列举一些重要的Spring模块&#xff1f;3. RestController 与 Controller 的区别4. 谈谈自己对于 Spring IoC 和 AOP 的理解5. Spring 中的 bean 的作用域有哪些?6. Spring 中的单例 bean 的线程安全问题了解吗7. Component…

C#进阶系列——AOP?AOP!

前言&#xff1a;今天大阅兵&#xff0c;可是苦逼的博主还得坐在电脑前写博客&#xff0c;为了弄清楚AOP&#xff0c;博主也是拼了。这篇打算写写AOP&#xff0c;说起AOP&#xff0c;其实博主接触这个概念也才几个月&#xff0c;了解后才知道&#xff0c;原来之前自己写的好多代…

SpringMVC大厂常问技术面试题大全 —— 金三银四进大厂

目录 ⭐你对SpringMVC框架的理解&#xff1f; ⭐SpringMVC主要组件&#xff1f; ⭐SpringMVC的执行流程以及各个组件的作用&#xff1f; ⭐SpringMVC支持的转发和重定向的写法&#xff1f; ⭐SpringMVC的常用注解&#xff1f; ⭐SpringMVC统一异常处理的思想和实现方式&a…

c#进阶(7)—— 异步编程基础(async 和 await 关键字)

async 和 await 关键字只是编译器功能&#xff0c;编译器会用Task类创建代码。 返 回值是一个Task&#xff0c;这种返回新线程的方法虽然可以提高系统的响应能力&#xff0c;但是多线程取值会给编码带来不便&#xff0c;所以新出的关键字await用于阻塞当前线程并 获取目标线程…

字节二面 —— 什么是同步锁、死锁、乐观锁、悲观锁

马上就要到金三银四佳季了&#xff0c;是找工作的好时候&#xff0c;小伙伴们一定要把握好时机&#xff0c;找到心仪的高薪工作。找工作就少不了面试&#xff0c;那我们从现在开始&#xff0c;多刷刷面试题&#xff0c;查缺补漏&#xff01;&#xff01;&#xff01; 目录 1. …

C#进阶之WebAPI(一)

最近出去面试&#xff0c;被问到关于WebAPI的知识&#xff0c;因为项目中没有单独写过WebAPI&#xff0c;使用的时候是和mvc结合在一起使用的&#xff0c;所以&#xff0c;在我的印象中WebAPI和mvc是差不多的&#xff0c;这种答案当然不能让人满意了&#xff0c;于是今天做个关…

【LeetCode-SQL每日一练】—— 620. 有趣的电影

&#x1f388;写在前面 &#x1f64b;‍♂️大家好呀&#xff0c;我是超梦。大家可以叫我小梦~ 小伙伴们都知道&#xff0c;不管是在学习中还是日常工作中&#xff0c;几乎天天是要跟数据库打交道的&#xff0c;为了更好的操作数据库&#xff0c;我们的SQL知识储备是必不可少的…

改了一行代码,MySQL查询效率提升了80%,老板奖了我50万

⭐前言 优化MySQL数据库是数据库管理员必备的技能&#xff0c;通过不同的优化方式方法来达到提高MySQL数据库性能的目的。 MySQL数据库当用户和数据量非常少的情况下&#xff0c;我们就很难判断MySQL数据库性能的好坏。只有当用户量与数据量大起来&#xff0c;MySQL的性能如何才…

C#进阶之WebAPI(二)

今天学习一下&#xff1a;WebAPI如何使用呢&#xff1f; 首先我们打开vs新建一个WebAPI项目&#xff0c;可以看到一共有这些文件夹目录 首先了解一下这些文件夹/文件的意义&#xff08;按照程序启动的流程&#xff0c;相关的配置项就不说了&#xff09;&#xff0c; Global.as…

字节一面 —— List 和 Map、Set 的区别

马上就要到金三银四佳季了&#xff0c;是找工作的好时候&#xff0c;小伙伴们一定要把握好时机&#xff0c;找到心仪的高薪工作。找工作就少不了面试&#xff0c;那我们从现在开始&#xff0c;多刷刷面试题&#xff0c;查缺补漏&#xff01;&#xff01;&#xff01; 目录 ⭐常…

C#进阶之WebAPI(三)

今天复习一下WebAPI的路由知识&#xff1a; 首先分析一下MVC路由和WebAPI路由的区别&#xff1a; 在mvc里&#xff0c;默认的路由机制是通过URL路径去匹配控制器和Action方法的&#xff0c;在mvc中的默认路由定义在App_Start文件夹下的RouteConfig.cs文件下&#xff1a; publ…

阿里一面 —— HTTP中重定向和请求转发的区别?

马上就要到金三银四佳季了&#xff0c;是找工作的好时候&#xff0c;小伙伴们一定要把握好时机&#xff0c;找到心仪的高薪工作。找工作就少不了面试&#xff0c;那我们从现在开始&#xff0c;多刷刷面试题&#xff0c;查缺补漏&#xff01;&#xff01;&#xff01; 目录 ⭐T…

C#异步编程-------异步编程模型(APM)

术语解释&#xff1a; APM 异步编程模型&#xff0c; Asynchronous Programming Model EAP 基于事件的异步编程模式&#xff0c; Event-based Asynchronous Pattern TAP 基于任务的异步编程模式&#xff0c; Task-based Asynch…

【LeetCode-SQL每日一练】—— 627. 变更性别

&#x1f388;写在前面 &#x1f64b;‍♂️大家好呀&#xff0c;我是超梦。大家可以叫我小梦~ 又到了练习SQL的时候啦&#xff01;一起来学习吧&#xff01; &#x1f64b;‍♂️ 小伙伴们如果在学习过程中有不明白的地方&#xff0c;欢迎评论区留言提问&#xff0c;小梦定知无…

iis运行原理 Asp.Net详解IIS内部运行原理

本章节主要讲IIS和 管道内部如何处理客户端Http请求&#xff0c;会较多的以代码的形式讲述&#xff0c;让大家对HttpApplication、HttpHandler、HttpApplicationFactory、Page这几个在处理请求过程中扮演重要角色的对象有更深入的了解。 下面我们通过单步调式跟踪System.Web.D…

【LeetCode-SQL每日一练】—— 1179. 重新格式化部门表

&#x1f388;写在前面 &#x1f64b;‍♂️大家好呀&#xff0c;我是超梦。大家可以叫我小梦~ 又到了练习SQL的时候啦&#xff01;一起来学习吧&#xff01; &#x1f64b;‍♂️ 小伙伴们如果在学习过程中有不明白的地方&#xff0c;欢迎评论区留言提问&#xff0c;小梦定知无…

阿里一面 —— 什么是多线程?

马上就要到金三银四佳季了&#xff0c;是找工作的好时候&#xff0c;小伙伴们一定要把握好时机&#xff0c;找到心仪的高薪工作。找工作就少不了面试&#xff0c;那我们从现在开始&#xff0c;多刷刷面试题&#xff0c;查缺补漏&#xff01;&#xff01;&#xff01; 目录 ⭐什…