基础知识 - .Net 程序设计与运行

1.程序设计,猫大叫一声,所有的老鼠都开始逃跑,主人被惊醒。

要求:

A. 要有联动性,老鼠和主人的行为是被动的。

B.  考虑可扩展性,猫的叫声可能引起其他联动效应。

要点:1. 联动效果,运行代码只要执行Cat.Cryed()方法。2. 对老鼠和主人进行抽象
评分标准: .构造出Cat、Mouse、Master三个类,并能使程序运行
从Mouse和Master中提取抽象联动效应,只要执行Cat.Cryed()就可以使老鼠逃跑,主人惊醒。

参考实现:https://www.cnblogs.com/star8521/p/4977912.html

答:a).先抽象定义分别两个接口IObserver和IObserveSubject

namespace ObserverExample
{
    public interface IObserver
    {
        void ObserverAction();//对被观察对象的行为作出反应,这里是指猫叫
    }
}

//需要建立不同的文件
namespace ObserverExample
{
    public interface IObserveSubject
    {
        void AddObserver(IObserver observer);//添加所有的观察者,在发生动作时对他们进行通知
    }
}

b).再分别定义实现这两个接口的类

using System;
using System.Collections.Generic;

namespace ObserverExample
{
    public class Cat : IObserveSubject
    {
        List<IObserver> list;

        public Cat()
        {
            list = new List<IObserver>();
        }

        public void AddObserver(IObserver observer)
        {
            list.Add(observer);//实现添加观察着对象的方法
        }

        public void Shout()
        {
            Console.WriteLine("猫大叫一声...");

            //猫叫了,并通知所有的观察者,作出相应的反应
            foreach (var item in list)
            {
                item.ObserverAction();
            }
        }
    }
}


//需要建立不同的文件
using System;

namespace ObserverExample
{
    public class Mouse : IObserver
    {
        public Mouse(IObserveSubject os)
        {
            os.AddObserver(this);//将当前的观察着对象添加到观察者集合中
        }

        public void ObserverAction()
        {
            Console.WriteLine("开始逃跑...");
        }
    }
}


//需要建立不同的文件
using System;

namespace ObserverExample
{
    public class Master : IObserver
    {
        public Master(IObserveSubject os)
        {
            os.AddObserver(this);//将当前的观察着对象添加到观察者集合中
        }

        public void ObserverAction()
        {
            Console.WriteLine("惊醒...");
        }
    }
}

c).其它方法调用实现

public static void RunCatShout()
{
   Cat c = new Cat();
   Mouse m = new Mouse(c);
   Master master = new Master(c);
   c.Shout();
}

2.下面的程序执行结果是什么?

class Person
    {
        public int Age { get; set; }

        void RunAge()
        {
            int i1 = 20;
            int i2 = i1;
            i1++;
            Console.WriteLine(i2);
            Person p1 = new Person();
            p1.Age = 20;
            Person p2 = p1;
            p1.Age++;
            Console.WriteLine(p2.Age);
        }
}

答:20、21

3.根据线程安全的相关知识,分析以下代码,当调用test方法时i>10时是否会引起死锁?并简要说明理由。

public void test(int i)
{
    lock (this)
    {
       if (i > 10)
       {
          i--;
          test(i);
        }
     }
}

答:不会发生死锁,(但有一点int是按值传递的,所以每次改变的都只是一个副本,因此不会出现死锁。但如果把int换做一个object,那么死锁会发生)

4.在下面的例子里, 当使用new B()创建B的实例时,产生什么输出?

class A
{
    public A()
    {
        PrintFields();
    }
    public virtual void PrintFields() { }
}

class B : A
{
    int x = 1;
    int y;
    public B()
    {
        y = -1;
    }
    public override void PrintFields()
    {
        Console.WriteLine("x={0},y={1}", x, y);
    }
}

答:X=1,Y=0;
1. 父类静态成员和静态初始化块 ,按在代码中出现的顺序依次执行
2. 子类静态成员和静态初始化块 ,按在代码中出现的顺序依次执行
3. 父类实例成员和实例初始化块 ,按在代码中出现的顺序依次执行
4. 父类构造方法
5. 子类实例成员和实例初始化块 ,按在代码中出现的顺序依次执行
6. 子类构造方法

5.请使用C#或者Javascript写出如何判断一个数为奇数还是偶数

答:一般普通版:

private bool IsOdd(int num)
{
   return (num % 2) == 1;  
}

现在升级版: 通过位运算(与)进行判断

private bool IsOdd(int num)
{
   return (num & 1) == 1;  
}

num = 10

0000 1010

0000 0001

num = 7

0000 0111

0000 0001

0000 0000 0000 0001
function(){
        if(t1.value%2==0){
            alert("这是个偶数");
        }else
            alert("这是个奇数");
    }

 5.用C#实现把一个Array复制到ArrayList里。

Array array = new int[] { 1, 2, 3 };
ArrayList arrayList = new ArrayList(array);

6.怎样在多线程中调用同一对象,前提是该对象每分钟会被某一线程改写一次,改写时,其他线程暂停访问,待改写完后再进行访问。

using System;
using System.Threading;

namespace MultiThread
{
    public class ThreadExample
    {
        ThreadObject threadObj;
        int loopCount = 200;

        public ThreadExample()
        {
            threadObj = new ThreadObject { ThreadRemainIndex = loopCount, ThreadTime = DateTime.Now };
        }

        /// <summary>
        /// 10.    怎样在多线程中调用同一对象,前提是该对象每分钟会被某一线程改写一次,改写时,其他线程暂停访问,待改写完后再进行访问。
        /// </summary>
        public void TestMultiThreadReadWrite()
        {
            //Thread 
            ParameterizedThreadStart ts_read = new ParameterizedThreadStart(ReadThreadObject);
            ThreadStart ts_write = new ThreadStart(WriteThreadObject);
            Thread t1 = new Thread(ts_read);
            Thread t2 = new Thread(ts_read);
            Thread t3 = new Thread(ts_write);
            Thread t4 = new Thread(ts_read);
            Thread t5 = new Thread(ts_read);
            Thread t6 = new Thread(ts_read);
            Thread t7 = new Thread(ts_read);
            t1.Start("t1");
            t2.Start("t2");
            t3.Start();
            t4.Start("t4");
            t5.Start("t5");
            t6.Start("t6");
            t7.Start("t7");

        }

        private object writeObj = new object();

        public void ReadThreadObject(object threadNum)
        {
            //lock (writeObj)
            //{
            for (int i = 0; i < loopCount; i++)
            {
                lock (writeObj)
                {
                    if (threadObj.ThreadRemainIndex <= 0)
                        break;
                    Thread.Sleep(100);
                    Console.WriteLine("Read ThreadTime:{0:yyyy-MM-dd HH:MM:ss.fff},ThreadNum:{1},ThreadRemainIndex:{2}", threadObj.ThreadTime, threadNum, threadObj.ThreadRemainIndex);

                    threadObj.ThreadRemainIndex -= 1;
                }
            }
            //}
        }

        public void WriteThreadObject()
        {
            //lock (writeObj)
            //{
            for (int i = 0; i < loopCount; i++)
            {
                lock (writeObj)
                {
                    if (threadObj.ThreadRemainIndex <= 0)
                        break;
                    Thread.Sleep(150);
                    threadObj.ThreadTime = DateTime.Now;
                    Console.WriteLine("Write hreadTime:{0:yyyy-MM-dd HH:MM:ss.fff},ThreadRemainIndex:{1}", threadObj.ThreadTime, threadObj.ThreadRemainIndex);
                    //lock (writeObj)
                    threadObj.ThreadRemainIndex -= 1;
                }
            }
        }
    }

    public class ThreadObject
    {
        public int ThreadRemainIndex { get; set; }

        public DateTime ThreadTime { get; set; }
    }
}
View Code
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace MultiThread
{
    public class ThreadObserverExample
    {
        ThreadObject threadObj;
        int loopCount = 200;

        public ThreadObserverExample()
        {
            threadObj = new ThreadObject { ThreadRemainIndex = loopCount, ThreadTime = DateTime.Now };
        }

        public void TestMultiThreadReadWrite()
        {
            //因为没有使用锁,所以ThreadRemainIndex会出现负数的情况
            Action<object> act_read = (threadNum) =>
            {
                for (int i = 0; i < loopCount; i++)
                {
                    if (threadObj.ThreadRemainIndex <= 0)
                        break;
                    Thread.Sleep(100);
                    Console.WriteLine("Read ThreadTime:{0:yyyy-MM-dd HH:MM:ss.fff},ThreadNum:{1},ThreadRemainIndex:{2}", threadObj.ThreadTime, threadNum, threadObj.ThreadRemainIndex);
                    threadObj.ThreadRemainIndex -= 1;
                }
            };

            Action act_write = () =>
            {
                for (int i = 0; i < loopCount; i++)
                {
                    if (threadObj.ThreadRemainIndex <= 0)
                        break;
                    Thread.Sleep(150);
                    threadObj.ThreadTime = DateTime.Now;
                    Console.WriteLine("Write hreadTime:{0:yyyy-MM-dd HH:MM:ss.fff},ThreadRemainIndex:{1}", threadObj.ThreadTime, threadObj.ThreadRemainIndex);
                    //lock (writeObj)
                    threadObj.ThreadRemainIndex -= 1;
                }
            };

            Task t1 = new Task(act_read, "t1");
            Task t2 = new Task(act_read, "t2");
            Task t3 = new Task(act_read, "t3");
            Task t4 = new Task(act_write);
            Task t5 = new Task(act_read, "t5");
            Task t6 = new Task(act_read, "t6");
            Task t7 = new Task(act_read, "t7");

            ThreadSubject ts = new ThreadSubject();
            ts.AddObserver(t1);
            ts.AddObserver(t2);
            ts.AddObserver(t3);
            ts.AddObserver(t5);
            ts.AddObserver(t6);
            ts.AddObserver(t7);
            ts.WriteObject(t4);
        }

        public interface IThreadObserveSubject
        {
            void AddObserver(Task observer);

            void WriteObject(Task subject);
        }

        public class ThreadSubject : IThreadObserveSubject
        {
            List<Task> list;

            public ThreadSubject()
            {
                list = new List<Task>();
            }

            public void AddObserver(Task observer)
            {
                list.Add(observer);
                //observer.Start();
            }

            public void WriteObject(Task subject)
            {
                foreach (Task t in list)
                {
                    if (t.Status == TaskStatus.Running)
                        t.Wait();
                    else
                        t.Start();
                }

                subject.Start();
                if (subject.IsCompleted)
                {
                    subject.Wait();
                    foreach (Task t in list)
                    {
                        t.Start();
                    }
                }
            }
        }
    }
}
View Code

7.将List<ClassA> obj 中的所有元素复制给另一个List<ClassA> obj2对象,有几种方法?复制后使用obj2 会出现什么问题?

参考答案:https://www.cnblogs.com/insus/p/8127745.html

答:有区分浅复制/深复制,值类型/引用类型;分别有:List<T> 自带的CopyTo方法,List<T> 自带的GetRange方法,List<T> 的构造方法 List(IEnumerable<T> collection),序列化与反序列化;

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;

namespace Helper
{
    static class ListExtensions
    {
        public static IList<T> Clone<T>(this IList<T> listToClone) where T : ICloneable
        {
            return listToClone.Select(item => (T)item.Clone()).ToList();
        }
        //当然前题是List中的对象要实现ICloneable接口
    }

    public class Question0628
    {
        //11.    将List<ClassA> obj 中的所有元素复制给另一个List<ClassA> obj2对象,有几种方法?复制后使用obj2 会出现什么问题?

        public void CopyList()
        {
            Func<List<ClassA>, List<ClassA>> copyList = (sourceList) =>
            {
                List<ClassA> resultList;
                ClassA[] array = new ClassA[sourceList.Count];
                sourceList.CopyTo(array);
                resultList = array.ToList();
                return resultList;
            };

            Action<List<ClassA>, string> act_read = (list, listName) =>
            {
                Console.WriteLine(listName);
                foreach (ClassA item in list)
                {
                    Console.WriteLine("Id:{0},Name:{1}", item.Id, item.Name);
                }
            };

            List<ClassA> list1 = new List<ClassA> {
                new ClassA { Id = 1, Name = "C1" },
                new ClassA { Id = 2, Name = "C2" },
                new ClassA { Id = 3, Name = "C3" }
            };

            act_read(list1, "list1");
            Console.WriteLine("copying...");
            List<ClassA> list2 = copyList(list1);
            List<ClassA> list3 = new List<ClassA>(list1);
            List<ClassA> list4 = list1.Clone().ToList();
            List<ClassA> list5 = list1.GetRange(0, list1.Count);
            List<ClassA> list6;
            using (MemoryStream ms = new MemoryStream())
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(ms, list1);
                ms.Position = 0;
                list6 = (List<ClassA>)bf.Deserialize(ms);
            }

            //list2 change
            list2.ForEach(f => f.Name = f.Name + "_" + "list2");

            act_read(list1,"list1");
            act_read(list2, "list2:");
            act_read(list3, "list3:");
            act_read(list4, "list4:");
            act_read(list5, "list5:");
            act_read(list6, "list6:");
        }

        [Serializable]
        public class ClassA : ICloneable
        {
            public int Id { get; set; }
            public string Name { get; set; }

            public object Clone()
            {
                //自己重写的Clone
                return new ClassA { Id = Id, Name = Name };
            }
        }
    }
}
View Code

8.以下方法被调用时会输出什么?

Public void Printout(){
    Var longName=”LawExam”;
    longName.Replace(“Exam”,”Go”);
    longName.Insert(3,”-”);
    Console.WriteLine(longName);
}

答:LawExam

9.C#代码中,下列分别输出什么?

int a=1; Console.WriteLine(a is dynamic); 

int? a = 1;  Console.WriteLine(a is int); 

int? a = 1;  Console.WriteLine(a.GetType() == typeof(int?)); 

答:True,True,False

10.执行以下代码片段输出什么?

 Action doit = async () =>
      {
Console.WriteLine(1);
              var task = Task.Run(() =>
              {
                     Thread.Sleep(3000);
                     Console.WriteLine(2);
               });

                await task;
                Console.WriteLine(3);
       };
       doit();

答:1,2,3

11.How to get all combinations from “allList”? Such as a1A,a1B,....c3E

List<List<string>> allList= new List<List<string>>
{
        new List<string> {“a”,”b”,”c”},
new List<string> {“1”,”2”,”3”},
new List<string> {“A”,”B”,”C” ,”D”,”E”},
};
List<string> outList = new List<string>();

            Func<List<string>, List<string>,List<string>> act = (list1, list2) =>
            {
                List<string> result = new List<string>();
                foreach (string str in list1)
                {
                    list2.ForEach(f =>
                    {
                        string str2 = str + f;
                        result.Add(str2);
                    });
                }
                return result;
            };

            foreach (var list in allList)
            {
                if (outList.Count == 0)
                {
                    outList = list;
                    continue;
                }
                outList = act(outList, list);
            }
            Console.WriteLine(string.Join(",", outList));
View Code

12.Write a singleton class of threaded safe.

public class MyFactory
    {
        private static class instanceHolder
        {
            public static MyFactory instance = new MyFactory();
        }

        public static MyFactory getInstance()
        {
            return MyFactory.instanceHolder.instance;
        }
    }
View Code

13.What is the output of the program below? Explain your answer.

Class program
{
    delegate void Printer();
    static void main(string[] args)
    {
        List<Printer> printers = new List<Printer>();
            for (int i = 0; i < 10; i++)
            {
                printers.Add(delegate { Console.WriteLine(i); });
            }

            foreach (var printer in printers)
            {
                printer();
            }
    }
}

答:10个10,因为所有的委托中的变量i都是指向同一块内存地址

14.What is the output of the program below? Explain your answer.

Class Program
{
    private static string result;
    static void Main(string[] args)
    {
        SaySomething();
        Console.WriteLine(result);
        Console.ReadKey(true);
    }

    static async Task<string> SaySomething()
    {
        Await Task.Delay(5);
        result=”Hello world!”;
        return “Something”;
    }
}

Also,would the answer change if we were to replace await Task.Delay(5) with Thread.Sleep(5)? Why or why not?

答:null,什么也没输出;会改变,Thread.Sleep 是同步延迟,Task.Delay异步延迟。

Thread.Sleep 会阻塞线程,Task.Delay不会。

15.To generate 6 random and unique members between 1 and 49,what way you think fast?

static void func_1()
        {
            int nowNum = 0;
            int[] array = new int[6];
            var r = new Random();
            while (nowNum < 6)
            {
                int v = r.Next(1, 49);
                bool flag = false;
                for (int i = 0; i < nowNum; i++)
                {
                    if (v == array[i])
                    {
                        flag = true;
                        break;
                    }
                }

                if (!flag)
                    array[nowNum++] = v;
            }
            Console.WriteLine(string.Join(",", array));
        }

16.请编程实现一个冒泡排序算法

static void bubble()
        {
            int[] arr = { 23, 44, 66, 76, 98, 11, 3, 9, 7 };
            int temp = 0;

            for (int i = 0; i < arr.Length - 1; i++)
            {
                for (int j = 0; j < arr.Length - 1 - i; j++)
                {
                    if (arr[j] > arr[j + 1])
                    {
                        temp = arr[j + 1];
                        arr[j + 1] = arr[j];
                        arr[j] = temp;
                    }
                }
            }

            string result = string.Join(",", arr);
            Console.WriteLine(result);
        }
View Code

99.一个完整的软件项目开发过程需要经历哪几个步骤?每个步骤会有哪些成果?

答:一、问题的定义及规划

此阶段是软件开发与需求放共同讨论,主要确定软件的开发目标及其可行性。

【团队/管理评审/背景调查/项目目标/角色/模块接口】

二、需求分析

在确定软件开发可行性的情况下,对软件需要实现的各个功能进行详细需求分析。

【产品原型/业务流程图/项目里程碑】

三、软件设计

软件设计一般分为总体设计和详细设计

【UI设计规范/系统框架设计/数据库设计】

四、程序编码

此阶段是将软件设计的结果转化为计算机可运行的程序代码。在程序编码中必定要制定统一、符合标准的编写规范。以保证程序的可读性、易维护性。提高程序的运行效率。

五、软件测试

编写测试用例,整个测试阶段分为单元测试、流程测试三个阶段进行。

posted @ 2019-09-11 15:27  FH1004322  阅读(164)  评论(0)    收藏  举报