Click here to Skip to main content
15,887,361 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
The following is for a programming test I was once given for a job interview. I am not a good test-taker. My solution is below, and I am just looking for some insights as to why my solution was not accepted:

I need to write a program in VB.Net which copies from input to output until the input is exhausted. The program should use (and NOT implement) the methods GetData() and PutData() described below.

The method GetData() provides input. Its function prototype is:
VB
Public Function GetData(ByRef Buf() As Char) As Integer


It returns the number of characters placed into Buf, a value less than or equal to 512. This number varies from one call to the next. If it is 0, input is exhausted.

The method PutData() accepts output. Its function prototype is:
VB
Public Sub PutData(ByVal Buf() as Char, ByVal Count As Integer)


It writes Countcharacters to output from Buf. Count must represent the number of characters contained in Buf and be 512 for every call but the last. It may be less than 512 (even 0) for the last call only.

The above is a programming test I was once given as a interview.

I submitted the following code:

I wrote the code below for the answer to this test, and the hiring manager said I was wrong because I was making assumptions:
VB
' This code is assuming that GetData() always returns 512 until the very 
' last data block is read; only then is 512 or less returned.
Sub Main()
    Dim buffer As Char() = New Char(512) {}
    Dim count As Integer = 0
    While (InlineAssignHelper(count, GetData(buffer))) <> 0
        PutData(buffer, count)
    End While
End Sub

' This method is only here to ensure we can assign the result of 
' GetData to count with each iteration of the while loop, while 
' at the same time, detect whether zero bytes have been returned.
Private Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
    target = value
    Return value
End Function


The hiring manager said i was wrong for making assumptions. Can anyone please tell me why this code does not answer the programming test, or is this interviewer being a patronizing douche bag that doesn't know what the F$CK he is talking about?

What's tripping me up is that there seems to be a 'sequence' involved in what the hiring manager is saying. However, I don't get it...if I have a GetData() method that is essentially a black-box "reader", how can I know, a priori, the data block sequence?

Personally i think this programming test was written by a dummy, a one-size-fits-all hiring manager who doesn't know a thing about coding but just was handed some piece of paper by their boss and the boss is saying, "here give everyone that applies this impossible-to-pass test."

Brian
Posted
Updated 16-Sep-15 8:45am
v3
Comments
ZurdoDev 16-Sep-15 13:54pm    
Where are you stuck?
Richard Deeming 16-Sep-15 14:24pm    
This sounds suspiciously like a homework question, but you've been here for 15 years. Surely you're not still in school? :P
Brian C Hart 16-Sep-15 14:32pm    
You are excatly right. This is a mindless "programming test" question. Don't you hate those? I am trying to use "phone a friend."
Brian C Hart 16-Sep-15 14:38pm    
I wrote the code below for the answer to this test, and the hiring manager said I was wrong because I was making assumptions:

‘ This code is assuming that GetData() always returns 512 until the very
‘ last data block is read; only then is 512 or less returned.
Sub Main()
Dim buffer As Char() = New Char(512) {}
Dim count As Integer = 0
While (InlineAssignHelper(count, GetData(buffer))) <> 0
PutData(buffer, count)
End While
End Sub

‘ This method is only here to ensure we can assign the result of
‘ GetData to count with each iteration of the while loop, while
‘ at the same time, detect whether zero bytes have been returned.
Private Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
target = value
Return value
End Function
Richard Deeming 16-Sep-15 14:44pm    
The only issue I can see with that is that the spec says that GetData can return a non-zero number less than or equal to 512, but PutData must write 512 characters every time except the last.

You would assume that if GetData returns a number less than 512, the next call will return 0. But the spec doesn't actually say that.

After a closer reading of the specification, this isn't quite as simple as it sounds.

GetData can (and will) return any number from 0 to 512. Only a return value of 0 indicates the end of the data; any other value could be followed by more data.

PutData must be passed exactly 512 characters for every call except that last.

Without the restriction on PutData, your code in the comments would be (almost*) perfect. However, with that restriction in place, your code doesn't meet the specification.

For example, GetData might return 250, 512, 110, 1, 0. To ensure that PutData received 512 characters on every call except the last, you would need a second buffer to deal with both underflow and overflow on the reads.

Something like this should work:
VB
Sub Main()
    Dim buffer As Char() = New Char(511) {}
    Dim count As Integer = 0

    Dim tempBuffer As Char() = New Char(511) {}
    Dim tempCount As Integer
    Dim toCopy As Integer

    Do
        tempCount = GetData(tempBuffer)
        If tempCount <> 0 Then
            ' Either copy all of the data read,
            ' or enough to fill the main buffer:
            toCopy = Math.Min(tempCount, buffer.Length - count)
            Array.Copy(tempBuffer, 0, buffer, count, toCopy)
            count += toCopy

            If count = buffer.Length Then
                ' We've filled the main buffer.
                ' Put the data and clear the buffer:
                PutData(buffer, count)
                count = 0

                If tempCount > toCopy Then
                    ' We read more data that we could fit in the main buffer.
                    ' Copy the remaining data to the main buffer.
                    ' (This will always be less than 512 characters, so no need to check for a second overflow.)
                    Array.Copy(tempBuffer, toCopy, buffer, 0, tempCount - toCopy)
                    count = tempCount - toCopy
                End If
            End If
        End If
    Loop While tempCount <> 0

    If count <> 0 Then
        ' We have some buffered data left, so write it to the output:
        PutData(buffer, count)
    End If
End Sub



* Almost, because your buffer is one character too large. VB.NET arrays are declared using the upper-bound of the array, not the number of elements, so your array should be declared as New Char(511){}.
 
Share this answer
 
Basically, you are right in your suspicious thoughts about the quality of this test. But it depends on how to look at the problem. Let's see…

There is nothing wrong with using some black box systems, but only if behave consistently. However, if you analyze it, you will see that it is theoretically possible to have such interface on input stream. The weird point is that if the return value returns less then 512, the input may or may not be exhausted. Nevertheless, you have to read until it's 0. How about output then?

If you look at the output, it may look as a contradiction. If you try straightforward approach, you can face the following situation. Let's say, you receive less then 512 characters from input. The rules say that it does not mean that it is exhausted. You can get any number of less-then-512 chunks of data, but not 0; the described interface allows the system to do that for you. If you send this chunk to output, you loose the ability to send anymore, even if input is not yet exhausted.

So, the right solution would be to accumulate data in intermediate storage, adding more data from input, until you get 512 bytes or more. When it happens, you should send exactly 512 bytes and leave the rest in this intermediate storage, adding data from input, until you have enough to send 215 or input is exhausted.

Certainly, the given system is an example of really poor design. But you failed to adopt it, which could be the main purpose for this test. You need to be able to spot problems in available systems you have to interface with, and work around such problems. You have to figure out if the solution is possible or not, reject systems which are theoretically impossible to work around, and consider using those which can be used.

—SA
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900