面试题问题和答案

110 阅读7分钟

第一题

image.png

-- ----------------------------
-- Table structure for Orders
-- ----------------------------
IF EXISTS (SELECT * FROM sys.all_objects WHERE object_id = OBJECT_ID(N'[dbo].[Orders]') AND type IN ('U'))
	DROP TABLE [dbo].[Orders]
GO

CREATE TABLE [dbo].[Orders] (
  [OrderNo] int  NOT NULL,
  [CustomerId] nvarchar(10) COLLATE Chinese_PRC_CI_AS  NULL,
  [OrderDate] datetime  NULL,
  [OrderAmt] numeric(12,2)  NULL
)
GO

ALTER TABLE [dbo].[Orders] SET (LOCK_ESCALATION = TABLE)
GO

-- ----------------------------
-- Records of Orders
-- ----------------------------
INSERT INTO [dbo].[Orders]  VALUES (N'1', N'aaaa11110', N'2019-01-01 00:00:00.000', N'10.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'2', N'aaaa11111', N'2019-01-01 00:00:00.000', N'20.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'3', N'aaaa11111', N'2019-11-01 00:00:00.000', N'30.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'4', N'aaaa11112', N'2019-01-01 00:00:00.000', N'40.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'5', N'aaaa11112', N'2019-08-01 00:00:00.000', N'50.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'6', N'aaaa11113', N'2019-01-01 00:00:00.000', N'60.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'7', N'aaaa11113', N'2019-02-01 00:00:00.000', N'70.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'8', N'aaaa11114', N'2019-02-01 00:00:00.000', N'80.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'9', N'aaaa11114', N'2019-03-01 00:00:00.000', N'90.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'10', N'aaaa11115', N'2019-03-01 00:00:00.000', N'100.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'11', N'aaaa11115', N'2019-07-01 00:00:00.000', N'110.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'12', N'aaaa11116', N'2019-03-01 00:00:00.000', N'120.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'13', N'aaaa11116', N'2019-11-01 00:00:00.000', N'130.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'14', N'aaaa11117', N'2019-01-01 00:00:00.000', N'140.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'15', N'aaaa11117', N'2019-12-01 00:00:00.000', N'150.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'16', N'aaaa11110', N'2020-01-01 00:00:00.000', N'160.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'17', N'aaaa11111', N'2020-03-01 00:00:00.000', N'170.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'18', N'aaaa11111', N'2020-05-01 00:00:00.000', N'180.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'19', N'aaaa11112', N'2020-01-01 00:00:00.000', N'190.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'20', N'aaaa11112', N'2020-07-01 00:00:00.000', N'200.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'21', N'aaaa11113', N'2020-01-01 00:00:00.000', N'210.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'22', N'aaaa11113', N'2020-09-01 00:00:00.000', N'220.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'23', N'aaaa11114', N'2020-01-01 00:00:00.000', N'230.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'24', N'aaaa11114', N'2020-11-01 00:00:00.000', N'240.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'25', N'aaaa11115', N'2020-01-01 00:00:00.000', N'250.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'26', N'aaaa11115', N'2020-11-01 00:00:00.000', N'260.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'27', N'aaaa11116', N'2020-01-01 00:00:00.000', N'270.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'28', N'aaaa11116', N'2020-12-01 00:00:00.000', N'280.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'29', N'aaaa11117', N'2020-07-01 00:00:00.000', N'290.00')
GO

INSERT INTO [dbo].[Orders]  VALUES (N'30', N'aaaa11117', N'2020-08-01 00:00:00.000', N'300.00')
GO

-- ----------------------------
-- Primary Key structure for table Orders
-- ----------------------------
ALTER TABLE [dbo].[Orders] ADD CONSTRAINT [PK__Orders__3214EC0768487DD7] PRIMARY KEY CLUSTERED ([OrderNo])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)  
ON [PRIMARY]
GO


--思路
--一、是先取出2020年销售总额前10的客户ID
--二、汇总每个客户2019年和2020年的销售总额
--三、把第一个取得的客户ID作为第二步的条件

select o.CustomerId as '客户ID', o.sum2020 as '2020年销售额',o.sum2019 as '2019年销售额' from (
select CustomerId , sum( CASE datepart(yyyy,OrderDate)
	WHEN '2019' THEN OrderAmt
	ELSE 0
END) as 'sum2019',
sum( CASE datepart(yyyy,OrderDate)
	WHEN '2020' THEN OrderAmt
	ELSE 0
END) as 'sum2020'
 from Orders GROUP BY CustomerId 
 ) o where o.CustomerId in (
 
 select top 10 CustomerId from Orders  where   datepart(yyyy,OrderDate)='2020' GROUP BY  CustomerId order by  SUM(OrderAmt)  desc )  
 ORDER BY o.sum2020 desc
 

运行结果 我这里是取前3个

image.png

第二题

按你的理解给出一个完整的订单头表和订单明细表的解构

订单主表 orderMain

序号字段类型长度描述
1OrderNoint订单主表Id,主键
2CustomerIdnvarchar10客户ID
3OrderDatedatetime订单时间
4CreateIdint创建者
5Stateint订单状态【多种状态】
6Amountnumeric(12,2)总金额
7Remarknvarchar100备注

订单明细表 orderDetail

序号字段类型长度描述
1OrderDetailIdint订单明细Id,主键
2OrderNoint订单主表Id,外键
3Numint数量
4Pricenumeric(12,2)价格
5ProductIdint商品Id
6ProductNamenvarchar50商品名称(冗余字段)

第三题

多线程编程要注意生么?

1、明确目的,为什么要使用多线程?如果是由于单线程读写或者网络访问(例如HTTP访问互联网)的瓶颈,可以考虑使用线程池。如果是对不同的资源(例如SOCKET连接)进行管理,可以考虑多个线程。

2、线程使用中要注意,如何控制线程的调度和阻塞,例如利用事件的触发来控制线程的调度和阻塞,也有用消息来控制的。

3、线程中如果用到公共资源,一定要考虑公共资源的线程安全性。一般用LOCK锁机制来控制线程安全性。一定要保证不要有死锁机制。

4、合理使用sleep,何时Sleep,Sleep的大小要根据具体项目,做出合理安排。一般原则非阻塞状态下每个循环都要有SLeep,这样保证减少线程对CPU的抢夺。每次线程的就绪和激活都会占用一定得资源,如果线程体如果有多个循环,多处使用SLEEP将导致性能的下降。

5、线程的终止一般要使线程体在完成一件工作的情况下终止,一般不要直接使用抛出线程异常的方式终止线程。

6、线程的优先级一定根据程序的需要要有个整体的规划。

第五题

C#中怎么定义一个事件,在什么情况下要用事件?

class Test
{     
    public delegate void EventHandler();  //①申明委托;
    public event EventHandler Handler;      //②定义事件;
    static void Main()
    { 
        Test t=new Test();
         t.Handler +=new Test.EventHandler(MethodA);   //③将事件与委托关联(订阅事件);
         t.Handler();         //④触发事件;
    }
    public static void MethodA()
    {
       System.Console.WriteLine("方法A");
    }
}

注意:

1.委托delegate和事件Event的关系:

​ 委托(delegate)相当于一系列函数的抽象类,这一系列函数要求拥有相同的参数和返回值;而事件(Event)相当于委托的一个实例,只是前面冠有Event关键字。

2.在关联委托和事件时,应该注意:

①委托和事件都应该有应用对象来引用。

②传入委托中的函数,只写函数名,不带括号。

3.事件的触发,必须要有由具体的引用对象来触发。

做控件二次开发,扩展控件事件的时候,必须要用事件。

第六题

socket编程的主要步骤

服务端:socket—>bind—>listen—>accept—>send/recv—>closesocket

客户端:socket—>bind(可选)—>connect—>send/recv---->closesocket

或者

(1)创建Socket

(2)打开连接到Socket的输入/输出流。

(3)按照一定的协议对Socket进行读/写操作(这步很关键)。

(4)关闭打开的输入/输出流。

(5)关闭Socket。

服务端代码

            //监听器
            TcpListener listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 7777);
            listener.Start();
            Console.WriteLine("我启动了,服务端");
            TcpClient tcpClient = listener.AcceptTcpClient();
            Console.WriteLine("连接状态:"+tcpClient.Connected);
            //接受数据
            NetworkStream stream = tcpClient.GetStream();
            //byte[] data = new byte[1024];
            //stream.Read(data);
            //string str = Encoding.Default.GetString(data,0,data.Length);
            BinaryReader binaryReader = new BinaryReader(stream);
            string str = binaryReader.ReadString();
            Console.WriteLine("接受的数据是:"+str);
            stream.Close();
            tcpClient.Close();
            Console.Read();

客户端代码

          TcpClient client = new TcpClient();
            client.Connect("127.0.0.1", 7777);
            Console.WriteLine("连接成功");
            //发送数据
            NetworkStream stream = client.GetStream();
            //byte[] data = Encoding.Default.GetBytes("这是我发送的数据");
            //stream.Write(data, 0, data.Length);
            //stream.Flush();
            string str = "这是我发送的数据88888";
            BinaryWriter binaryWriter = new BinaryWriter(stream);
            binaryWriter.Write(str);
            Console.WriteLine("发送的数据是:"+str);
            stream.Close();
            client.Close();