真实面经分享
本文最后更新于166 天前,其中的信息可能已经过时,如有错误请发送邮件到2289035571@QQ.COM

公司选择:自动化大厂

汇川

大族激光

拓邦(双休)

慧灵机械人(公积金最高比例)

海目星激光

吉阳智能

英威腾

长盈精密技术

无锡先导

东莞思榕智能装备

苏州博众精工

实际问题

Modbus

底层交互逻辑: 主从模式通讯,主机发送信息,从机接受

Modbus网络上只能有一个主站存在,主站在 Modbus网络上没有地址,从站的地址范围为 0 – 247,其中 0 为广播地址,从站的实际地址范围为 1 – 247。Modbus通信标准协议可以通过各种传输方式传播,如 RS232C、RS485、光纤、无线电等。

通讯格式:波特率,检验方式,数据位,停止位

Modbus RTU:

帧结构 = 地址 + 功能码+ 数据 + 校验

  • 地址: 占用一个字节,范围0-255,其中有效范围是1-247,其他有特殊用途,比如255是广播地址(广播地址就是应答所有地址,正常的需要两个设备的地址一样才能进行查询和回复)。
  • 功能码:占用一个字节,功能码的意义就是,知道这个指令是干啥的,比如你可以查询从机的数据,也可以修改数据,所以不同功能码对应不同功能。
  • 数据:根据功能码不同,有不同结构,在下面的实例中有说明。
  • 校验:为了保证数据不错误,增加这个,然后再把前面的数据进行计算看数据是否一致,如果一致,就说明这帧数据是正确的,我再回复;如果不一样,说明你这个数据在传输的时候出了问题,数据不对的,所以就抛弃了。
  • 发送:从机的地址+我要干嘛的功能码+我要查的寄存器的地址+我要查的寄存器地址的个数+校验码
  • 回复:从机的地址+主机发我的功能码+要发送给主机数据的字节数+数据+校验码

如何使用Modbus TCP协议与PLC通讯

  • 获取PLC的地址和端口号
  • 选择NModbus库
  • 创建Modbus TCP连接,连接需要指定PLC的IP地址和端口号(一般为502)
  • 读写寄存器,PLC的数据一般保存在寄存器中,使用读取输入寄存器或者保持寄存器等

Socket

WPF

EFCore

数据更新显示在界面上

public partial class Form1 : Form
    {
    // 定义用于跨线程更新 UI 的委托
    private delegate void UpdateUIDelegate(string data);

    public Form1()
    {
        InitializeComponent();
    }

    private void UpdateUI(string data)
    {
        // 确保在 UI 线程上执行
        if (textBox1.InvokeRequired)
        {
            //Invoke方法里面需要传入委托,data是UpdateUI需要传入的参数
            textBox1.Invoke(new UpdateUIDelegate(UpdateUI), data);
        }
        else
        {
            // 在 UI 上更新控件
            textBox1.Text = data;
        }
    }

    private void SimulateThread()
    {
        // 模拟线程中的操作
        for (int i = 0; i < 10; i++)
        {
            // 模拟获取数据
            string data = $"Data from Thread: {i}";

            // 调用 UpdateUI 方法,确保在 UI 线程上执行
            UpdateUI(data);

            // 模拟线程休眠
            Thread.Sleep(1000);
        }
    }

    private void btnStartThread_Click(object sender, EventArgs e)
    {
        // 启动线程
        Thread thread = new Thread(SimulateThread);
        thread.Start();
    }
}

将Form2的数据传输到Form1

Form1窗体代码:

private void Button1_Click(object sender, EventArgs e)
{
    Form2 form2 = new Form2();
    form2.showEvent += Show; //注册事件,只能+=  必须放在ShowDialog()前面
    form2.ShowDialog();
}

private int Show(int arg)
{
    textBox1.Text = arg.ToString();
    return 1;
}

Form2窗体代码:

public event Func<int, int> showEvent;  //声明事件委托变量f,类型为int,返回值为int

//form2按钮事件
private void Button1_Click(object sender, EventArgs e)
{
    //给form1窗体的文本框赋值20
    if (showEvent != null) //判断事件是否为空
    {
        showEvent(20); //触发事件
    }
}

为什么要使用EF框架(ORM框架连接数据库)

  • 不必直接处理数据库表和SQL查询。可以将数据库的表映射到程序中的对象,使用C#处理
  • 简化数据库操作:提供了强大的API,数据库的增删查改更加容易
  • 可移植性:不要改变应用程序代码,只需更新EF的配置即可(mysql、sqlserver、postgresql)
  • Linq支持

如何与MES通讯

C#

委托与事件

委托:

  • 委托一般声明在类的外部
  • 将⽅法当作参数传⼊另⼀个⽅法,可以理解为指向一个方法的引用
  • 修饰符 + delegate + 返回值类型 + 委托名(参数);
  • C#自定义委托有Action<T>,表示引用一个void返回类型的方法。Func<T>,表示引用带返回类型的方法

Func委托、Action委托、Predicate委托

Func委托必须要求所有的接受方法必须要有返回值类型

//前面是形参 最后一个是返回值类型(如果只有一个参数那么则是返回值类型)
Func<int,int,double> func = (a,b) => a + b;  //double为返回值类型

Action委托接受没有返回值的方法
应用于:在跨线程访问可视化控件的时候经常访问

//返回值类型为void
Action<string> act = a => {"你好啊!{0}",a};

Predicate委托是固定bool类型

//返回值类型固定为bool
public delegate bool Predicate<T> (T obj);

(1).BeginInvoke

一个独立的线程上执行所引用方法,并且立即返回到原始线程。原始线程可以继续,所引用方法则在线程池中与原始线程并行执行。

(2).EndInvoke

可在由BeginInvoke新起的线程完成之后获取返回结果,方法是检查BeginInvoke返回的IAsyncResult的IsCompleted属性,或者调用委托的EndInvoke方法来等待委托执行完成。

(3).Invoke和BeginInvoke

Invoke或者BeginInvoke方法都需要一个委托对象作为其参数,

Invoke类似于使用SendMessage方法来给界面线程发送消息,是一个同步方法,不拿到结果就阻塞在那里了。

使用委托实现主从窗体通信

从窗体发送信息—->主窗体接受信息
主窗体发送信息—->从窗体接受信息

委托与事件的对比

事件

  • 先定义委托
  • 定义事件 修饰符 + event + 委托名 + 事件名
  • 注册事件 将事件和处理方法绑在一起 事件+=方法
  • 触发事件 判断事件是否为空 不为空则执行

用户控件

用户自己将控件组合。控件中的字体必须和父容器的字体一样。不然不兼容

winform自定义控件

当你自定义一个按钮控件时,通常你会定义自己的外观和交互逻辑。

OnPaint方法

  • 当鼠标进入或离开控件区域时,也可能引起 OnPaint 方法的调用
  • 界面发生变化时 ??Form窗体变化不会引起OnPaint方法
  • 按钮被遮挡
  • 调用Invalidate()方法
using System;
using System.Drawing;
using System.Windows.Forms;

public class CustomButton : Control
{
    // 构造函数
    public CustomButton()
    {
        // 设置一些默认值
        this.BackColor = Color.LightGray;
        this.ForeColor = Color.Black;
        this.Size = new Size(100, 40);

        // 注册鼠标事件
        this.MouseEnter += CustomButton_MouseEnter;
        this.MouseLeave += CustomButton_MouseLeave;
        this.MouseDown += CustomButton_MouseDown;
        this.MouseUp += CustomButton_MouseUp;
    }

    // 鼠标进入时改变背景颜色
    private void CustomButton_MouseEnter(object sender, EventArgs e)
    {
        this.BackColor = Color.Gray;
    }

    // 鼠标离开时还原背景颜色
    private void CustomButton_MouseLeave(object sender, EventArgs e)
    {
        this.BackColor = Color.LightGray;
    }

    // 鼠标按下时改变背景颜色
    private void CustomButton_MouseDown(object sender, MouseEventArgs e)
    {
        this.BackColor = Color.DarkGray;
    }

    // 鼠标释放时还原背景颜色
    private void CustomButton_MouseUp(object sender, MouseEventArgs e)
    {
        this.BackColor = Color.Gray;
    }

    // 重写绘图逻辑 
    //当控件首次显示或者大小发生变化时,系统自动调用  
    //如果想手动调用则 Invalidate()方法
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        // 使用Graphics对象绘制按钮的外观
        using (Graphics g = e.Graphics)
        {
            // 填充按钮的背景
            g.FillRectangle(new SolidBrush(this.BackColor), ClientRectangle);

            // 绘制按钮的文本
            StringFormat sf = new StringFormat
            {
                Alignment = StringAlignment.Center,
                LineAlignment = StringAlignment.Center
                };
            g.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), ClientRectangle, sf);
        }
    }
}

上述代码创建了一个名为 CustomButton 的自定义按钮控件。你可以在你的 WinForms 项目中使用这个自定义按钮控件,方式类似于使用内置的按钮控件:

private void Form1_Load(object sender, EventArgs e)
{
    CustomButton customButton = new CustomButton
    {
        Text = "Click me!",
        Location = new Point(50, 50)
    };

    this.Controls.Add(customButton);
}

设计模式

发布者-订阅者模式

类与结构体的区别

相同点 都可以实现接⼝

不同点

1.class是引⽤类型,struct是值类型

2.class允许继承、被继承,struct不允许,只能继承接⼝

3.class可以初始化变量,struct不可以

4.class可以有⽆参的构造函数,struct不可以,必须是有参的构造函数,⽽且在有参的构造函数必须初 始化所有成员

使⽤场景

1.Class⽐较适合⼤的和复杂的数据,表现抽象和多级别的对象层次时。

2.Struct适⽤于作为经常使⽤的⼀些数据组合成的新类型,表示诸如点、矩形等主要⽤来存储数据的轻 量级对象时,偏简单值。

3.Struct有性能优势,Class有⾯向对象的扩展优势。

Debug

Console.WriteLine();//控制台应用输出

Debug.WriteLine();//窗体应用在控制台输出

类的多继承问题,如何解决

C#不支持多继承,但提供了其他的一些机制来实现类似的功能

  • 接口:实现多个接口
  • 组合:一个类可以包含其他类的实例,调用这些实例的方法的获得所需的行为
  • 委托和事件
  • 模式

委托的多继承效果:

通过委托,一个类可以包含对另一个类的方法的引用,从而在运行时调用这些方法。

      	// 使用委托将 ClassB 的方法引用传递给 ClassA
        MyDelegate myDelegate = objB.MethodB;
        
        // 调用 ClassA 的方法
        objA.MethodA();
        
        // 调用 ClassB 的方法
        myDelegate();

事件的多继承效果

事件是建立在委托的基础上的,通过事件,一个类可以在其内部触发其他类的方法。

class Publisher //发布者
{
    public event Action MyEvent;

    public void RaiseEvent()
    {
        MyEvent?.Invoke();
    }
}
 
class Subscriber //订阅者
{
    public void HandleEvent()
    {
        Console.WriteLine("Event handled by Subscriber");
    }
}

class Program
{
    static void Main()
    {
        Publisher publisher = new Publisher();
        Subscriber subscriber = new Subscriber();

        // 订阅事件
        publisher.MyEvent += subscriber.HandleEvent;

        // 触发事件
        publisher.RaiseEvent();
    }
}

数据库

MySql怎么提高增删查改(CRUD)的效率

  • 增加索引:经常被查询的字段,注意索引并非越多越好,索引过多会增加系统开销
  • 分区表
  • RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区。
  • LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。
  • HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。任何有效的MySQL表达式,只要产生非负整数值,都可以包含在这个函数中。
  • KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。必须有一列或多列包含整数值。
  • 适当的数据类型:选择适当的数据类型,以减小表的存储空间和提高查询性能。例如,使用INT而不是VARCHAR作为索引列。
  • 使用批量操作:使用批量操作来替代逐条操作,减少数据库交互的开销。例如,使用

INSERT INTO 表名(字段1,字段2,字段3) VALUES (值1,值2,值3)

INSERT INTO 表名 VALUES(值1,值2,值3)语法进行批量插入。

  • 缓存策略:使用缓存技术,如Memcached或Redis,来缓存频繁读取但不经常更新的数据,减轻数据库的压力。
  • 查询优化:确保查询语句是最优语句,避免不必要的连接和子查询。禁止使用select *

SQLServer

觉得有帮助可以投喂下博主哦~感谢!
作者:Lincol
本文链接:https://www.lincol29.cn/%e7%9c%9f%e5%ae%9e%e9%9d%a2%e7%bb%8f%e5%88%86%e4%ba%ab
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0协议转载请注明文章地址及作者哦~

评论

  1. w
    Windows Edge
    5 月前
    2024-1-04 17:36:23

    催更!!!

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇